Hi, I think I don't need to refer to your concrete example. Basically an object is a named key-value store. So a class A with instance variable a,b,c is just something like A a -> valueOfA b -> valueOfB c -> valueOfC A subclass of A would either have the same amount of variables or more. So subclass B of A could look like B a -> valueOfA b -> valueOfB c -> valueOfC d -> valueOfD If you have a serialized form of a B you need to know that it is a B in order to read all of the 4 values back into the right object type. - in OODBs this case is easy. The serialization contains everything from the key-values and the class that they belong to. Sometimes the data format on disk is the same as in memory so there is less to do. The difference between magma and gemstone is that magma is an addition to an image. That means you have your smalltalk image in memory and than you have magma. With magma you define a persisted root object, e.g. a Dictionary. Everything you attach to the Dictionary will be persisted if you do a commit. Well, you need to do your changes inside a transaction but there are always ways to make this look nearly transparent. In gemstone everything is already persisted including all the classes and objects. As soon as you attach a newly created object somewhere that is already persistent it will be persisted, too. The easiest way of handling your data is to keep an instance variable in your class that holds the instances. Et voila, that's all! All you objects are persisted. Speaking of seaside gemstone can be used doing autocommits on a request basis so you don't have to care at all about transactions. You just use your objects and that is it. Querying is like using collections. If you need special kind of querying either for your problem or performance you can provide a special type of collection that is optimized for the problem - In XMLDBs / document databases (CouchDB) you just have a representation of that key-value store. Be it an xml element or a Javascript object in JSON format they are both key-value stores. You then need to serialize/deserialize those formats. Reading a subclass is just a matter of providing the right class name when reading the serialized format. References can be handled multiple ways, but default ones will be id/idref in XML and link/Uri in restful ways. Querying in XMLDB is using xpath, in CouchDB and document databases I don't know if there is a general query support - In SQL databases the instance variables are mapped to columns of a table or multiple tables and each row is an object. Relationships of objects are handled by keys in the tables. A 1:1 relationships contains a key of the relation source in the relation target table. A n:m relationship needs an intermediate table that maps relation source keys to relation target keys. Talking about inheritance this gets easily complicated. Basically there are two options. You can solve it like everyone would expect it, let's say more BNF like. You would have a table A for class A and a table B for class B. Now in all tables of objects that reference A or B you need an additional information which class is meant: A or B. The tables than could be joint correctly after evaluation the additional value. Another strategy is to do multiple lookups until you've found the right value. The other approach is to make one table that is a super set of all needed variables. The keys are unique among all the subclasses and can be lookuped up more easily. But you waste some space because a lot of the columns would be empty. In any case you need to change your database schema if you change your model. Joins and number of requests can grow easily so that your application will be slowed down. Glorp gives you all of these strategies if you want them. My personal advize would be to avoid inheritance in that scenario completely or do only the simplest cases possible. Relational databases and object oriented approaches just don't fit together. You need to decide if your problem is more of the one or the other type. Then take one of those two approaches. Querying is based on column types and joins. Glorp is providing a query protocol that is similar to collections. You just need to use some things differently due to the nature of the layer below is different. Hope this helps, Norbert On 08.04.2010, at 09:02, Friedrich Dominicus wrote:
Friedrich Dominicus <frido@q-software-solutions.de> writes:
I just wonder about experiences with non relational databases like e.g - Magma - Gemstone - others Ok to get a bit more concrete assume I have a simple inheritance as in the example
Object subclass: #ClosedFigure instanceVariableNames: 'sideA sideB sideC alpha beta gamma' classVariableNames: '' poolDictionaries: '' category: 'Pharo-Mailing-List-Example'!
!ClosedFigure methodsFor: 'as yet unclassified' stamp: 'FriedrichDominicus 4/8/2010 08:21'! area ^0 ! !
!ClosedFigure methodsFor: 'as yet unclassified' stamp: 'FriedrichDominicus 4/8/2010 07:07'! circumreference ^ 0! !
Object subclass: #ModelLine instanceVariableNames: 'length beginPoint endPoint' classVariableNames: '' poolDictionaries: '' category: 'Pharo-Mailing-List-Example'!
!ModelLine methodsFor: 'accessing' stamp: 'FriedrichDominicus 4/8/2010 07:09'! beginPoint ^ beginPoint! !
!ModelLine methodsFor: 'accessing' stamp: 'FriedrichDominicus 4/8/2010 07:09'! beginPoint: anObject beginPoint := anObject! !
!ModelLine methodsFor: 'accessing' stamp: 'FriedrichDominicus 4/8/2010 07:09'! endPoint ^ endPoint! !
!ModelLine methodsFor: 'accessing' stamp: 'FriedrichDominicus 4/8/2010 07:09'! endPoint: anObject endPoint := anObject! !
!ModelLine methodsFor: 'accessing' stamp: 'FriedrichDominicus 4/8/2010 07:09'! length ^ length! !
!ModelLine methodsFor: 'accessing' stamp: 'FriedrichDominicus 4/8/2010 07:09'! length: anObject length := anObject! !
!ModelLine methodsFor: 'as yet unclassified' stamp: 'FriedrichDominicus 4/8/2010 07:19'! initialize super initialize. length := 0.! !
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
ModelLine class instanceVariableNames: ''!
!ModelLine class methodsFor: 'as yet unclassified' stamp: 'FriedrichDominicus 4/8/2010 07:33'! new: initialLength ^ self new length: initialLength ! !
ClosedFigure subclass: #ModelRectangle instanceVariableNames: 'lengthSideA lengthSideB' classVariableNames: '' poolDictionaries: '' category: 'Pharo-Mailing-List-Example'!
!ModelRectangle methodsFor: 'accessing' stamp: 'FriedrichDominicus 4/8/2010 08:31'! lengthSideA ^ lengthSideA! !
!ModelRectangle methodsFor: 'accessing' stamp: 'FriedrichDominicus 4/8/2010 08:31'! lengthSideA: anObject lengthSideA := anObject! !
!ModelRectangle methodsFor: 'accessing' stamp: 'FriedrichDominicus 4/8/2010 08:31'! lengthSideB ^ lengthSideB! !
!ModelRectangle methodsFor: 'accessing' stamp: 'FriedrichDominicus 4/8/2010 08:31'! lengthSideB: anObject lengthSideB := anObject! !
!ModelRectangle methodsFor: 'as yet unclassified' stamp: 'FriedrichDominicus 4/8/2010 08:35'! area ^ lengthSideA * lengthSideB ! !
!ModelRectangle methodsFor: 'as yet unclassified' stamp: 'FriedrichDominicus 4/8/2010 08:32'! lengthSideA: lenA lengthSideB: lenB super initialize. lengthSideA := lenA. lengthSideB := lenB.! !
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
ModelRectangle class instanceVariableNames: ''!
!ModelRectangle class methodsFor: 'as yet unclassified' stamp: 'FriedrichDominicus 4/8/2010 08:39'! lengthSideA: lenA lengthSideB: lenB ^ self new lengthSideA: lenA lengthSideB: lenB.! !
ClosedFigure subclass: #ModelTriangle instanceVariableNames: 'height length' classVariableNames: '' poolDictionaries: '' category: 'Pharo-Mailing-List-Example'!
!ModelTriangle methodsFor: 'accessing' stamp: 'FriedrichDominicus 4/8/2010 08:51'! area ^ 1/2 * length * height ! !
!ModelTriangle methodsFor: 'accessing' stamp: 'FriedrichDominicus 4/8/2010 08:46'! height ^ height! !
!ModelTriangle methodsFor: 'accessing' stamp: 'FriedrichDominicus 4/8/2010 08:46'! height: anObject height := anObject! !
!ModelTriangle methodsFor: 'accessing' stamp: 'FriedrichDominicus 4/8/2010 08:46'! length ^ length! !
!ModelTriangle methodsFor: 'accessing' stamp: 'FriedrichDominicus 4/8/2010 08:46'! length: anObject length := anObject! !
!ModelTriangle methodsFor: 'as yet unclassified' stamp: 'FriedrichDominicus 4/8/2010 08:47'! length: aLength height: aHeight super initialize. length := aLength. height:= aHeight. ! !
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
ModelTriangle class instanceVariableNames: ''!
!ModelTriangle class methodsFor: 'as yet unclassified' stamp: 'FriedrichDominicus 4/8/2010 08:49'! length: aLength height: aHeight ^ self new length: aLength height: aHeight.! !
Now this is as simple as can be. I have a Parent and two derived classes. How would I make this stuff persistent, and how would it look in different persistence solutions.
Let us assume. I would store the outline e.g in an OrderedCollection of Lines or whatever. What about other "ClosedFigures" like e.g circles, ellipses etc. How do I model inheritance in the diverse OR mappers. How does that work in let's say - Magma - Glorp - GemStone - whatever you choose
How would I query the database on let's side length of some lines of the Closed Figure, or let's say I like to query a few closed figures on their circumreference or area.
Or asked anotherway. How is inheritance handled in the diverse persistence tools..
Another question is how easy or difficult is it to have let's say something like a person with addresses, phone numbers etc.
How would I have to query let's say the street address of a certain Person. e.g
Regards Friedrich
-- Q-Software Solutions GmbH; Sitz: Bruchsal; Registergericht: Mannheim Registriernummer: HRB232138; Geschaeftsfuehrer: Friedrich Dominicus
_______________________________________________ Pharo-users mailing list Pharo-users@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-users