Updating multiple dictionaries?

Forums for specific tips, techniques and example code
ConvertFromOldNGs
Posts: 5321
Joined: Wed Aug 05, 2009 5:19 pm

Updating multiple dictionaries?

Postby ConvertFromOldNGs » Fri Aug 07, 2009 2:12 pm

by Silver Springs ... >> Mon, 12 Apr 1999 21:29:08 GMT

From: Philip Doggett <dogndrum@globalnet.co.uk>
Date: Sunday, April 11, 1999 2:50 AM
Subject: Using dictionaries


When I create a persistent object that I want to be able to obtain via a number of different dictionaries (MemberKeyDictionary), is it always necessary for me to explicitly add the new object to each of the dictionaries? Is there no way to define a relationship between the object and the dictionary that would accomplish this automatically?

For example, say I want to build a simple World Geography application whose major object is:

CountryClass
Attributes:
CountryName : String(30)
CapitalCity: String(30)
Population : Integer

Because I want to be able to list this data:
- alphabetically by CountryName
- alphabetically by CapitalCity
- by Population and CountryName

I need three different dictionaries.

When I populate the database, I seem to be required to:

beginTransaction;
create countryObj;
// initialise the attributes, then
mkdict1.add(countryObj);
mkdict2.add(countryObj);
mkdict3.add(countryOb);
commitTransaction;

Is there no way to define a relationship that results in countryObj being added to each of the dictionaries as a result of the commitTransaction following the create?

Philip Doggett
dogndrum@globalnet.co.uk

ConvertFromOldNGs
Posts: 5321
Joined: Wed Aug 05, 2009 5:19 pm

Re: Updating multiple dictionaries?

Postby ConvertFromOldNGs » Fri Aug 07, 2009 2:12 pm

by Dean Cooper >> Mon, 12 Apr 1999 22:36:26 GMT

Hi Philip,

Yes, you can define a relationship that will accomplish this. The question is: what is the parent (or owner) object of your dictionaries (mkdict1, mkdict2 and mkdict3)? Presumably you have another class somewhere on which these dictionaries are exclusive references. Say this class is called World and looks something like this:

World
Attributes:
...whatever...
References:
mkdict1 : CountryByNameDict
mkdict2 : CountryByCapitalDict
mkdict3 : CountryByPopAndNameDict

where CountryByNameDict, CountryByCapitalDict and CountryByPopAndNameDict are all MemberKeyDictionary subclasses with membership of Country and keys as per their name.

Having defined the World class, you can now define three relationships from Country to World (with each relationship originating from the same property on Country) that will automatically maintain the dictionaries. Add a reference to Country called myWorld of type World. Define three one-to-many inverses to myWorld: mkdict1, mkdict2 and mkdict3 of Country. Define myWorld as manual and each of its inverses as automatic. Having done this, you can now change your code as follows:

vars
theWorld : World;begin

// firstly, get the current world somehow
theWorld := app.currentWorld;
beginTransaction;
create countryObj;
// initialise the attributes
countryObj.myWorld := theWorld;
commitTransaction;
end;

When Jade updates a reference that has inverses, it automatically maintains those inverses. In this case, assigning theWorld to countryObj.myWorld will result in countryObj being added automatically to the three dictionaries (inverses) on the other side of the relationship.

I've assumed above that you have a method or reference on app (app.currentWorld) that returns the currently active world; for example, you may have one (singleton) instance of World that you obtain when your app starts.

Note that mkdict1, mkdict2 and mkdict3 can participate in these relationships only if they are exclusive collections on some parent class (in this case, World). If they are shared collections (that is, they are not exclusive and you are creating and deleting them yourself) and exist independently of a parent object, they cannot participate in the relationships I've described above. If this is the case, I would strongly recommend that you consider introducing a root object (like a World instance) which owns these dictionaries. This is generally much better design, and allows you to take far more advantage of Jade's automatic relationships.

Dean.

ConvertFromOldNGs
Posts: 5321
Joined: Wed Aug 05, 2009 5:19 pm

Re: Updating multiple dictionaries?

Postby ConvertFromOldNGs » Fri Aug 07, 2009 2:12 pm

by Geoff Davies >> Tue, 13 Apr 1999 22:16:20 GMT

Dean Cooper advised
If this is the case, I would strongly
recommend that you consider introducing a root object (like a World instance) which owns these dictionaries. This is generally much better design, and allows you to take far more advantage of Jade's automatic relationships.

This advice is of course excellent. However rather than create a new class called World (or whatever) which is destined only ever to have one persistent instance, why not attach our master collections of allCountries to that already-existing, easy-to-reference, single, persistent object that nobody ever uses - I am talking about global.

ConvertFromOldNGs
Posts: 5321
Joined: Wed Aug 05, 2009 5:19 pm

Re: Updating multiple dictionaries?

Postby ConvertFromOldNGs » Fri Aug 07, 2009 2:12 pm

by Craig Shearer >> Wed, 14 Apr 1999 0:17:36 GMT

Hello All

While storing stuff on global seems like a good idea, there are some gotchas with it. When extracting and importing a schema, the state of the persistent application and global objects are dumped along with the schema, and restored on import. If you have a reference to an object on Global, then that object is no longer going to exist when you import the schema, resulting in a error (or at least a message box) during the load. For this reason, I tend to avoid putting stuff on Global.

Also, from a modelling perspective, it makes more sense to have a "World" class.

Craig.

ConvertFromOldNGs
Posts: 5321
Joined: Wed Aug 05, 2009 5:19 pm

Re: Updating multiple dictionaries?

Postby ConvertFromOldNGs » Fri Aug 07, 2009 2:12 pm

by Dean Cooper >> Wed, 14 Apr 1999 1:12:51 GMT
When extracting and importing a schema, the state of the persistent application and global objects are dumped along with the schema, and restored on import. If you have a reference to an object on Global, then that object is no longer going to exist when you import the schema, resulting in a error (or at least a message box) during the load.

In Jade 5, persistent applications are instances of the Application class; they are not instances of your schema's Application subclass (in the same way that all persistent form definitions are instances of Form). This means that the schema extract/load will no longer attempt to extract and load properties that you've added to your schema's Application subclass (it will also mean that you can add such properties without having to reorg your apps!). Also in Jade 5, the schema load will not attempt to load global at all, as it is considered to be user data and not specification data. Both of these changes should eliminate the schema load problems that can occur today with references on app and global.
Also, from a modelling perspective, it makes more sense to have a "World" class.


Good point. I sometimes avoid using global for this reason as well. Also, I tend to use it only for data that is to be shared across *all* apps in a schema.

Dean.

ConvertFromOldNGs
Posts: 5321
Joined: Wed Aug 05, 2009 5:19 pm

Re: Updating multiple dictionaries?

Postby ConvertFromOldNGs » Fri Aug 07, 2009 2:12 pm

by Darrell Duniam >> Fri, 16 Apr 1999 4:02:26 GMT

Dean,

<snip>
In Jade 5, persistent applications are instances of the Application class; they are not instances of your schema's Application subclass (in the same way that all persistent form definitions are instances of Form). This means that the schema extract/load will no longer attempt to extract and load properties that you've added to your schema's Application subclass (it will also mean that you can add such properties without having to reorg your apps!). Also in Jade 5, the schema load will not attempt to load global at all, as it is considered to be user data and not specification data. Both of these changes should eliminate the schema load problems that can occur today with references on app and global.

When you say that in JADE 5 'the schema load will not attempt to load global at all', does that include methods on the Global class please ?

darrell.

<snip>

ConvertFromOldNGs
Posts: 5321
Joined: Wed Aug 05, 2009 5:19 pm

Re: Updating multiple dictionaries?

Postby ConvertFromOldNGs » Fri Aug 07, 2009 2:13 pm

by Dean Cooper >> Fri, 16 Apr 1999 4:30:10 GMT
When you say that in JADE 5 'the schema load will not attempt to load global at all', does that include methods on the Global class please ?

Sorry, I should have been more clear.

In Jade 5, only the global *instance* (ie: the data) will no longer be loaded. Currently, the global instance is extracted in the ddb file and reloaded when you load the ddb (which can lead to the problems Craig mentioned in his posting). The *definition* of your global class (ie: the properties, methods, etc that are extracted in the scm file) will still be loaded.

Didn't mean to scare anybody! :-)

Dean.

ConvertFromOldNGs
Posts: 5321
Joined: Wed Aug 05, 2009 5:19 pm

Re: Updating multiple dictionaries?

Postby ConvertFromOldNGs » Fri Aug 07, 2009 2:13 pm

by Paul Mathews >> Tue, 13 Apr 1999 22:16:52 GMT

In actual practice, you will probably find there are advantages in
having multiple RootObjects, eg Live, Demo, Test.

We have a collection of RootObjects on Global.

In the CMSchema downloadable from our WEBSite there are utilities to Clone the Data of Root Objects and backup / restore all Data.

ConvertFromOldNGs
Posts: 5321
Joined: Wed Aug 05, 2009 5:19 pm

Re: Updating multiple dictionaries?

Postby ConvertFromOldNGs » Fri Aug 07, 2009 2:13 pm

by Darrell Duniam >> Mon, 12 Apr 1999 22:40:55 GMT

You could do the following:

CountryClass
Attributes:
myRootClass (type=RootClass)
countryName (type=String)
capitalCity (type=String)
population (type=Integer)

MemberKeyDictionaries:
CountryByNameDict (membership=CountryClass, key=countryName)
CountryByCapitalDict (membership=CountryClass, key=countryName,
duplicates allowed)
CountryByPopulationDict (membership=CountryClass,
key=population,
duplicates allowed)

RootClass
Attributes:
allCountriesByName (type=CountryByNameDict)
allCountriesByCapital (type=CountryByCapitalDict)
allCountriesByPopulation (type=CountryByPopulationDict)

Application Class
Attributes:
myRootClass (type=RootClass) - set at application initialization
...

The manual/auto inverse of the 'RootClass' Country collections would be 'myRootClass' of the CountryClass. Therefore, a set method on the CountryClass class could:

set(pName:String; pCapital:String; pPopulation:Integer) updating;

vars
begin

self.countryName := pName;
self.capitalCity := pCapital;
self.population := pPopulation;
self.myRootClass := app.myRootClass;
end;

.....this would automatically populate the Country collections on the RootClass class, for example:

createCountry() updating;

vars
country : CountryClass;
begin

beginTransaction;
create country;
country.set('Australia', 'Canberra', '300000');
commitTransaction;
end;

regards,
darrell.


Return to “Tips and Techniques”

Who is online

Users browsing this forum: No registered users and 0 guests