Re: Creating a EOModel in code
Re: Creating a EOModel in code
- Subject: Re: Creating a EOModel in code
- From: Don Lindsay via Webobjects-dev <email@hidden>
- Date: Tue, 30 Jun 2020 11:29:17 -0400
Thank you, I appreciate all your insight.
> On Jun 29, 2020, at 13:04, OCsite <email@hidden> wrote:
>
> Don,
>
>> On 29 Jun 2020, at 17:16, Don Lindsay <email@hidden
>> <mailto:email@hidden>> wrote:
>> Thanks for the information. This may be the path I will need to go down for
>> this specific project.
>
> Good luck!
>
> I have checked our sources and actually there were two small gotcha's we did
> bump into:
>
> (i) programmatically added attributes are by default used for locking;
> (ii) when adding new attribute, entity does not check whether its DB column
> is unique.
>
> Both of these behaviours might well be intentional, but for us, both of them
> proved a bit at the surprising side. Given we do not run multi-instance, all
> we need to lock on are the PKs; and, we never share DB columns betwixt
> different attributes. Thus, we had to add extra code for both the cases.
>
> Probably not the most elegant approach by far, but this works reliably for us
> for years (not pure Java, but I hope understandable without extra
> Groovy-explaining comments):
>
> ===
> @Extension(EOEntity) class EntityExtensions {
> ... ...
> void addAttributeIfNeeded(EOAttribute attr) {
> EOAttribute old=this.attributeNamed(attr.name)
> if (!old) {
> EOAttribute clash=this.attributes.find { oa ->
> oa.columnName==attr.columnName }
> if (clash) Exception.raise "cannot add attribute '$attr.name':
> column '$attr.columnName' already exists"
> this.addAttribute(attr)
> NSArray locks=this.attributesUsedForLocking()
> if (locks.contains(attr)) {
> locks.remove(attr)
> this.attributesUsedForLocking=locks
> }
> return
> }
> String ocn=old.className(),ncn=attr.className()
> if (ocn!=ncn) {
> Class
> ocl=_NSUtilities.classWithName(ocn),ncl=_NSUtilities.classWithName(ncn)
> if (ocl!=ncl) { // we may get same classes for different names,
> eg. String/NSString
> if (!ocl) Exception.raise "no class for name '$ocn' attribute
> '$old.name'"
> if (!ncl) Exception.raise "no class for name '$ncn' attribute
> '$attr.name'"
> if (ncl !in ocl) Exception.raise "class '$ncl' incompatible
> with existing '$ocl' attribute '$attr.name'"
> }
> }
> [
> 'allowsNull','externalType','precision','scale',/*'width',*/
> 'adaptorValueClass', 'adaptorValueConversionClassName',
> 'adaptorValueConversionMethodName', 'adaptorValueType', 'definition',
> 'factoryMethodArgumentType', 'isReadOnly', 'prototypeName', 'readFormat',
> 'relationshipPath', 'valueFactoryMethodName', 'valueType',
> 'valueTypeClassName', 'writeFormat'].each { key ->
> if (old."$key"!=attr."$key") {
> Exception.raise "$key '",attr."$key","' differs from existing
> '"+old."$key"+"' attribute '$attr.name'"
> }
> }
> }
> }
> ===
>
> All the best,
> OC
>
>>
>> Thanks
>>
>> Don
>>
>>> On Jun 29, 2020, at 07:14, OCsite <email@hidden <mailto:email@hidden>> wrote:
>>>
>>> Don,
>>>
>>> we do something remotely similar all the time (not creating a complete
>>> model, but adding attributes dynamically at launch to entities). Works
>>> without a glitch, I cannot recall any problem at all with this.
>>>
>>> Should work for you as well, I would be rather surprised if you encounter
>>> any problems model-side.
>>>
>>> Potential problems might possibly occur at the database side: how do you
>>> read the schema in? We tried lots of things, eventually decided to stick
>>> with low-level DB-specific approach like e.g.,
>>>
>>> def sch_list=EOUtilities.rawRowsForSQL(ec,model.name,'select "SCHEMA_PK",
>>> "SCHEMA_NAME" from INFORMATION_SCHEMA.SCHEMATA',null)
>>> def table_list=EOUtilities.rawRowsForSQL(ec,model.name,/select "TABLE_PK",
>>> "TABLE_NAME" from INFORMATION_SCHEMA.TABLES where
>>> "SCHEMA_PK"=$schemaPK/,null)
>>>
>>> and so forth, which seem to work reliably for our FrontBase. None of the
>>> higher-level APIs we have tried worked reliably for us (note though we not
>>> only read the schema in, but also need to add columns to tables
>>> dynamically; presumably, you won't need that).
>>>
>>> All the best,
>>> OC
>>>
>>>> On 28 Jun 2020, at 17:51, Don Lindsay via Webobjects-dev
>>>> <email@hidden <mailto:email@hidden>>
>>>> wrote:
>>>>
>>>> Sorry if I was not clear in my first email.
>>>>
>>>> I don’t want to create a EOModel file. I want to take database connection
>>>> properties from the user of an application and use those to build an
>>>> EOModel that is used in the application while it is running on the server.
>>>> The database connection parameters would be stored in a settings database
>>>> and retrieved when the user wants to load data from that connection. This
>>>> is a tool to allow users to specify their own data sources and compare
>>>> data between different datasources in whatever manner the user wishes to
>>>> compare or display it.
>>>>
>>>> Thanks for all the answers so far I was not aware Apache Cayenne could be
>>>> used as a full replacement for EOF
>>>>
>>>> Don
>>>>
>>>>
>>>>> On Jun 25, 2020, at 20:53, Don Lindsay via Webobjects-dev
>>>>> <email@hidden <mailto:email@hidden>>
>>>>> wrote:
>>>>>
>>>>> Hello;
>>>>>
>>>>> The Documentation for EOModel states that you can build one in code, but
>>>>> there are no examples or further information that I can find. Does
>>>>> anyone have any documentation or samples that they can direct me to so I
>>>>> can create EOModels while the application is running:
>>>>>
>>>>> What I want to do is connect to a database that my app does not know
>>>>> about, someone provides connection parameters and I create an EOModel and
>>>>> connect to that database or rest and access it using the EOModel created
>>>>> using new EOModel().
>>>>>
>>>>> Thanks
>>>>>
>>>>> Don
>>>>> _______________________________________________
>>>>> Do not post admin requests to the list. They will be ignored.
>>>>> Webobjects-dev mailing list (email@hidden
>>>>> <mailto:email@hidden>)
>>>>> Help/Unsubscribe/Update your Subscription:
>>>>>
>>>>> This email sent to email@hidden <mailto:email@hidden>
>>>>
>>>> _______________________________________________
>>>> Do not post admin requests to the list. They will be ignored.
>>>> Webobjects-dev mailing list (email@hidden
>>>> <mailto:email@hidden>)
>>>> Help/Unsubscribe/Update your Subscription:
>>>>
>>>> This email sent to email@hidden <mailto:email@hidden>
>>>
>>
>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden