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

Reply via email to