Can I directly store a type in an ADOJobStore in Quartz.Net - quartz.net

I would like to execute a job that requires that I save a type in the JobDataMap. This will later be used along with the ID of an entity to rehydrate the entity so the job can use it.
I know I could get the AssemblyQualifiedName of the type and store that, then use GetType() in the job, but before I go down that path, I thought I'd see if quartz just does this for me.
If I put a type in the JobDataMap, will it serialize and deserialize when I access the property later?

Sure it will. You can use the JobDataMap indexer to store arbitrary data. Type instances are quite safe, but you need to be extra careful about versions (using only assembly qualified name removes this problem), namespaces and public keys.
If there were a slight possibility that the type might change after persisting I would recommended using a 'meta name' like 'BackupJobHelperType' that you would then resolve to the actual type. Generelly always prefer simple serialization safe types over own types, if possible set quartz.jobStore.useProperties to true which will enforce string key and values.
You can save the info when building the job and it will be available when the job starts.

Related

Genexus Extensions SDK - Is there a built in helper to save data locally?

I Would like to know if the Genexus Extension SDK already implements something to store persistent data locally (KB Independant and per KB), something like PersistentDictionary from ManagedEsent
I know that genexus uses SQL Server to store KB Related information, is there an interface for me to extend that?
I want to save data per genexus instance (locally) and use that data to load my extension config, everytime the users executes Genexus.
We don't use PersistentDictionary. I would advice not to use it, as it's a Windows specific API, and we are trying make everything new cross platform, as part of our journey of making GeneXus BL run on other OS.
There are different options of persistence, depending on the specific details of your scenario.
If you want to store something like configuration settings for your extension, you can use the ConfigurationHelper class located in Artech.Common.Helpers. This class provides read access to the configurations defined in the GeneXus.exe.config file in the GeneXus installation folder, as well as read/write access to the Environment.config file located in %AppData%\GeneXus\GeneXus\<version>\Environment.config. Note this file depends on the current user, and is shared between different GeneXus instances of a same main version.
The ConfigurationHelper class provides operations to read and save settings of basic types string, int and bool.
const string MY_EXTENSION = "MyExtensionSettings";
const string SETTING1 = "Setting1";
const string SETTING1_DEFAULT_VALUE = "This is the default value";
const string SETTING2 = "Setting2";
const int SETTING2_DEFAULT_VALUE = 20;
string setting1Value = ConfigurationHelper.GetUserSetting(MY_EXTENSION, SETTING1, SETTING1_DEFAULT_VALUE);
int setting2Value = ConfigurationHelper.GetUserSetting(MY_EXTENSION, SETTING2, SETTING2_DEFAULT_VALUE);
// Do something and maybe change the setting values
ConfigurationHelper.SetUserSetting(MY_EXTENSION, SETTING1, setting1Value);
ConfigurationHelper.SetUserSetting(MY_EXTENSION, SETTING2, setting2Value);
If you want to store something in a file based on the current opened KB, there's no specific API that'll help you handle the persistence. You can use the properties Location and UserDirectory of the KnowledgeBase class to access the KB location or a directory for the current user under the KB location, but it's up to you the handling of the file. You'll have to decide on the file format (binary or text), file encoding in case of text files, and handle all read and write operations to that file.
We use the kb.UserDirectory path to store non-critical stuff, such as the set of objects that were opened the last time the KB was closed, or the filter values for different dialogs.
In case you'd like to store settings inside the KB, there are plenty of options.
You can add properties to existing objects, KB version or environment. Making it a property doesn't necessary mean you'll have to edit the value in the property grid, although it's usually the way to go.
You can define a new kind of entity. Entities are the basic elements that can be stored in a KB. The entity may be stored depending on the active version of the KB, or may be independent of the current version. Entities can have properties, whose serialization is handled by the property engine, and also can read and store a byte array whose format and content will be handled by you.
You can add a part to an existing object. For instance you may want to add a part to Procedure objects. In order to do this you'll have to extend KBObjectPart, define your part in a BL package, declare that the part composes objects of certain type, and provide an editor for your new part in a UI package. KBObjectPart extends Entity so the serialization of the part is similar as in the previous case. A caveat of this option is that you'll also have to handle how the part content is imported, exported, and compared.
You can add a new kind of object. Objects extend the KBObject class, which extends Entity. Objects are not obliged to have parts (for instance the Folder object doesn't have any). When choosing to provide a new kind of object you have to consider a couple of things, such as:
Do you want to be able to create new instances from the new object dialog?
Will it be shown in the folder view?
Can it be added into modules?
Can it have the same name as other objects of different types?
As a general guideline, if you choose to add a new property, add it to objects, versions, or environments, not parts. Adding properties to parts is not so good for discoverability. Also if you choose to add a new kind of object, even though it inherits from Entity which as mentioned earlier can read and store a byte array, it's preferred to don't use the byte array in KBObject and add a KBObjectPart to it instead. That way the KBObject remains as lightweight as possible, and loading the object definition from the DB remains fast, and the blob content is loaded only when truly needed.
There's no rule of thumb. Depending on the specifics of the scenario, one option may be more suited than others.

Delphi - Passing query results between units?

In one unit I'm running a query which will return one users details from the database. Right now I'm thinking of creating a user object and assigning the results of the query to the different properties, the setting that as a global variable. I wanted to know if there was a way to pass the data between the units without having to use the global variables.
Avoiding global variables is actually a good idea. Also, storing the query result as properties of a (database-independent) object makes sense, because the application might need the information also when the connection is not active.
To avoid a global variable, the easiest way would be to make the object a field of a main form (or datamodule), and use Getter methods to make it (and its fields) read-only. I would also implement the procedure of loading the dataset values into the object properties as a spearate class.

Grails: how to programatically bind command object data to domain object in service?

I have a command object that I want to convert into a domain object.
However, the object I want to convert the command object into may be one of two domain classes (they're both derived classes), and I need to do it in a service (which is where, based on other data, I decide which type of object it should be bound to). Is this possible and what's the best way to do this? bindData() only exists in a controller.
Do I just have to manually map command object parameters to the appropriate domain object properties? Or is there a faster/better way?
If the parameters have the same name, then you can use this question to copy the values over. A quick summary can be as follows.
Using the Grails API
You can cycle through the properties in a class by accessing the properties field in the class.
object.properties.each { property ->
// Do something
}
You can then check to see if the property is present in the other object.
if(otherObject.hasProperty(property) && !(key in ['class', 'metaClass']))
Then you can copy it from one object to the other.
Using Commons
Spring has a really good utility class called BeanUtils that provides a generic copy method that means you can do a simlple oneliner.
BeanUtils.copyProperties(object, otherObject);
That will copy values over where the name is the same. You can check out the docs here.
Otherwise..
If there is no mapping between them, then you're kind of stuck because the engine has no idea how to compare them, so you'll need to do it manually.

How to create nodes in neo4j with properties defined by a dictionary via neo4jclient in C#

As a complete novice programmer I am trying to populate my neo4j DB with data from heterogeneous sources. For this I am trying to use the Neo4jClient C# API. The heterogeneity of my data comes from a custom, continuously evolving DSL/DSML/metamodel that defines the possible types of elements, i.e. models, thus creating classes for each type would not be ideal.
As I understand, my options are the following:
Have a predefined class for each type of element: This way I can easily serialize my objects that is if all properties are primitive types or arrays/lists.
Have a base class (with a Dictionary to hold properties) that I use as an interface between the models that I'm trying to serialize and neo4j. I've seen an example for this at Can Neo4j store a dictionary in a node?, but I don't understand how to use the converter (defined in the answer) to add a node. Also, I don't see how an int-based dictionary would allow me to store Key-Value pairs where the keys (that are strings) would translate to Property names in neo4j.
Generate a custom query dynamically, as seen at https://github.com/Readify/Neo4jClient/wiki/cypher#manual-queries-highly-discouraged. This is not recommended and possibly is not performant.
Ultimately, what I would like to achieve is to avoid the need to define a separate class for every type of element that I have, but still be able to add properties that are defined by types in my metamodel.
I would also be interested to somehow influencing the serializer to ignore non-compatible properties (similarly to XmlIgnore), so that I would not need to create a separate class for each class that has more than just primitive types.
Thanks,
J
There are 2 problems you're trying to solve - the first is how to program the C# part of this, the second is how to store the solution to the first problem.
At some point you'll need to access this data in your C# code - unless you're going fully dynamic you'll need to have some sort of class structure.
Taking your 3 options:
Please have a look at this question: neo4jclient heterogenous data return which I think covers this scenario.
In that answer, the converter does the work for you, you would create, delete etc as before, the converter just handles the IDictionary instance in that case. The IDictionary<int, string> in the answer is an example, you can use whatever you want, you could use IDictionary<string, string> if you wanted, in fact - in that example, all you'd need to do would be changing the IntString property to be an IDictionary<string,string> and it should just work.
Even if you went down the route of using custom queries (which you really shouldn't need to) you will still need to bring back objects as classes. Nothing changes, it just makes your life a lot harder.
In terms of XmlIgnore - have you tried JsonIgnore?
Alternatively - look at the custom converter and get the non-compatible properties into your DB.

Creating a 'configuration settings' object, persisted to the db, that you can create properties for

Since Rails is using Ruby (dynamic language), would it be possible to create a very flexible
'configuration' class that has properties that you use throughout the website, AND have the ability to add new class properties (in the db for web modification) and then just use it in the code.
Each property would be of a specific type like a string, integer, bool etc.
You can't do this in a strongly typed language, but it must be possible with Ruby!
So say my class is like:
globalConfig.is_active
globalConfig.admin_email
I guess to make this work, I would loop through all the properties in the db, create properties in the class and assign the value right?
I actually have a settings plugin on GitHub you can use:
http://github.com/bellmyer/settings
It makes this easier for you. Right now it's not rails3-ready, so let me know if you need that. I also need to put in the time to roll it into a gem, instead of a plugin.
If you end up using it, let me know and I'll get it up to date. Otherwise, you can look at the code to see how I did things, and use that to help build your own custom solution.

Resources