Mark, > On 19 Dec 2018, at 4:39 PM, Mark Wardle <m...@wardle.org> wrote: > > I want to define a group enterprise objects at runtime and yet use them in a > fairly similar way to "normal" enterprise objects. > > Essentially, I want a generic object that is backed by a NSDictionary (or > other persistence mechanism like bytes/protobuf) and has a defined behaviour > class. I would like to define the model at runtime rather than using > EOModeler. The definition of the object (list of properties and for each > property: name, dataType, class, prototype etc.) defined itself at runtime in > the backing database. > > Anyone done something similar, and if so, what is the best approach? I have > contemplated building a generic EO that delegates its behaviour and data to > the behaviour class and the backing NSDictionary respectively, and alters the > implementation of KVC to make it fairly transparent. I'm aware that some of > the hidden "magic" that comes from defining an object in EOModeler might be > lost.
Presumed you have fixed entities (with dynamic attributes) and you know beforehand which entities need the BLOB backing, you don't even need to change model nor the schema. (If you need to add entities dynamically, then you need to fix the model runtime — which is not difficult —, and also to sync the DB schema at runtime; that's where fun begins and madness lies :) Nevertheless, far as I understand, you don't need to do that.) KVC can be fixed through handleQueryWithUnboundKey/handleTakeValueForUnboundKey with a slight (and for most cases completely negligible) performance penalty. You need just a pretty straightforward code in there to check whether the unknown key matches one of your dynamic attributes for the entity, and access the backing dictionary to store/read the value if so. It gets a bit at the convoluted side though if you need to cache the values, so that you don't need to encode/decode the dictionary upon each access. In that case, you might bump to some synchronisation problems for the cache is shared by different users with different ECs. Myself, I have used a global value cache indexed by both global IDs of the owner EOs and, of course, attribute keys for the particular values; so far, it seems to work OK, but took some time to tune up. Also, beware that a change of an attribute inside of the backing dictionary does not automatically cause the appropriate BLOB backing attribute to be marked as changed and saved. This is easy far as your values are scalars; then you simply store changes in the handleTakeValueForUnboundKey method. If, though, the values themselves can be further structured (i.e., if your dynamic attributes may contain arrays/dictionaries), this might get a bit hairy, for it's not easy to track changes inside of the multi-level nested structure.Myself, I have played with a special dictionary which knows its backing attribute and marks it changed whenever its contents change; but so far, I was not able to find a reliable implementation of the thing. Hopefully you won't need this :) Based on the particular way of encoding your dictionaries, you might also bump into the pitfall that one and the same dictionary might get encoded as two different BLOBs. Depending on your needs, you might want to add code to compare decoded dictionaries (not encoded NSDatas), and store only if the new one differs from the old one. As for the API-level, Java-side, this might get a bit ugly, I fear. Myself, I use Groovy which is (JVM-compatible and) able to install methods/properties at runtime; thus, upon launch, I simply add all the appropriate accessors to my EO classes, and I can use them freely in all my code. If you are sticking with Java, I am afraid it's going to be a bit at the clumsy side, and you'll have to stick with KVC in code, too. I hope I did not forget anything of importance, OC _______________________________________________ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (Webobjects-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com