modeling-cvs Mailing List for Object-Relational Bridge for python (Page 29)
Status: Abandoned
Brought to you by:
sbigaret
You can subscribe to this list here.
2003 |
Jan
|
Feb
|
Mar
(54) |
Apr
(29) |
May
(94) |
Jun
(47) |
Jul
(156) |
Aug
(132) |
Sep
(40) |
Oct
(6) |
Nov
(18) |
Dec
(24) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
(18) |
Feb
(59) |
Mar
(7) |
Apr
|
May
(8) |
Jun
(2) |
Jul
(12) |
Aug
(15) |
Sep
(12) |
Oct
(6) |
Nov
(25) |
Dec
(1) |
2005 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2006 |
Jan
|
Feb
(27) |
Mar
|
Apr
(16) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <sbi...@us...> - 2003-05-16 11:33:27
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv32227 Modified Files: Tag: brch-0_9pre6-1-ModelMasons_base_generation_scheme mdl_generate_python_code.py Log Message: Updated usage() Index: mdl_generate_python_code.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/scripts/mdl_generate_python_code.py,v retrieving revision 1.4 retrieving revision 1.4.2.1 diff -C2 -d -r1.4 -r1.4.2.1 *** mdl_generate_python_code.py 20 Apr 2003 16:10:41 -0000 1.4 --- mdl_generate_python_code.py 16 May 2003 11:33:24 -0000 1.4.2.1 *************** *** 110,113 **** --- 110,115 ---- Generation options: ------------------- + For an explanation on generation schemes, see below + -B --base-generation-scheme use the 'base' scheme -C --compact-generation-scheme use the 'compact' scheme (default) *************** *** 116,120 **** --generation_scheme=<scheme> use <scheme> as the generation scheme (either 'base' or 'compact') ! """ % prgName sys.stderr.write(_usage) --- 118,135 ---- --generation_scheme=<scheme> use <scheme> as the generation scheme (either 'base' or 'compact') ! ! 'compact' scheme: puts all generated file in the same directory (the package ! for the model). When re-generating the files, a file that ! already exists is NEVER overwritten ! ! 'base' scheme: adds a sub-module 'MDL' within the generated package. All files ! within MDL/ are ALWAYS overwritten when the python code is regenerated, ! while others (in the root package) are never overwritten if they exist. ! This is probably the one you want to use if your model changes often. ! ! Note: this can be used if and only if there is no entity sharing the same ! module with one of its (direct or indirect) subentities. If this is ! not the case, the generation will raise and indicate the problem. ! """ % prgName sys.stderr.write(_usage) |
From: <sbi...@us...> - 2003-05-16 11:04:43
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons In directory sc8-pr-cvs1:/tmp/cvs-serv21096a/ModelMasons Modified Files: Tag: brch-0_9pre6-1-ModelMasons_base_generation_scheme PyModelMason.py Log Message: Added: check that the model is valid for the 'base' generation scheme + fixed: __init__ in MDL/ was not overwritten Index: PyModelMason.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons/PyModelMason.py,v retrieving revision 1.8.2.1 retrieving revision 1.8.2.2 diff -C2 -d -r1.8.2.1 -r1.8.2.2 *** PyModelMason.py 21 Apr 2003 22:53:05 -0000 1.8.2.1 --- PyModelMason.py 16 May 2003 11:04:40 -0000 1.8.2.2 *************** *** 42,45 **** --- 42,100 ---- from Python_bricks import init,init_base,model,base_module,module_base,module_compact,setup_tmpl + class InvalidModelError(Exception): + "Raised by checkModelIsValid()" + pass + + def checkModelIsValid(model, generation_scheme): + """ + Checks that the supplied model is valid for a given python-code generation + scheme: + + - if 'generation_scheme' is 'compact', all models are valid, + + - if 'generation_scheme' is 'base', the model is valid iff a class/entity does + not share the same module than any of its subclasses + + Parameters: + + model -- a instance of Modeling.Model.Model + + generation_scheme -- either 'compact' or 'base' + + Returns: None + + Raises InvalidModelError if the model is invalid. + + Note: this is NOT validation of the model itself (responsability of + Modeling.ModelValidation) + + """ + if generation_scheme=='compact': return + if generation_scheme=='base': + + # Build ordered list of entities + oe=[] + entities=list(model.entities()) + entities_processed=[] + for entity in [e for e in entities if not e.parentEntity()]: + oe.append(entity) + entities_processed.append(entity.name()) + entities.remove(entity) + while entities: + es=[e for e in entities if e.parentEntity().name() in entities_processed] + for entity in es: + entities.remove(entity) + entities_processed.append(entity.name()) + oe.append(entity) + # check every parent against it subentities + for e in oe: + parent_moduleName=e.moduleName() + subs=e.allSubEntities() + for sub in subs: + if sub.moduleName()==parent_moduleName: + raise InvalidModelError, "Model is invalid wrt the 'base' generation scheme: entity '%s' and its subentity '%s' share the same moduleName.\nEither correct this or use the 'compact' generation scheme"%(e.name(), sub.name()) + else: + raise ValueError, "Invalid value for 'generation_scheme' (%s), should be either 'base' or 'compact'"%use_scheme + class PyModelMason(ModelMason): def __init__(self, model, rootPath=None, verbose_mode=0, *************** *** 63,66 **** --- 118,122 ---- if generation_scheme not in ('compact', 'base'): raise ValueError,"Parameter generation_scheme can be either 'compact' or 'base'" + checkModelIsValid(model, generation_scheme) ModelMason.__init__(self, model, rootPath, Modeling.ModelMasons.PyModelMason, 'Python_bricks', *************** *** 144,148 **** self.createFileFromTemplate(init_base.init_base(), os.path.join(self.base_dir,"__init__.py"), ! overwrite=0) create_model_files(self, --- 200,204 ---- self.createFileFromTemplate(init_base.init_base(), os.path.join(self.base_dir,"__init__.py"), ! overwrite=1) create_model_files(self, |
From: <sbi...@us...> - 2003-05-16 11:02:50
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons/Python_bricks In directory sc8-pr-cvs1:/tmp/cvs-serv20408/ModelMasons/Python_bricks Modified Files: Tag: brch-0_9pre6-1-ModelMasons_base_generation_scheme init.tmpl init_base.tmpl module_base.tmpl Log Message: Added a timestamp in comment at beginning of file Index: init.tmpl =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons/Python_bricks/init.tmpl,v retrieving revision 1.3.4.1 retrieving revision 1.3.4.2 diff -C2 -d -r1.3.4.1 -r1.3.4.2 *** init.tmpl 21 Apr 2003 22:53:05 -0000 1.3.4.1 --- init.tmpl 16 May 2003 11:02:47 -0000 1.3.4.2 *************** *** 1,3 **** --- 1,5 ---- ## This template will build the __init__.py file + #import time + # Generated by mdl_generate_python_code.py / time.strftime("%Y/%m/%d %H:%M") #set $model_name = str($model().name()) # Load the model Index: init_base.tmpl =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons/Python_bricks/Attic/init_base.tmpl,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -C2 -d -r1.1.2.1 -r1.1.2.2 *** init_base.tmpl 21 Apr 2003 22:53:05 -0000 1.1.2.1 --- init_base.tmpl 16 May 2003 11:02:47 -0000 1.1.2.2 *************** *** 1,4 **** --- 1,6 ---- ## This template will build the __init__.py file in the 'base_dir' package ## (see ModelMasons.PyModelMason) + # WARNING: Any changes made here will be OVERWRITTEN next time the package + # is regenerated #for entities in $entitiesSet: import $(entities[0].moduleName()) Index: module_base.tmpl =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons/Python_bricks/module_base.tmpl,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -C2 -d -r1.1.2.1 -r1.1.2.2 *** module_base.tmpl 21 Apr 2003 22:53:05 -0000 1.1.2.1 --- module_base.tmpl 16 May 2003 11:02:47 -0000 1.1.2.2 *************** *** 1,4 **** --- 1,6 ---- ## This template will build the module + #import time import $(base_dir) + # Generated by mdl_generate_python_code.py / time.strftime("%Y/%m/%d %H:%M") from Modeling.Validation import ValidationException from mx.DateTime import DateTimeFrom |
From: <sbi...@us...> - 2003-05-16 11:01:28
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons/Python_bricks In directory sc8-pr-cvs1:/tmp/cvs-serv19810/ModelMasons/Python_bricks Modified Files: Tag: brch-0_9pre6-1-ModelMasons_base_generation_scheme base_module.tmpl Log Message: Added a timestamp in comment at beginning of file Index: base_module.tmpl =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons/Python_bricks/base_module.tmpl,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -C2 -d -r1.1.2.1 -r1.1.2.2 *** base_module.tmpl 21 Apr 2003 22:53:05 -0000 1.1.2.1 --- base_module.tmpl 16 May 2003 11:01:25 -0000 1.1.2.2 *************** *** 1,3 **** --- 1,5 ---- ## This template will build the <module>Base.py module + #import time + # Generated by mdl_generate_python_code.py / $(time.strftime("%Y/%m/%d %H:%M")) # DO NOT MODIFY THIS FILE -- IT WILL BE OVERWRITTEN # Instead, modify $(model.packageName).$(entities[0].moduleName()) |
From: <sbi...@us...> - 2003-05-16 10:46:27
|
Update of /cvsroot/modeling/ProjectModeling/Modeling In directory sc8-pr-cvs1:/tmp/cvs-serv14251 Modified Files: Tag: brch-0_9pre6-1-ModelMasons_base_generation_scheme Model.py Entity.py Attribute.py Relationship.py Log Message: Applied some changes made in 0.9pre7: added field 'comment' in Model, Entity, Attribute and Relationship Index: Model.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/Model.py,v retrieving revision 1.3 retrieving revision 1.3.4.1 diff -C2 -d -r1.3 -r1.3.4.1 *** Model.py 10 Jan 2003 10:45:44 -0000 1.3 --- Model.py 16 May 2003 10:46:22 -0000 1.3.4.1 *************** *** 55,59 **** _connectionDictionary={} _packageName='' ! def __init__(self, aName=''): "Initializes a model. A name **must** be provided." --- 55,60 ---- _connectionDictionary={} _packageName='' ! _comment='' ! def __init__(self, aName=''): "Initializes a model. A name **must** be provided." *************** *** 95,98 **** --- 96,103 ---- anEntity._setModel(self) + def comment(self): + "Returns the comment field" + return self._comment + def connectionDictionary(self): "Returns the connection dictionary" *************** *** 191,194 **** --- 196,203 ---- self._adaptorName=adaptorName + def setComment(self, aComment): + "Sets the comment field" + self._comment=aComment + def setConnectionDictionary(self, aConnectionDictionary): "Sets the connection dictionary" *************** *** 315,320 **** 'connectionDictionary': ('string', self.setConnectionDictionary, ! self.connectionDictionary) ! } --- 324,331 ---- 'connectionDictionary': ('string', self.setConnectionDictionary, ! self.connectionDictionary), ! 'comment': ('string', ! self.setComment, ! self.comment), } Index: Entity.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/Entity.py,v retrieving revision 1.10 retrieving revision 1.10.4.1 diff -C2 -d -r1.10 -r1.10.4.1 *** Entity.py 17 Mar 2003 10:27:09 -0000 1.10 --- Entity.py 16 May 2003 10:46:22 -0000 1.10.4.1 *************** *** 145,148 **** --- 145,149 ---- _attrsUsedForLocking=() _moduleName=None + _comment='' def __init__(self, name='', aModel=None): *************** *** 158,161 **** --- 159,163 ---- self._attrsUsedForLocking=() self._className=None + self._comment='' self._externalName='' self._model=None *************** *** 358,361 **** --- 360,367 ---- if rel.isClassProperty()]) + def comment(self): + "Returns the comment field" + return self._comment + def definedKeys(self): """ *************** *** 838,841 **** --- 844,851 ---- self._className=aName + def setComment(self, aComment): + "Sets the comment field" + self._comment=aComment + def setExternalName(self, externalName): "Sets the external name" *************** *** 1378,1381 **** --- 1388,1394 ---- self.setClassName, self.className ), + 'comment': ( 'string', + self.setComment, + self.comment), 'externalName': ( 'string', self.setExternalName, Index: Attribute.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/Attribute.py,v retrieving revision 1.11 retrieving revision 1.11.4.1 diff -C2 -d -r1.11 -r1.11.4.1 *** Attribute.py 17 Mar 2003 11:15:11 -0000 1.11 --- Attribute.py 16 May 2003 10:46:22 -0000 1.11.4.1 *************** *** 100,103 **** --- 100,104 ---- _columnName='' _width=0 + _comment='' def __init__(self, aName='', anEntity=None): *************** *** 111,114 **** --- 112,116 ---- self._allowsNone=1 self._columnName='' + self._comment='' self._defaultValue=None self._definition='' *************** *** 165,168 **** --- 167,174 ---- return self._columnName + def comment(self): + "Returns the comment field" + return self._comment + def defaultValue(self): "Returns the default value associated to this attribute" *************** *** 323,326 **** --- 329,336 ---- self._columnName=columnName + def setComment(self, aComment): + "Sets the comment field" + self._comment=aComment + def convertStringToAttributeType(self, aValue): """ *************** *** 595,598 **** --- 605,611 ---- self.setColumnName, self.columnName), + 'comment' : ( 'string', + self.setComment, + self.comment), 'displayLabel' : ('string', self.setDisplayLabel, *************** *** 638,642 **** subList=('name', 'columnName', 'precision', 'scale', 'width', 'externalType', #DB ! 'displayLabel', 'isClassProperty', 'isRequired', 'defaultValue', 'type', ) dict=self.fullPropertySet() --- 651,655 ---- subList=('name', 'columnName', 'precision', 'scale', 'width', 'externalType', #DB ! 'comment', 'displayLabel', 'isClassProperty', 'isRequired', 'defaultValue', 'type', ) dict=self.fullPropertySet() *************** *** 647,651 **** def flattenedPropertySet(self): subList=('name', 'displayLabel', 'isClassProperty', 'definition', ! 'isFlattened', ) dict=self.fullPropertySet() deleteKeys=filter(lambda k, list=subList: k not in list, dict.keys()) --- 660,664 ---- def flattenedPropertySet(self): subList=('name', 'displayLabel', 'isClassProperty', 'definition', ! 'isFlattened', 'comment') dict=self.fullPropertySet() deleteKeys=filter(lambda k, list=subList: k not in list, dict.keys()) Index: Relationship.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/Relationship.py,v retrieving revision 1.7 retrieving revision 1.7.4.1 diff -C2 -d -r1.7 -r1.7.4.1 *** Relationship.py 10 Feb 2003 12:12:15 -0000 1.7 --- Relationship.py 16 May 2003 10:46:22 -0000 1.7.4.1 *************** *** 69,72 **** --- 69,73 ---- # _isClassProperty=1 + _comment='' __implements__=(RelationshipInterface, XMLCapabilityInterface) *************** *** 76,79 **** --- 77,81 ---- self._deleteRule = DELETE_NULLIFY self._displayLabel = '' + self._comment = '' self._entity = None self._isClassProperty = 1 *************** *** 83,86 **** --- 85,92 ---- return + def comment(self): + "Returns the comment field" + return self._comment + def entity(self): "Return the relationship's source entity" *************** *** 146,149 **** --- 152,159 ---- return self._name + def setComment(self, aComment): + "Sets the comment field" + self._comment=aComment + def setDeleteRule(self, rule): """ *************** *** 280,283 **** --- 290,296 ---- "-" return { + 'comment' : ('string', + self.setComment, + self.comment), 'name' : ('string', lambda self=None,p=None: None, |
From: <sbi...@us...> - 2003-05-15 17:45:01
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/tests In directory sc8-pr-cvs1:/tmp/cvs-serv25871/tests Added Files: Tag: brch-0_9pre7-1-PyModel test_PyModel.py Log Message: Added PyModel.py and tests --- NEW FILE: test_PyModel.py --- #! /usr/bin/env python #----------------------------------------------------------------------------- # # Modeling Framework: an Object-Relational Bridge for python # (c) 2001, 2002, 2003 Sebastien Bigaret # # This file is part of the Modeling Framework. # # The Modeling Framework is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as published # by the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # # The Modeling Framework is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License along # with the Modeling Framework; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # #----------------------------------------------------------------------------- """ Tests for PyModel """ import unittest if __name__ == "__main__": import utils, sys utils.fixpath() from Modeling.PyModel import * class TestPyModel(unittest.TestCase): """ Tests for PyModel """ def checkEntitiesProperties(self, entities): """ For each entity in 'entities', check that its attributes and relationships entity() points to it. Also check that the relationships' destination entity is not None. See in particular the comment in updateComponent() for an explanation """ for e in entities: for a in e.attributes(): self.assertEqual(a.entity(), e) for r in e.relationships(): self.assertEqual(r.entity(), e) self.failUnless(r.destinationEntity(),'%s.%s.destinationEntity() is None'%(e.name(),r.name())) def setUp(self): self.model = Model('StoreEmployees',adaptorName='Postgresql') self.model.version='0.1' Entity.defaults['properties'] = [ APrimaryKey('id', isClassProperty=0, isRequired=1, doc='Default PK') ] AString.defaults['width'] = 20 def test_01_attr(self): "[PyModel] entity w/ attributes and default pk" model = self.model model.entities = [ Entity('Employee', properties=[ AString('lastName', isRequired=1, usedForLocking=1), AString('firstName', isRequired=1, width=50, usedForLocking=1), ] ), ] model.build() emp=model.component.entityNamed('Employee') self.checkEntitiesProperties((emp,)) self.assertEqual(emp.attributeNamed('lastName').width(), 20) self.assertEqual(emp.attributeNamed('firstName').width(), 50) self.assertEqual(emp.attributeNamed('firstName').isRequired(), 1) self.assertEqual(emp.primaryKeyAttributeNames(), ['id']) # default PK self.failIf(emp.primaryKeyAttributes()[0].isClassProperty()) self.assertEqual(emp.primaryKeyAttributes()[0].defaultValue(), None) def test_02_pk(self): "[PyModel] entity w/ pk" model = self.model model.entities = [ Entity('Employee', properties=[ APrimaryKey('ID', isClassProperty=1, isRequired=1, doc='SalesClerk PK') ] ), ] model.build() emp=model.component.entityNamed('Employee') self.checkEntitiesProperties((emp,)) self.assertEqual(emp.primaryKeyAttributeNames(), ['ID']) self.failUnless(emp.primaryKeyAttributes()[0].isClassProperty()) self.assertEqual(emp.primaryKeyAttributes()[0].defaultValue(), 0) def test_03_attrs_and_inheritance(self): "[PyModel] attrs_and_inheritance" model = self.model model.entities = [ Entity('Employee', properties=[ AString('lastName', isRequired=1, usedForLocking=1), AString('firstName', isRequired=1, width=50, usedForLocking=1), ] ), Entity('SalesClerk', parent='Employee', properties=[ APrimaryKey('id', isClassProperty=1, isRequired=1, # NB: avec ID & Rels c'est une erreur! doc='SalesClerk PK'), AString('firstName', isRequired=1, width=5, usedForLocking=1), ] ), Entity('Executive', parent='Employee', properties=[ AString('officeLocation', width=5), ] ), ] model.build() emp=model.component.entityNamed('Employee') sc=model.component.entityNamed('SalesClerk') ex=model.component.entityNamed('Executive') self.checkEntitiesProperties((emp,sc,ex)) self.assertEqual(emp.primaryKeyAttributeNames(), ['id']) self.assertEqual(emp.primaryKeyAttributeNames(), ['id']) # PK overriden self.assertEqual(emp.primaryKeyAttributeNames(), ['id']) self.failIf(emp.primaryKeyAttributes()[0].isClassProperty()) self.failIf(ex.primaryKeyAttributes()[0].isClassProperty()) self.failUnless(sc.primaryKeyAttributes()[0].isClassProperty()) # Propagation of attributes self.failIf([a for a in emp.attributesNames() if a not in sc.attributesNames()]) self.failIf([a for a in emp.attributesNames() if a not in ex.attributesNames()]) self.assertEqual(len(sc.attributes()),3) self.assertEqual(len(ex.attributes()),4) # self.assertEqual(emp.attributeNamed('firstName').width(), 50) self.assertEqual(sc.attributeNamed('firstName').width(), 5) self.assertEqual(emp.attributeNamed('id').entity(), emp) self.assertEqual(sc.attributeNamed('id').entity(), sc) self.assertEqual(ex.attributeNamed('id').entity(), ex) def test_04_fully_qualified_relationships_no_inverse(self): "[PyModel] fully_qualified_relationships" model = self.model model.entities = [ Entity('Employee', properties=[ AForeignKey('fkStore'), RToOne('toStore', 'Store',src='fkStore',dst='id'), RToMany('toMarks', 'Mark',src='id',dst='fkEmployee'), ] ), Entity('SalesClerk', parent='Employee'), Entity('Mark', properties=[ AForeignKey('fkEmployee') ]), Entity('Store'), ] model.build() emp=model.component.entityNamed('Employee') sc=model.component.entityNamed('SalesClerk') store=model.component.entityNamed('Store') mark=model.component.entityNamed('Mark') self.checkEntitiesProperties((emp,sc,store,mark)) self.assertEqual(len(sc.relationships()), 2) def check(self, toStore, toMarks, store, mark): self.failUnless(toStore.isToOne()) self.failUnless(toMarks.isToMany()) self.assertEqual(toStore.destinationEntity(), store) self.assertEqual(toMarks.destinationEntity(), mark) toStore=emp.propertyNamed('toStore') toMarks=emp.propertyNamed('toMarks') check(self, toStore, toMarks, store, mark) toStore=sc.propertyNamed('toStore') toMarks=sc.propertyNamed('toMarks') check(self, toStore, toMarks, store, mark) def test_05_unqualified_relationships_no_inverse(self): "[PyModel] unqualified_relationships_no_inverse" model = self.model model.entities = [ Entity('Employee', properties=[ RToMany('toMarks', 'Mark'), RToOne('toStore', 'Store'), ] ), Entity('SalesClerk', parent='Employee'), Entity('Mark'), Entity('Store'), ] model.build() emp=model.component.entityNamed('Employee') sc=model.component.entityNamed('SalesClerk') store=model.component.entityNamed('Store') mark=model.component.entityNamed('Mark') self.checkEntitiesProperties((emp,sc,store,mark)) self.assertEqual(len(sc.relationships()), 2) # Check that each entity has the expected number of attributes self.assertEqual(len(emp.attributes()), 2) # id + fk self.assertEqual(len(sc.attributes()), 2) # id + fk self.assertEqual(len(store.attributes()), 1) # id self.assertEqual(len(mark.attributes()), 2) # id + fk self.failUnless(emp.attributeNamed('fkStore')) self.failUnless(sc.attributeNamed('fkStore')) self.failUnless(mark.attributeNamed('fkEmployee')) def check(self, toStore, toMarks, store, mark): self.failUnless(toStore.isToOne()) self.failUnless(toMarks.isToMany()) self.assertEqual(toStore.destinationEntity(), store) self.assertEqual(toMarks.destinationEntity(), mark) # check the parent toStore=emp.propertyNamed('toStore') toMarks=emp.propertyNamed('toMarks') check(self, toStore, toMarks, store, mark) self.failIf(emp.propertyNamed('fkStore') not in toStore.sourceAttributes()) self.failIf(store.propertyNamed('id') not in toStore.destinationAttributes()) self.failIf(emp.propertyNamed('id') not in toMarks.sourceAttributes()) self.failIf(mark.propertyNamed('fkEmployee') not in toMarks.destinationAttributes()) # Also check the sub-entity toStore=sc.propertyNamed('toStore') toMarks=sc.propertyNamed('toMarks') check(self, toStore, toMarks, store, mark) self.failIf(sc.propertyNamed('fkStore') not in toStore.sourceAttributes()) self.failIf(store.propertyNamed('id') not in toStore.destinationAttributes()) self.failIf(sc.propertyNamed('id') not in toMarks.sourceAttributes()) self.failIf(mark.propertyNamed('fkEmployee') not in toMarks.destinationAttributes()) # test_06 qualified & unqualified # model = self.model # model.entities = [ # Entity('Employee', # properties=[ AForeignKey('fkStore'), # #RToOne('toStore', 'Store',src='fkStore',dst='id'), # RToMany('toMarks', 'Mark',src='id',dst='fkEmployee'), # ] ), # Entity('SalesClerk', parent='Employee'), # Entity('Mark', # properties=[ AForeignKey('fkEmployee'), # #RToOne('toEmployee','Employee',inverse='toMarks') # ] # ), # Entity('Store', # properties=[RToMany('toEmployees','Employee')#,src='id',dst='fkStore') # ]#,inverse='toStore')] # ), # # NB: quid si inverse='ghjgh'? --> TBD test! # ] def check_model(self, model): model.build() emp=model.component.entityNamed('Employee') sc=model.component.entityNamed('SalesClerk') store=model.component.entityNamed('Store') mark=model.component.entityNamed('Mark') self.checkEntitiesProperties((emp,sc,store,mark)) self.assertEqual(len(sc.relationships()), 2) def check(self, toStore, toMarks, store, mark): self.failUnless(toStore.isToOne()) self.failUnless(toMarks.isToMany()) self.assertEqual(toStore.destinationEntity(), store) self.assertEqual(toMarks.destinationEntity(), mark) toStore=emp.propertyNamed('toStore') toMarks=emp.propertyNamed('toMarks') check(self, toStore, toMarks, store, mark) toStore=sc.propertyNamed('toStore') toMarks=sc.propertyNamed('toMarks') check(self, toStore, toMarks, store, mark) #### JUSQU'ICI on est pareil que test_04 self.failUnless(mark.relationshipNamed('toEmployee').inverseRelationship()==emp.propertyNamed('toMarks')) self.failUnless(store.relationshipNamed('toEmployees').inverseRelationship()==emp.propertyNamed('toStore')) def test_07_relationships_with_inverse(self): "[PyModel] qualified_relationships_with_inverse" model = self.model model.entities = [ Entity('Employee', properties=[ AForeignKey('fkStore'), RToOne('toStore', 'Store',src='fkStore',dst='id'), RToMany('toMarks', 'Mark',src='id',dst='fkEmployee'), ] ), Entity('SalesClerk', parent='Employee'), Entity('Mark', properties=[ AForeignKey('fkEmployee'), RToOne('toEmployee','Employee',inverse='toMarks') ] ), Entity('Store', properties=[RToMany('toEmployees','Employee',inverse='toStore', )#src='id',dst='fkStore') ]#,inverse='toStore')] ), # NB: quid si inverse='ghjgh'? --> TBD test! ] self.check_model(self.model) # self.setUp() self.model.entities = [ Entity('Employee', properties=[ RToOne('toStore', 'Store'),#,src='fkStore',dst='id'), RToMany('toMarks', 'Mark'),#,src='id',dst='fkEmployee'), ] ), Entity('SalesClerk', parent='Employee'), Entity('Mark', properties=[ RToOne('toEmployee','Employee',inverse='toMarks') ] ), Entity('Store', properties=[RToMany('toEmployees','Employee',inverse='toStore',)] ), ] self.check_model(self.model) # Automatic creation of source + destination key self.setUp() self.model.entities = [ Entity('Employee', properties=[ RToOne('toStore', 'Store',src='fkStore',dst='id'), RToMany('toMarks', 'Mark',src='id',dst='fkEmployee'), ] ), Entity('SalesClerk', parent='Employee'), Entity('Mark', properties=[ RToOne('toEmployee','Employee',inverse='toMarks') ] ), Entity('Store', properties=[RToMany('toEmployees','Employee',inverse='toStore',)] ), ] #self.check_model(self.model) def test_08_qualified_relationships_with_inverse(self): "[PyModel] unqualified_relationships_with_inverse" model = self.model model.entities = [ Entity('Employee'), Entity('SalesClerk', parent='Employee'), Entity('Mark'), Entity('Store'), ] model.associations = [ Association('Employee', 'Store'), Association('Mark', 'Employee'), ] self.check_model(self.model) def test_suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(TestPyModel, "test_08")) return suite if __name__ == "__main__": verbose='-V' in sys.argv and 'Y' or ('-v' in sys.argv and 1 or 0) errs = utils.run_suite(test_suite(), verbosity=verbose) sys.exit(errs and 1 or 0) ## TBD: test init/build sur elements, p.ex. RToOne + cardinality, etc. |
From: <sbi...@us...> - 2003-05-15 17:45:01
|
Update of /cvsroot/modeling/ProjectModeling/Modeling In directory sc8-pr-cvs1:/tmp/cvs-serv25871 Added Files: Tag: brch-0_9pre7-1-PyModel PyModel.py Log Message: Added PyModel.py and tests --- NEW FILE: PyModel.py --- #----------------------------------------------------------------------------- # # Modeling Framework: an Object-Relational Bridge for python # (c) 2001, 2002, 2003 Sebastien Bigaret # # This file is part of the Modeling Framework. # # The Modeling Framework is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as published # by the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # # The Modeling Framework is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License along # with the Modeling Framework; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # #----------------------------------------------------------------------------- """ Pythonic Description of an OO-RDBM Model Rules: - a model is an object of type Model - a model may specify a list of entities, each of type Entity - an entity may specify a list of properties, that are either of type Attribute or \of type Relation - all references to attributes, relations, entities, models, is by their "name" i.e. not by their columnName or className, etc, as the case may be - whenever deemed useful, defaults are used - note that the default "type" for an attribute is int (not string -- seems more logical to me) - delete rule values are in lowercase New Changes to note: parentEntity -> parent Entity only exposes a properties[] (that holds all attributes and relations) default for Model.adaptorName is None added doc attribute on all description classes Previous changes: defaults class dictionary variable, for all model description classes deleteRule -> delete multiplicityLowerBound and miltiplicity upperBound -> multiplicity parentEntity -> isAlso default for displayLabel is value of name (not of columnName) Entity only has attributes[] (that may also be relations) """ ## import Modeling from Entity import externalNameForInternalName from utils import isListOrTuple identity=lambda x: x def debug(msg): print msg def error(msg): raise RuntimeError, msg class MP: def __init__(self, method, *args): self.method=method self.param=args class BaseDescription: ''' Base description class (should not be exported to client code) ''' VERSION='0.1' defaults = {} def update(self): pass ## NB pourrait servir a mettre une derniere fois a jour le component ## en fct. de self.__dict__ filtr'e par self.__class__.defaults.keys() ## ++ ?? peut-etre ajouter un truc du genre 'ignore' dans les defaults def build(self, model): pass def requiredField(self, field): ''' make test more useful ''' if not field: raise ValueError, 'Required field' return field def defaultedField(self, field, defaultValue): if field: return field else: return defaultValue def clone(self, descriptionObject): ''' return an independant copy of object ''' return descriptionObject def toXML(self): return '<later/>' #def __str__(self): # return '<%s instance at %s>'%(str(self.__class__), hex(id(self))) ## class Model(BaseDescription): ''' Describes a Model ''' defaults={ 'packageName': MP(identity, 'name'), 'adaptorName': '', 'connDict': { 'host': '', 'database': '', 'user': '', 'password': '' }, 'entities': [], 'associations': [], 'doc': '', } def __init__(self, name, **kw): self.name=self.requiredField(name) self.entities=list(kw.get('entities', [])) from Model import Model as MModel self.component=MModel(name) updateComponent(self, kw, Model.defaults, name, ignore=('entities','associations')) def entityNamed(self, name): for e in self.entities: if e.name==name: return e return None def validate(self): ''' validate this model instance ''' pass def generatePython(self,entityName=None): ''' generate code for model, or only for entityName if specified ''' pass def generateDBSchema(self,entityName=None): ''' Generate SQL only ''' pass def createDBSchema(self,entityName=None): ''' drops and recreates from scratch ''' pass def updateDBSchema(self,mode,entityName=None): ''' operate on existing tables (and defined by this schema), employing mode: - check: only report differences between model and existent DB - incremental: only add/modify columns in existing tables - clean: add/modify new columns/tables, and drop obsolete ones Note: renaming of columns or tables? ''' pass def addEntity(self, entityDescObj): ''' add entity to model ''' pass def removeEntity(self, name): ''' remove entity from model ''' pass def build_associations(self): """ """ debug('Processing associations') for assoc in self.associations: assoc.build(self) def build(self): # Check version if getattr(self, 'version', None)!=BaseDescription.VERSION: raise ValueError, 'Incompatible versions' # Build ordered list of entities self.ordered_entities=oe=[] entities=list(self.entities) entities_processed=[] for entity in [e for e in entities if not e.parent]: oe.append(entity) entities_processed.append(entity.name) entities.remove(entity) while entities: print [e.name for e in entities], entities_processed es=[e for e in entities if e.parent in entities_processed] for entity in es: entities.remove(entity) entities_processed.append(entity.name) oe.append(entity) # Build defaults, parent, attributes for entity in self.ordered_entities: entity.prebuild_with_defaults(model=self) entity.prebuild_with_parent_properties(model=self) # Build Associations self.build_associations() for entity in self.ordered_entities: # propagates changes made by Associations entity.prebuild_with_parent_properties(model=self) # Build attributes for entity in self.ordered_entities: entity.build_attributes(model=self) self.component.addEntity(entity.component) # Check inheritance for entity in self.ordered_entities: if entity.parent: superEntity=self.component.entityNamed(entity.parent) superEntity.addSubEntity(entity.component) # model / build phase 2 for entity in self.ordered_entities: entity.build_preprocess_relationships_and_inverse(self) for entity in self.ordered_entities: entity.build_toOne_relationships(self) for entity in self.ordered_entities: entity.build_toMany_relationships(self) ## class Entity(BaseDescription): ''' Describes an Entity ''' defaults={ 'className': MP(identity, 'name'), 'externalName': MP(externalNameForInternalName, 'name'), 'moduleName': MP(identity, 'name'), 'typeName': '', 'isAbstract': 0, 'isReadOnly': 0, 'properties': [], 'parent': '', 'doc': None, } def __init__(self, name, **kw): self.name=self.requiredField(name) #self.properties=kw.get('properties', ()) from Entity import Entity as MEntity self.component=MEntity(name) updateComponent(self, kw, Entity.defaults, name, ignore=('parent','properties')) def addAttribute(self, attributeDescObj, model): ''' add attribute to model ''' debug('Entity.addAttribute e: %s / attr: %s'%(self.name, attributeDescObj.name)) # check it does not already exist a=self.attributeNamed(attributeDescObj.name) if a: debug(' Found it -- ignoring / .entity()=%s'%a.component.entity()) return # continue self.properties.append(attributeDescObj) attributeDescObj.build(model, self) # bizarre, plutot build(entity, model) self.component.addAttribute(attributeDescObj.component) self.processAttributes(model) self.propagate_attribute(attributeDescObj, model) def attFKName(self, destEntityName): n='fk'+destEntityName count=1 while self.propertyNamed(n): n='fk'+destEntityName+str(count) count+=1 return n def attributeNamed(self, name): for prop in [r for r in self.properties if isinstance(r, Attribute)]: if prop.name==name: return prop return None def removeAttribute(self, attributeDescObj): ''' remove attribute from model ''' pass def addRelation(self, relationDescObj): ''' add relation to model ''' pass def attributes(self): "-" return [r for r in self.properties if isinstance(r, Attribute)] def propertyNamed(self, name): a=self.attributeNamed(name) if a: return a else: return self.relationshipNamed(name) def relationshipNamed(self, name): "-" for r in self.relationships(): if r.name==name: return r return None def relationships(self): "-" return [r for r in self.properties if isinstance(r, BaseRelation)] def removeRelation(self, relationDescObj): ''' remove relation from model ''' pass def inheritFrom(self, entityDescObj): ''' add to this entity all other atts & rels defined in entityDescObj ''' pass def primaryKey(self): """ Returns the entity's PK """ for prop in self.properties: if isinstance(prop, APrimaryKey): return prop return 0 def propagate_attribute(self, attributeDescObj, model): debug('Entity.propagate_attribute e: %s / attr: %s'%(self.name, attributeDescObj.name)) for e in [ee.name() for ee in self.component.subEntities()]: entity=model.entityNamed(e) #if not entity.component.attributeNamed(attributeDescObj.name): entity.addAttribute(attributeDescObj.clone(), model) def processAttributes(self, model): # Process attributes and look for PKs & attributes usedForLocking pks=[] usedForLocking=[] for prop in self.attributes(): prop.build(model, self) if isinstance(prop, APrimaryKey): pks.append(prop.component) if prop.usedForLocking: usedForLocking.append(prop.component) self.component.setPrimaryKeyAttributes(pks) self.component.setAttributesUsedForLocking(usedForLocking) def prebuild_with_defaults(self, model): "Phase 1" debug('Entity.build/1: %s'%self.name) # check defaults properties if Entity.defaults.get('properties'): # Update properties iff: # - they are not already present # - we do not add a PK if one is already defined self_prop_names=[prop.name for prop in self.properties] for dprop in Entity.defaults['properties']: if dprop.name not in self_prop_names: if not ( self.primaryKey() and isinstance(dprop, APrimaryKey) ): self.properties.append(dprop.clone()) def prebuild_with_parent_properties(self, model): """ Builds a Modeling.Entity / Phase 2 """ debug('Entity.build/2: %s'%self.name) # Check inheritance if self.parent: parent=model.entityNamed(self.parent) if not parent: raise ValueError, "Unable to find parent '%s' for entity '%s'"%(self.parent, self.name) # Update the properties self_prop_names=[prop.name for prop in self.properties] for pprop in parent.properties: if pprop.name in self_prop_names: # Overriden property, shouldnt be changed continue clone=pprop.clone() clone.propagated_by=self.parent self.properties.append(clone) def build_attributes(self, model): """ Builds a Modeling.Entity / Phase 3 """ debug('Entity.build/3: %s'%self.name) ## ATTRIBUTES # Add all attributes for prop in self.attributes(): prop.build(model, self) self.component.addAttribute(prop.component) debug('build_attributes %s.%s: %s'%(self.name,prop.name,prop.component.entity())) self.processAttributes(model) def build_preprocess_relationships_and_inverse(self, model): """ Builds a Modeling.Entity / Phase 4 """ if self.parent: return debug('Entity.build/4: %s'%self.name) for r in self.relationships(): destEntity=model.entityNamed(r.destination) if not destEntity: raise ValueError, 'Relation %s.%s: cannot find destination entity %s'%(self.name,r.name,r.destination) if getattr(r, 'inverse',None): self.forward_rel_info(r, model) def forward_rel_info(self, rel, model): ''' ''' debug('forward_rel_info %s.%s'%(self.name,rel.name)) def check_or_make_equal(x,y): if x and y: assert x == y return x and (x,x) or (y,y) for e in self.component.allSubEntities(): r=model.entityNamed(e.name()).relationshipNamed(rel.name) r.inverse='' rel.src,r.src=check_or_make_equal(rel.src,r.src) rel.dst,r.dst=check_or_make_equal(rel.dst,r.dst) if rel.inverse: invr=model.entityNamed(rel.destination).relationshipNamed(rel.inverse) if invr.inverse: assert invr.inverse==rel.name else: invr.inverse=rel.name rel.src,invr.dst=check_or_make_equal(rel.src,invr.dst) rel.dst,invr.src=check_or_make_equal(rel.dst,invr.src) def build_toOne_relationships(self, model): toOneRels=[r for r in self.properties if isinstance(r, RToOne)] for prop in toOneRels: # Note: we build() AFTER we add the relationship, or # relationship.component.entity==None and then it's impossible to # add a join to such a MRelationship self.component.addRelationship(prop.component) prop.build(model, self) def build_toMany_relationships(self, model): toManyRels=[r for r in self.properties if isinstance(r, RToMany)] for prop in toManyRels: # Note: we build() AFTER we add the relationship, or # relationship.component.entity==None and then it's impossible to # add a join to such a MRelationship self.component.addRelationship(prop.component) prop.build(model, self) def _void_void(self, model): # We need to have two phases: building relationships requires that all # attributes of all entities are previously initalized and built. ## RELATIONS toOneRels=[r for r in self.properties if isinstance(r, RToOne)] toManyRels={} [toManyRels.setdefault(k,v) for k,v in [(r.name,r) for r in self.properties if isinstance(r, RToMany)]] # process inverse #for r in toOneRels+toManyRels ## TBD: ici il faut encore 2 phases: 1. traiter toutes les toOnes, ## puis 2. toutes les toManys, ou alors 1. traiter les inverses, 2. traiter ## les relations. ## La 2eme solution implique plus de tests dans le build des relations ## (si inverse mais pas encore traitee, chercher/creer la fk et sinon ## recuperer la bonne avec le bon nom... # toOne #print toManyRels for prop in toOneRels: # Note: we build() AFTER we add the relationship, or # relationship.component.entity==None and then it's impossible to # add a join to such a MRelationship self.component.addRelationship(prop.component) prop.build(model, self) # toMany for prop in toManyRels.values(): self.component.addRelationship(prop.component) prop.build(model, self) ## TBD: RETURN les entites modifiees pour update et propagation! ## ex. updateAfterChanges() ## pourrait tester l'existant avec entity.propertyNamed ## class Attribute(BaseDescription): ''' Describes an Attribute ''' defaults={ 'columnName': MP(externalNameForInternalName, 'name'), #'key': 0, 'usedForLocking': 0, 'type': 'int', 'externalType': 'INTEGER', 'isClassProperty': 1, 'isRequired': 0, 'precision': 0, 'width': 0, 'scale': 0, 'defaultValue': None, 'displayLabel': '', 'doc': None, } def __init__(self, name, **kw): self.name=self.requiredField(name) from Attribute import Attribute as MAttribute self.component=MAttribute(name) updateComponent(self, kw, Attribute.defaults, name, ignore='usedForLocking') def build(self, model, entity): pass def clone(self): d=self.__dict__.copy() try: del d['component'] except: pass clone=apply(self.__class__, (), d) return clone class AInteger(Attribute): defaults={ 'type': 'int', 'externalType': 'INTEGER', 'defaultValue': 0, } def __init__(self, name, **kw): apply(Attribute.__init__.im_func, (self, name), kw) updateComponent(self, kw, AInteger.defaults, name, ignore='usedForLocking') class AString(Attribute): defaults={ 'type': 'string', 'externalType': 'VARCHAR', 'width': 255, 'defaultValue': '', } def __init__(self, name, **kw): apply(Attribute.__init__.im_func, (self, name), kw) updateComponent(self, kw, AString.defaults, name, ignore='usedForLocking') # http://www.onlamp.com/pub/a/onlamp/2001/09/13/aboutSQL.html # # SQL Wisdom #7) The data type is invariably different -- even if it has the # same name -- in another database. Always check the documentation. class AFloat(Attribute): defaults={ 'type': 'float', 'externalType': 'NUMERIC', 'precision': 15, 'scale': 5, 'defaultValue': 0.0, } def __init__(self, name, **kw): apply(Attribute.__init__.im_func, (self, name), kw) updateComponent(self, kw, AFloat.defaults, name, ignore='usedForLocking') class ADateTime(Attribute): defaults={ 'type': 'DateTime', 'externalType': 'TIMESTAMP', 'defaultValue': None, } def __init__(self, name, **kw): apply(Attribute.__init__.im_func, (self, name), kw) updateComponent(self, kw, ADateTime.defaults, name, ignore='usedForLocking') class APrimaryKey(AInteger): defaults={ 'isClassProperty': 0, 'isRequired': 1, 'defaultValue': MP(lambda i: (i and [0] or [None])[0], 'isClassProperty'), 'doc': 'Primary Key', } def __init__(self, name='id', **kw): apply(AInteger.__init__.im_func, (self, name), kw) updateComponent(self, kw, APrimaryKey.defaults, name, ignore='usedForLocking') class AForeignKey(AInteger): defaults={ 'isClassProperty': 0, 'isRequired': 0, 'defaultValue': None, 'doc': 'Foreign Key', } def __init__(self, name='id', **kw): apply(AInteger.__init__.im_func, (self, name), kw) updateComponent(self, kw, AForeignKey.defaults, name, ignore='usedForLocking') ## def xor(a,b): return not not ((a and not b) or (not a and b)) class BaseRelation(BaseDescription): ''' Describes a Relation ''' defaults={ 'delete': 0, #'key': 0, #'destinationEntity': '', ##'usedForLocking': 0, 'isClassProperty': 1, 'multiplicity': [0,1], 'joinSemantic': 0, 'src': '', 'dst': '', 'displayLabel': '', 'doc': '', 'inverse': '', } # Additinal attr. for self.: src_dst_specified def __init__(self, name, destination, **kw): self.name=self.requiredField(name) self.destination=self.requiredField(destination) from Relationship import SimpleRelationship as MRelationship self.component=MRelationship(name) updateComponent(self,kw,BaseRelation.defaults,name, ignore=('src', 'dst', 'multiplicity', 'src_dst_specified', 'inverse')) if xor(self.src, self.dst): raise ValueError, "Parameters src and dst should be both specified" def clone(self): d=self.__dict__.copy() try: del d['component'] # we do not want to copy this except: pass try: del d['src_dst_specified'] except: pass clone=apply(self.__class__, (), d) return clone class RToOne(BaseRelation): defaults={ 'multiplicity': [0,1], 'joinSemantic': 0, } propagated_by=None def __init__(self, name, destination, **kw): apply(BaseRelation.__init__.im_func, (self, name, destination), kw) updateComponent(self, kw, RToOne.defaults, name, ignore=('src', 'dst', 'multiplicity', 'src_dst_specified', 'inverse')) def build(self, model, entity): debug('(build toOne) Relation %s.%s'%(entity.name,self.name)) self.src_dst_specified=not not self.src destEntity=model.entityNamed(self.destination) destMEntity=destEntity.component #print model.component.entitiesNames() # Check multiplicity lowB=int(self.multiplicity[0]) uppB=int(self.multiplicity[1]) err='' if lowB not in (0,1): err+='Lower bound must be 0 or 1. ' if uppB not in (0,1): err+='Upper bound must be 0 or 1. ' if err: raise ValueError, 'Relation %s.%s: %s'%(entity.component.name(), self.component.name(), err) self.component.setMultiplicity(lowB, uppB) # Process src & dst attributes if not self.src_dst_specified: destinationMAttribute=destMEntity.primaryKeyAttributes()[0] if not self.propagated_by: sourceAttribute=AForeignKey(entity.attFKName(destEntity.name)) else: # The attribute has already been propagated, find & re-use it mparent=model.entityNamed(self.propagated_by).component mparent_destAttr=mparent.relationshipNamed(self.name).sourceAttributes() fkName=mparent_destAttr[0].name() sourceAttribute=entity.attributeNamed(fkName) if not sourceAttribute: error('Could not find src.attr. %s.%s for relationship %s.%s with %s inheriting from parent=%s (propagated_by=%s).\nThis should not happen, please report to <mod...@li...> along with your model'%(entity.name,fkName,entity.name,self.name,entity.name,entity.parent, self.propagated_by)) entity.addAttribute(sourceAttribute, model) sourceMAttribute=sourceAttribute.component self.src=sourceAttribute.name self.dst=destinationMAttribute.name() entity.forward_rel_info(self, model) else: # src & dst specified sourceMAttribute=entity.component.attributeNamed(self.src) if not sourceMAttribute: raise ValueError, 'Relation %s.%s: unable to find source attribute %s.%s'%(entity.component.name(), self.component.name(), entity.name, self.src) destinationMAttribute=destMEntity.attributeNamed(self.dst) # check destinationAttribute if not destinationMAttribute: if self.dst: err_msg='Relation %s.%s: unable to find destination attribute %s.%s'%(entity.name, self.name, self.destination, self.dst) else: err_msg='Relation %s.%s: unable to find destination attribute: no primary key declared for entity %s'%(entity.name, self.name, self.destination) raise ValueError, err_msg # src and dest are set, ok from Join import Join as MJoin j=MJoin(sourceMAttribute, destinationMAttribute) self.component.addJoin(j) #if not self.component.destinationEntity(): import pdb ; pdb.set_trace() class RToMany(BaseRelation): defaults={ 'multiplicity': [0,None], 'joinSemantic': 0, } propagated_by=None def __init__(self, name, destination, **kw): apply(BaseRelation.__init__.im_func, (self, name, destination), kw) updateComponent(self, kw, RToMany.defaults, name, ignore=('src', 'dst', 'multiplicity','inverse')) def build(self, model, entity): self.src_dst_specified=not not self.src debug('(build toMany) Relation %s.%s(%s->%s)'%(entity.name,self.name, self.src, self.dst)) #print model.component.entitiesNames() destEntity=model.entityNamed(self.destination) destMEntity=destEntity.component # Check multiplicity lowB=int(self.multiplicity[0]) uppB=self.multiplicity[1] err='' if uppB in (0,1): err+='Invalid value for upper bound of a toMany rel.' if err: raise ValueError, 'Relation %s.%s: %s'%(entity.component.name(), self.component.name(), err) self.component.setMultiplicity(lowB, uppB) # Process src & dst attributes if not self.src_dst_specified: sourceMAttribute=entity.component.primaryKeyAttributes()[0] if not self.propagated_by: destinationAttribute=AForeignKey(destEntity.attFKName(entity.name)) else: # The attribute has already been propagated, find it mparent=model.entityNamed(self.propagated_by).component mparent_destAttr=mparent.relationshipNamed(self.name).destinationAttributes() fkName=mparent_destAttr[0].name() destinationAttribute=destEntity.attributeNamed(fkName) if not destinationAttribute: error('Could not find dest.attr. %s.%s for relationship %s.%s with %s inheriting from parent=%s (propagated_by=%s).\nThis should not happen, please report to <mod...@li...> along with your model'%(destEntity.name,fkName,entity.name,self.name,entity.name,entity.parent, self.propagated_by)) destEntity.addAttribute(destinationAttribute, model) destinationMAttribute=destinationAttribute.component self.src=sourceMAttribute.name() self.dst=destinationMAttribute.name() entity.forward_rel_info(self, model) else: # src and dst specified sourceMAttribute=entity.component.attributeNamed(self.src) destinationMAttribute=destMEntity.attributeNamed(self.dst) if not destinationMAttribute: raise ValueError, 'Relation %s.%s: unable to find destination attribute %s.%s'%(entity.component.name(), self.component.name(), self.destination, self.dst) # Check source attribute if not sourceMAttribute: if self.src: err_msg='Relation %s.%s: unable to find source attribute %s.%s'%(entity.name, self.name, entity.name, self.src) else: err_msg='Relation %s.%s: unable to find source attribute: no primary key declared for entity %s'%(entity.name, self.name, entity.name) raise ValueError, err_msg # src and dest are set from Join import Join as MJoin j=MJoin(sourceMAttribute, destinationMAttribute) self.component.addJoin(j) #if not self.component.destinationEntity(): import pdb ; pdb.set_trace() class Association(BaseDescription): ''' Describes a Relation between 2 entities ''' # TBD a placer dans les prop. de Entity # ex. Relation('Employee', 'Address', ([0,None],cascade), ([0,1],deny)) # --> soit ca # --> soit tout a la main # --> soit dans les Entity, RToOne, RToMany: # - avec seulement destEntity # - avec destEntity et inverse= def __init__(self, src, dst, multiplicity=[0,1], invMultiplicity=[0,None], srcProps={}, dstProps={}): if multiplicity[1]>1: raise ValueError, 'invalid mult' if not (invMultiplicity[1] in (None, '*', -1) or invMultiplicity[0]>1): raise ValueError, 'invalid invMult' self.src=src self.dst=dst ## TBD 1: inverser src/dst si multiplicities sont inversees ## TBD 2: possibilite d'ajout des srcKey/dstKey self.multiplicity=multiplicity self.invMultiplicity=invMultiplicity self.srcProps=srcProps self.dstProps=dstProps def build(self, model): srcE=model.entityNamed(self.src) if not srcE: raise ValueError, 'Association: Unable to find source entity %s'%self.src dstE=model.entityNamed(self.dst) if not dstE: raise ValueError, 'Association: Unable to find destination entity %s'%self.dst dstAtt=dstE.primaryKey() if not dstAtt: dstAtt=APrimaryKey() dstE.properties.append(srcAtt) # FK: create it (TBD: unless ajout dstKey cf __init__) srcAtt=AForeignKey(srcE.attFKName(dstE.name)) srcE.properties.append(srcAtt) # Relationships srcRelName='to'+dstE.name # TBD: build it appropriately! dstRelName='to'+srcE.name+'s' # TBD: build it appropriately! srcRel=RToOne(srcRelName, dstE.name, ## TBD: +properties src=srcAtt.name, dst=dstAtt.name) dstRel=RToMany(dstRelName, srcE.name, ## TBD: +properties src=dstAtt.name, dst=srcAtt.name) srcE.properties.append(srcRel) dstE.properties.append(dstRel) ## def updateComponent(object, kw, defaults, name, ignore=()): """ Parameters: component -- kw -- NB: kw is not modified defaults -- name -- """ def copy(v): if isListOrTuple(v): return list(v) #return list(v) if type(v) is type({}): return v.copy() #if hasattr(v, 'clone') and callable(v.clone): # print '###Cloning' # return v.clone() # props else: return v if type(ignore) is type(''): ignore=[ignore] ignore=list(ignore) ; ignore.extend(['name','propagated_by']) _kw=defaults.copy() # We need to clone the defaults['properties'], such as in Entity.defaults: # when this is not done, Entities.default is reused as is in # different entities; e.g. each default attr. is assigned # to different entities, which in turn manipulate and change that attr. # and its component --> a test like in # test_PyModel.checkEntitiesProperties() then fails. clone_or_self=lambda p: (hasattr(p, 'clone') and callable(p.clone)) and p.clone() or p if _kw.get('properties'): _kw['properties']=map(clone_or_self, _kw['properties']) _kw.update(kw) ; kw=_kw kw['name']=name for k,v in kw.items(): # On ajoute tout a l'objet aussi, ca sert pdt le build setattr(object,k,copy(v)) if k in ignore: continue if isinstance(v,MP): l=[kw[n] for n in v.param] v=apply(v.method, l) else: v=copy(v) #try: print k, ': ', v #except: import pdb ; pdb.set_trace() object.component.takeStoredValueForKey(v,k) ## |
From: <sbi...@us...> - 2003-05-15 17:44:23
|
Update of /cvsroot/modeling/ProjectModeling/Modeling In directory sc8-pr-cvs1:/tmp/cvs-serv25464 Modified Files: Tag: brch-0_9pre7-1-PyModel Entity.py Model.py Attribute.py Relationship.py Log Message: Added: handleTakeStoredValueForUnboundKey(): used by PyModel e.g. when assigning 'doc' the value should go to the object's field 'comment' Index: Entity.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/Entity.py,v retrieving revision 1.11 retrieving revision 1.11.2.1 diff -C2 -d -r1.11 -r1.11.2.1 *** Entity.py 22 Apr 2003 09:31:56 -0000 1.11 --- Entity.py 15 May 2003 17:44:19 -0000 1.11.2.1 *************** *** 33,36 **** --- 33,37 ---- from XMLutils import * from EntityClassDescription import EntityClassDescription + from KeyValueCoding import KeyValueCoding from Model import ModelError from Attribute import Attribute *************** *** 115,119 **** from Persistent import Persistent ! class Entity(XMLCapability, Persistent): """ Describes an entity --- 116,120 ---- from Persistent import Persistent ! class Entity(XMLCapability, Persistent, KeyValueCoding): """ Describes an entity *************** *** 1415,1420 **** ## ! ## Validation of an Entity ! ## - ## --- 1416,1430 ---- ## ! ## KeyValueCoding error handling ! ## ! def handleAssignementForUnboundKey(self, value, key): ! if key=='doc': self.setComment(value) ! else: ! raise AttributeError, key ! handleTakeStoredValueForUnboundKey=handleAssignementForUnboundKey ! ! ## ! ## TBD Validation of an Entity ! ## ## Index: Model.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/Model.py,v retrieving revision 1.4 retrieving revision 1.4.2.1 diff -C2 -d -r1.4 -r1.4.2.1 *** Model.py 22 Apr 2003 09:31:56 -0000 1.4 --- Model.py 15 May 2003 17:44:20 -0000 1.4.2.1 *************** *** 40,44 **** from utils import isaValidName from XMLutils import * ! import types --- 40,44 ---- from utils import isaValidName from XMLutils import * ! from KeyValueCoding import KeyValueCoding import types *************** *** 49,53 **** from Persistent import Persistent ! class Model(Persistent, XMLCapability): "Describes a model" _is_a_model = 1 --- 49,53 ---- from Persistent import Persistent ! class Model(Persistent, XMLCapability, KeyValueCoding): "Describes a model" _is_a_model = 1 *************** *** 330,333 **** --- 330,343 ---- } + ## + ## KeyValueCoding error handling + ## + def handleAssignementForUnboundKey(self, value, key): + if key=='connDict': self.setConnectionDictionary(value) + elif key=='doc': self.setComment(value) + else: + raise AttributeError, key + handleTakeStoredValueForUnboundKey=handleAssignementForUnboundKey + # Validation # Index: Attribute.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/Attribute.py,v retrieving revision 1.12 retrieving revision 1.12.2.1 diff -C2 -d -r1.12 -r1.12.2.1 *** Attribute.py 22 Apr 2003 09:31:56 -0000 1.12 --- Attribute.py 15 May 2003 17:44:20 -0000 1.12.2.1 *************** *** 37,40 **** --- 37,41 ---- from XMLutils import * from Model import ModelError + from KeyValueCoding import KeyValueCoding import Validation from Modeling.utils import capitalizeFirstLetter *************** *** 85,89 **** from Persistent import Persistent ! class Attribute(Persistent, XMLCapability): "Describes an attribute" # + public/private _TBD --- 86,90 ---- from Persistent import Persistent ! class Attribute(Persistent, XMLCapability, KeyValueCoding): "Describes an attribute" # + public/private _TBD *************** *** 678,679 **** --- 679,688 ---- raise 'Unimplemented' + ## + ## KeyValueCoding error handling + ## + def handleAssignementForUnboundKey(self, value, key): + if key=='doc': self.setComment(value) + else: + raise AttributeError, key + handleTakeStoredValueForUnboundKey=handleAssignementForUnboundKey Index: Relationship.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/Relationship.py,v retrieving revision 1.8 retrieving revision 1.8.2.1 diff -C2 -d -r1.8 -r1.8.2.1 *** Relationship.py 22 Apr 2003 09:31:56 -0000 1.8 --- Relationship.py 15 May 2003 17:44:20 -0000 1.8.2.1 *************** *** 32,35 **** --- 32,36 ---- from Join import Join from utils import isaValidName, toBoolean + from KeyValueCoding import KeyValueCoding from XMLutils import * import Validation *************** *** 64,68 **** ! class Relationship(Persistent, XMLCapability): "See interfaces.Relationship for detail" --- 65,69 ---- ! class Relationship(Persistent, XMLCapability, KeyValueCoding): "See interfaces.Relationship for detail" *************** *** 205,213 **** upperBound -- must be a strictly positive integer, or -1 for a non ! constrained to-many relationship. Special value '*' is ! equivalent to -1. """ ! if upperBound=='*': upperBound=-1 assert(int(upperBound)>0 or int(upperBound)==-1) self._multUpper=int(upperBound) --- 206,214 ---- upperBound -- must be a strictly positive integer, or -1 for a non ! constrained to-many relationship. Special values '*' ! and None are equivalent to -1. """ ! if upperBound in ('*', None): upperBound=-1 assert(int(upperBound)>0 or int(upperBound)==-1) self._multUpper=int(upperBound) *************** *** 339,342 **** --- 340,344 ---- self._propagatesPK = 0 self._ownsDestination = 0 + print 'RELATIONSHIP INIT %s'%aName return *************** *** 802,805 **** --- 804,817 ---- return d + ## + ## KeyValueCoding error handling + ## + def handleAssignementForUnboundKey(self, value, key): + if key=='doc': self.setComment(value) + elif key=='delete': self.setDeleteRule(value) + else: + raise AttributeError, key + handleTakeStoredValueForUnboundKey=handleAssignementForUnboundKey + class FlattenedRelationship(Relationship): *************** *** 1162,1166 **** return d - # Validation # --- 1174,1177 ---- |
From: <sbi...@us...> - 2003-05-10 17:41:20
|
Update of /cvsroot/modeling/ProjectModeling/Modeling In directory sc8-pr-cvs1:/tmp/cvs-serv10438 Removed Files: MANIFEST Log Message: Removed deprecated file --- MANIFEST DELETED --- |
From: <sbi...@us...> - 2003-05-10 17:38:27
|
Update of /cvsroot/modeling/ProjectModeling/Modeling In directory sc8-pr-cvs1:/tmp/cvs-serv8975/Modeling Modified Files: CHANGES Log Message: Fixed in public release 0.9pre7.1 (and tagged as 0.9pre7): The script mdl_compile_model.py was not included in the 0.9pre7 tarball. Index: CHANGES =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/CHANGES,v retrieving revision 1.101 retrieving revision 1.102 diff -C2 -d -r1.101 -r1.102 *** CHANGES 7 May 2003 11:22:06 -0000 1.101 --- CHANGES 10 May 2003 17:38:24 -0000 1.102 *************** *** 13,16 **** --- 13,21 ---- password). See tests/Postgresql.cfg for an example. + 0.9-pre-7.1 (2003/05/08) + ----------- + + * Forgot to include mdl_compile_model.py + 0.9-pre-7 (2003/05/06) --------- |
From: <sbi...@us...> - 2003-05-10 17:38:27
|
Update of /cvsroot/modeling/ProjectModeling In directory sc8-pr-cvs1:/tmp/cvs-serv8975 Modified Files: MANIFEST.in Log Message: Fixed in public release 0.9pre7.1 (and tagged as 0.9pre7): The script mdl_compile_model.py was not included in the 0.9pre7 tarball. Index: MANIFEST.in =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/MANIFEST.in,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** MANIFEST.in 4 Feb 2003 08:12:05 -0000 1.5 --- MANIFEST.in 10 May 2003 17:38:23 -0000 1.6 *************** *** 12,15 **** --- 12,16 ---- include Modeling/scripts/mdl_generate_python_code.py include Modeling/scripts/mdl_validate_model.py + include Modeling/scripts/mdl_compile_model.py include Modeling/tests/README |
From: <sbi...@us...> - 2003-05-07 11:28:48
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/doc/UserGuide In directory sc8-pr-cvs1:/tmp/cvs-serv24374/doc/UserGuide Modified Files: EnvironmentVariables.tex Log Message: Fixed typos Index: EnvironmentVariables.tex =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/doc/UserGuide/EnvironmentVariables.tex,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** EnvironmentVariables.tex 7 May 2003 11:22:07 -0000 1.5 --- EnvironmentVariables.tex 7 May 2003 11:28:45 -0000 1.6 *************** *** 4,8 **** \begin{tableiii}{p{1cm}p{11cm}|p{3cm}}{code}{Name}{Description}{Possible values} ! \lineiii{MDL_DB_CONNECTIONS}{}{} \lineiii{}{It happens that a model can be written in different places: in an xml file, in a python file, and even in a pickle when you use --- 4,8 ---- \begin{tableiii}{p{1cm}p{11cm}|p{3cm}}{code}{Name}{Description}{Possible values} ! \lineiii{MDL_DB_CONNECTIONS_CFG}{}{} \lineiii{}{It happens that a model can be written in different places: in an xml file, in a python file, and even in a pickle when you use |
From: <sbi...@us...> - 2003-05-07 11:28:48
|
Update of /cvsroot/modeling/ProjectModeling/Modeling In directory sc8-pr-cvs1:/tmp/cvs-serv24374 Modified Files: ModelSet.py Log Message: Fixed typos Index: ModelSet.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/ModelSet.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** ModelSet.py 7 May 2003 11:22:07 -0000 1.6 --- ModelSet.py 7 May 2003 11:28:45 -0000 1.7 *************** *** 105,109 **** A sample configuration file is like:: ! [DEFAULTS] host: localhost --- 105,109 ---- A sample configuration file is like:: ! [DEFAULT] host: localhost *************** *** 150,154 **** try: options.remove('adaptor') except ValueError: pass ! for key in options: ##### TBD ++ section [Default] defaults[key]=cp.get(model.name(), key) model.setConnectionDictionary(defaults) --- 150,154 ---- try: options.remove('adaptor') except ValueError: pass ! for key in options: defaults[key]=cp.get(model.name(), key) model.setConnectionDictionary(defaults) |
From: <sbi...@us...> - 2003-05-07 11:27:13
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/tests In directory sc8-pr-cvs1:/tmp/cvs-serv22893 Modified Files: README test_EditingContext_Global.py test_EditingContext_Global_Inheritance.py test_EditingContext_ParentChild.py utils.py Added Files: Postgresql.cfg MySQL.cfg Removed Files: test.cfg Log Message: Updated the cfg. files for tests, now that ModelSet module got updateModelWithCFG() [RFE #726839]. File test.cfg is replaced by 2 files: Postgresql.cfg and MySQL.cfg --- NEW FILE: Postgresql.cfg --- # This file is used to initalize the model's connection dictionary and # adaptor's name when the tests are run for Postgresql # Change this to reflect your own configuration [DEFAULT] adaptor: Postgresql host: localhost user: postgres password: [AuthorBooks] [StoreEmployees] --- NEW FILE: MySQL.cfg --- # This file is used to initalize the model's connection dictionary and # adaptor's name when the tests are run for MySQL # Change this to reflect your own configuration [DEFAULT] adaptor: MySQL host: localhost user: root password: [AuthorBooks] [StoreEmployees] Index: README =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/tests/README,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** README 20 Feb 2003 15:19:28 -0000 1.7 --- README 7 May 2003 11:27:10 -0000 1.8 *************** *** 12,17 **** # Remaining tests require: # - that a PostgreSQL and/or MySQL database server is running somewhere ! # - you modify the file ./test.cfg to reflect you own PostgreSQL/MySQL ! # installation # - two different (***) databases (may be empty) with names: "AUTHOR_BOOKS" & # "STORE_EMPLOYEES" --- 12,17 ---- # Remaining tests require: # - that a PostgreSQL and/or MySQL database server is running somewhere ! # - you modify either ./Postgresql.cfg or MySQL.cfg to reflect you own ! # PostgreSQL/MySQL installation # - two different (***) databases (may be empty) with names: "AUTHOR_BOOKS" & # "STORE_EMPLOYEES" Index: test_EditingContext_Global.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/tests/test_EditingContext_Global.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** test_EditingContext_Global.py 27 Mar 2003 11:47:57 -0000 1.19 --- test_EditingContext_Global.py 7 May 2003 11:27:10 -0000 1.20 *************** *** 37,41 **** import unittest, sys import utils - from utils import parseConfigFile_and_updateModel if __name__ == "__main__": utils.fixpath() --- 37,40 ---- *************** *** 1017,1021 **** verbose=0 ! databaseAdaptorName='Postgresql' def main(args): --- 1016,1020 ---- verbose=0 ! database_cfg='Postgresql.cfg' def main(args): *************** *** 1024,1028 **** options, args = getopt.getopt(sys.argv[1:], 'vVprd:') #except: usage(me, 1) ! global verbose, databaseAdaptorName profile=0; reinitDB_flag=0 --- 1023,1027 ---- options, args = getopt.getopt(sys.argv[1:], 'vVprd:') #except: usage(me, 1) ! global verbose, database_cfg profile=0; reinitDB_flag=0 *************** *** 1034,1038 **** if k=='-d': if v not in ('Postgresql', 'MySQL'): usage(me, 1) ! databaseAdaptorName=v continue if k=='-r': reinitDB_flag=1; continue --- 1033,1037 ---- if k=='-d': if v not in ('Postgresql', 'MySQL'): usage(me, 1) ! database_cfg='%s.cfg'%v continue if k=='-r': reinitDB_flag=1; continue *************** *** 1041,1048 **** author_books_model=ModelSet.defaultModelSet().modelNamed('AuthorBooks') ! parseConfigFile_and_updateModel(author_books_model, databaseAdaptorName) # MySQL specifics: change TIMESTAMP to DATETIME ! if databaseAdaptorName=='MySQL': author_books_model.entityNamed('Writer').attributeNamed('birthday').setExternalType('DATETIME') --- 1040,1048 ---- author_books_model=ModelSet.defaultModelSet().modelNamed('AuthorBooks') ! # Initialization of model's caracs. ! ModelSet.updateModelWithCFG(author_books_model, database_cfg) # MySQL specifics: change TIMESTAMP to DATETIME ! if database_cfg=='MySQL.cfg': author_books_model.entityNamed('Writer').attributeNamed('birthday').setExternalType('DATETIME') Index: test_EditingContext_Global_Inheritance.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/tests/test_EditingContext_Global_Inheritance.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** test_EditingContext_Global_Inheritance.py 10 Feb 2003 22:04:19 -0000 1.8 --- test_EditingContext_Global_Inheritance.py 7 May 2003 11:27:10 -0000 1.9 *************** *** 37,41 **** import unittest, sys import utils - from utils import parseConfigFile_and_updateModel if __name__ == "__main__": utils.fixpath() --- 37,40 ---- *************** *** 396,400 **** verbose=0 ! databaseAdaptorName='Postgresql' def main(args): --- 395,399 ---- verbose=0 ! database_cfg='Postgresql.cfg' def main(args): *************** *** 403,407 **** options, args = getopt.getopt(sys.argv[1:], 'vVprd:') #except: usage(me, 1) ! global verbose, databaseAdaptorName profile=0; reinitDB_flag=0 for k, v in options: --- 402,406 ---- options, args = getopt.getopt(sys.argv[1:], 'vVprd:') #except: usage(me, 1) ! global verbose, database_cfg profile=0; reinitDB_flag=0 for k, v in options: *************** *** 412,416 **** if k=='-d': if v not in ('Postgresql', 'MySQL'): usage(me, 1) ! databaseAdaptorName=v continue if k=='-r': reinitDB_flag=1; continue --- 411,415 ---- if k=='-d': if v not in ('Postgresql', 'MySQL'): usage(me, 1) ! database_cfg='%s.cfg'%v continue if k=='-r': reinitDB_flag=1; continue *************** *** 418,422 **** # Initialization of model's caracs. ! parseConfigFile_and_updateModel(ModelSet.defaultModelSet().modelNamed('StoreEmployees'), databaseAdaptorName) if reinitDB_flag: reinitDB(); return --- 417,422 ---- # Initialization of model's caracs. ! model=ModelSet.defaultModelSet().modelNamed('StoreEmployees') ! ModelSet.updateModelWithCFG(model, database_cfg) if reinitDB_flag: reinitDB(); return Index: test_EditingContext_ParentChild.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/tests/test_EditingContext_ParentChild.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** test_EditingContext_ParentChild.py 14 Mar 2003 11:40:13 -0000 1.6 --- test_EditingContext_ParentChild.py 7 May 2003 11:27:10 -0000 1.7 *************** *** 15,19 **** import unittest, sys import utils - from utils import parseConfigFile_and_updateModel if __name__ == "__main__": utils.fixpath() --- 15,18 ---- *************** *** 509,513 **** verbose=0 ! databaseAdaptorName='Postgresql' def main(args): --- 508,512 ---- verbose=0 ! database_cfg='Postgresql.cfg' def main(args): *************** *** 516,520 **** options, args = getopt.getopt(sys.argv[1:], 'vVprd:') #except: usage(me, 1) ! global verbose, databaseAdaptorName profile=0; reinitDB_flag=0 --- 515,519 ---- options, args = getopt.getopt(sys.argv[1:], 'vVprd:') #except: usage(me, 1) ! global verbose, database_cfg profile=0; reinitDB_flag=0 *************** *** 526,530 **** if k=='-d': if v not in ('Postgresql', 'MySQL'): usage(me, 1) ! databaseAdaptorName=v continue if k=='-r': reinitDB_flag=1; continue --- 525,529 ---- if k=='-d': if v not in ('Postgresql', 'MySQL'): usage(me, 1) ! database_cfg='%s.cfg'%v continue if k=='-r': reinitDB_flag=1; continue *************** *** 533,541 **** author_books_model=ModelSet.defaultModelSet().modelNamed('AuthorBooks') ! parseConfigFile_and_updateModel(author_books_model, databaseAdaptorName) ! parseConfigFile_and_updateModel(ModelSet.defaultModelSet().modelNamed('StoreEmployees'), databaseAdaptorName) # MySQL specifics: change TIMESTAMP to DATETIME ! if databaseAdaptorName=='MySQL': author_books_model.entityNamed('Writer').attributeNamed('birthday').setExternalType('DATETIME') --- 532,542 ---- author_books_model=ModelSet.defaultModelSet().modelNamed('AuthorBooks') ! store_employee_model=ModelSet.defaultModelSet().modelNamed('StoreEmployees') ! # Initialization of model's caracs. ! ModelSet.updateModelWithCFG(author_books_model, database_cfg) ! ModelSet.updateModelWithCFG(store_employee_model, database_cfg) # MySQL specifics: change TIMESTAMP to DATETIME ! if database_cfg=='MySQL.cfg': author_books_model.entityNamed('Writer').attributeNamed('birthday').setExternalType('DATETIME') Index: utils.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/tests/utils.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** utils.py 10 Jan 2003 10:45:45 -0000 1.6 --- utils.py 7 May 2003 11:27:10 -0000 1.7 *************** *** 67,88 **** % (len(result.errors), len(result.failures))) return newerrs - - - def parseConfigFile_and_updateModel(model, dbAdaptorName): - """ - Parse 'test.cfg' and change the model's connection dictionary according to - the options the configuration file sets. - - This should only be triggered after the model has been loaded, e.g. after - one of the modules in the corresponding package has been loaded. - """ - from ConfigParser import ConfigParser - import os - defaults=model.connectionDictionary() - cp=ConfigParser() - cp.read('test.cfg') - for key in defaults.keys(): - if cp.has_option(dbAdaptorName, key): - defaults[key]=cp.get(dbAdaptorName, key) - model.setConnectionDictionary(defaults) - model.setAdaptorName(dbAdaptorName) --- 67,68 ---- --- test.cfg DELETED --- |
From: <sbi...@us...> - 2003-05-07 11:27:13
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/tests/testPackages/StoreEmployees In directory sc8-pr-cvs1:/tmp/cvs-serv22893/testPackages/StoreEmployees Modified Files: model_StoreEmployees.py model_StoreEmployees.xml Log Message: Updated the cfg. files for tests, now that ModelSet module got updateModelWithCFG() [RFE #726839]. File test.cfg is replaced by 2 files: Postgresql.cfg and MySQL.cfg Index: model_StoreEmployees.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/tests/testPackages/StoreEmployees/model_StoreEmployees.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** model_StoreEmployees.py 29 Aug 2002 11:14:27 -0000 1.4 --- model_StoreEmployees.py 7 May 2003 11:27:10 -0000 1.5 *************** *** 1,4 **** model_src="""<?xml version='1.0' encoding='iso-8859-1'?> ! <model name='StoreEmployees' packageName='StoreEmployees' adaptorName='Postgresql' connectionDictionary="{'database': 'STORE_EMPLOYEES', 'user': 'big', 'password': '', 'host': 'bidibule'}"> <entity isReadOnly='0' isAbstract='0' name='Store' parentEntity='' moduleName='Store' className='Store' typeName='' externalName='STORE'> <primaryKey attributeName='id'/> --- 1,4 ---- model_src="""<?xml version='1.0' encoding='iso-8859-1'?> ! <model name='StoreEmployees' packageName='StoreEmployees' adaptorName='' connectionDictionary="{'database': 'STORE_EMPLOYEES', 'user': '', 'password': '', 'host': ''}"> <entity isReadOnly='0' isAbstract='0' name='Store' parentEntity='' moduleName='Store' className='Store' typeName='' externalName='STORE'> <primaryKey attributeName='id'/> Index: model_StoreEmployees.xml =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/tests/testPackages/StoreEmployees/model_StoreEmployees.xml,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** model_StoreEmployees.xml 29 Aug 2002 11:14:29 -0000 1.4 --- model_StoreEmployees.xml 7 May 2003 11:27:11 -0000 1.5 *************** *** 1,4 **** <?xml version='1.0' encoding='iso-8859-1'?> ! <model name='StoreEmployees' packageName='StoreEmployees' adaptorName='Postgresql' connectionDictionary="{'database': 'STORE_EMPLOYEES', 'user': 'big', 'password': '', 'host': 'bidibule'}"> <entity isReadOnly='0' isAbstract='0' name='Store' parentEntity='' moduleName='Store' className='Store' typeName='' externalName='STORE'> <primaryKey attributeName='id'/> --- 1,4 ---- <?xml version='1.0' encoding='iso-8859-1'?> ! <model name='StoreEmployees' packageName='StoreEmployees' adaptorName='' connectionDictionary="{'database': 'STORE_EMPLOYEES', 'user': '', 'password': '', 'host': ''}"> <entity isReadOnly='0' isAbstract='0' name='Store' parentEntity='' moduleName='Store' className='Store' typeName='' externalName='STORE'> <primaryKey attributeName='id'/> |
From: <sbi...@us...> - 2003-05-07 11:27:13
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/tests/testPackages/AuthorBooks In directory sc8-pr-cvs1:/tmp/cvs-serv22893/testPackages/AuthorBooks Modified Files: model_AuthorBooks.xml Log Message: Updated the cfg. files for tests, now that ModelSet module got updateModelWithCFG() [RFE #726839]. File test.cfg is replaced by 2 files: Postgresql.cfg and MySQL.cfg Index: model_AuthorBooks.xml =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/tests/testPackages/AuthorBooks/model_AuthorBooks.xml,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** model_AuthorBooks.xml 27 Mar 2003 11:47:57 -0000 1.5 --- model_AuthorBooks.xml 7 May 2003 11:27:10 -0000 1.6 *************** *** 1,5 **** <?xml version='1.0' encoding='iso-8859-1'?> <!-- <!DOCTYPE model SYSTEM "mdl_model.dtd"> --> ! <model name='AuthorBooks' packageName='AuthorBooks' adaptorName='Postgresql' connectionDictionary="{'database': 'AUTHOR_BOOKS', 'user': 'postgres', 'password': '', 'host': 'localhost'}"> <entity isReadOnly='0' externalName='WRITER' name='Writer' parentEntity='' className='Writer' typeName='Writer' isAbstract='0'> <primaryKey attributeName='id'/> --- 1,5 ---- <?xml version='1.0' encoding='iso-8859-1'?> <!-- <!DOCTYPE model SYSTEM "mdl_model.dtd"> --> ! <model name='AuthorBooks' packageName='AuthorBooks' adaptorName='' connectionDictionary="{'database': 'AUTHOR_BOOKS', 'user': '', 'password': '', 'host': ''}"> <entity isReadOnly='0' externalName='WRITER' name='Writer' parentEntity='' className='Writer' typeName='Writer' isAbstract='0'> <primaryKey attributeName='id'/> |
From: <sbi...@us...> - 2003-05-07 11:22:10
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/doc/UserGuide In directory sc8-pr-cvs1:/tmp/cvs-serv22018/doc/UserGuide Modified Files: EnvironmentVariables.tex Log Message: RFE #726839: Added environment variable MDL_DB_CONNECTIONS_CFG; it points to a single ini-file which centralizes the sensitive informations contained in each model's database connection dictionary (username, password). See tests/Postgresql.cfg for an example. Index: EnvironmentVariables.tex =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/doc/UserGuide/EnvironmentVariables.tex,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** EnvironmentVariables.tex 10 Mar 2003 17:02:50 -0000 1.4 --- EnvironmentVariables.tex 7 May 2003 11:22:07 -0000 1.5 *************** *** 4,9 **** \begin{tableiii}{p{1cm}p{11cm}|p{3cm}}{code}{Name}{Description}{Possible values} ! \lineiii{MDL_ENABLE_DATABASE_LOGGING}{}{} \lineiii{}{DatabaseAdaptors for Postgresql and MySQL use a common logging mechanism, whose methods are located in module \module{Modeling.logging}. This --- 4,38 ---- \begin{tableiii}{p{1cm}p{11cm}|p{3cm}}{code}{Name}{Description}{Possible values} ! \lineiii{MDL_DB_CONNECTIONS}{}{} ! \lineiii{}{It happens that a model can be written in different places: ! in an xml file, in a python file, and even in a pickle when you use ! \code{mdl_compile_model.py}. The consequence is that the connection ! dictionary itself for each model, containing the user and its password, ! is written two or three times in the filesystems. For security and ! administrative reasons, one would prefer that this sensitive information ! should be written in a single place.\newline ! ~\newline ! This environment variable allows you to externalize the connection ! dictionaries of all your models in a single file; you'll typically ! remove the user and password from your models, and add these ! informations to a single file, say ! \file{/full/path/to/db_conn_dicts.cfg}, in a dedicated section for each ! model, like this:\newline ! \begin{center} ! \code{[aModelName]~~~~}\newline ! \code{user: a_username}\newline ! \code{password: passwd}\end{center} ! Then, simply assign to the env. variable \code{MDL_DB_CONNECTIONS_CFG} ! the full path to your \file{db_conn_dicts.cfg}, and your models' ! connection dictionaries will automatically be updated when they are ! loaded.\newline Last, every parameter normally assigned to a connection ! dictionary can be defined in this file, such as: \code{host}, ! \code{port}, etc. An extra field can be specified, \code{adaptor}, which ! overrides the adaptor's name in your model (example value: ! \code{Postgresql}, \code{MySQL}).\newline See also python documentation ! for \module{ConfigParser}.}{full path to an ini-file} ! \hline + \lineiii{MDL_ENABLE_DATABASE_LOGGING}{}{} \lineiii{}{DatabaseAdaptors for Postgresql and MySQL use a common logging mechanism, whose methods are located in module \module{Modeling.logging}. This *************** *** 12,16 **** --- 41,47 ---- the \code{sys.stderr}. To disable it, just unset this variable, or set it to the empty string.}{e.g. '1', 'YES' (plus the empty string for de-activation)} + \hline + \lineiii{MDL_PERMANENT_DB_CONNECTION}{}{} \lineiii{}{By default, the database connection is closed each time the last |
From: <sbi...@us...> - 2003-05-07 11:22:10
|
Update of /cvsroot/modeling/ProjectModeling/Modeling In directory sc8-pr-cvs1:/tmp/cvs-serv22018 Modified Files: CHANGES ModelSet.py Log Message: RFE #726839: Added environment variable MDL_DB_CONNECTIONS_CFG; it points to a single ini-file which centralizes the sensitive informations contained in each model's database connection dictionary (username, password). See tests/Postgresql.cfg for an example. Index: CHANGES =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/CHANGES,v retrieving revision 1.100 retrieving revision 1.101 diff -C2 -d -r1.100 -r1.101 *** CHANGES 6 May 2003 13:52:00 -0000 1.100 --- CHANGES 7 May 2003 11:22:06 -0000 1.101 *************** *** 8,11 **** --- 8,16 ---- -------------------------------------------------------- + * RFE #726839: Added environment variable MDL_DB_CONNECTIONS_CFG; it points + to a single ini-file which centralizes the sensitive informations + contained in each model's database connection dictionary (username, + password). See tests/Postgresql.cfg for an example. + 0.9-pre-7 (2003/05/06) --------- Index: ModelSet.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/ModelSet.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** ModelSet.py 28 Feb 2003 23:21:26 -0000 1.5 --- ModelSet.py 7 May 2003 11:22:07 -0000 1.6 *************** *** 56,60 **** import types ! from logging import error try: --- 56,60 ---- import types ! from logging import error, warn try: *************** *** 98,101 **** --- 98,161 ---- setDefaultModelGroup=setDefaultModelSet + def updateModelWithCFG(model, cfg_path): + """ + Updates the model's connection dictionary and adaptorName with the values + in file 'cfg_path'. + + A sample configuration file is like:: + + [DEFAULTS] + host: localhost + + [ModelName_1] + user: user_1 + password: pwd_1 + + [ModelName_2] + adaptor: MySQL + user: user_2 + password: pwd_2 + + The special field 'adaptor', if present, changes the adaptorName of the + model. + + Raises IOError if file 'cfg_path' cannot be found. + + See also: ModelSet.addModel() + + Parameters: + + model -- the model whose conn.dict. should be updated + + cfg_path -- the full path to the configuration file + + """ + from ConfigParser import ConfigParser + import os + defaults=model.connectionDictionary() + cp=ConfigParser() + try: + cp.readfp(open(cfg_path)) + except IOError: + import traceback, cStringIO, sys + exc_raised=sys.exc_info()[:2] + err_msg="Unable to open file '%s' pointed by env. variable MDL_DB_CONNECTIONS_CFG"%cfg_path + exc=cStringIO.StringIO() + traceback.print_exception(exc_raised[0], exc_raised[1], None, file=exc) + err_msg+="\nOriginal exception was: %s"%exc.getvalue() + raise IOError, err_msg + + try: options=cp.options(model.name()) + except: return + try: options.remove('adaptor') + except ValueError: pass + for key in options: ##### TBD ++ section [Default] + defaults[key]=cp.get(model.name(), key) + model.setConnectionDictionary(defaults) + try: + model.setAdaptorName(cp.get(model.name(), 'adaptor')) + except: + pass + class ModelSet(Persistent): """Holds a set of Modeling.Models that can co-exist at runtime *************** *** 114,118 **** def addModel(self, aModel): ! "..." #assert # Check model name --- 174,189 ---- def addModel(self, aModel): ! """ ! Add a model to the model set. In order to be successfully added the model ! should not have the same name than one of the models already added to the ! ModelSet, nor should it hold an entity whose name is already used within ! the ModelSet. ! ! Raises ModelError if the insertion of aModel fails. ! ! If the environment variable 'MDL_DB_CONNECTIONS_CFG' is set, the file ! it points to is used to update aModel's connection dictionary (and ! possibly its adaptorName as well). See updateModelWithCFG() for details. ! """ #assert # Check model name *************** *** 129,132 **** --- 200,209 ---- aModel._setModelSet(self) + # MDL_DB_CONNECTIONS_CFG + import os + cfg_path=os.environ.get('MDL_DB_CONNECTIONS_CFG') + if cfg_path: + updateModelWithCFG(aModel, cfg_path) + # XML Import/Export facilities def addModelFromXML(self, xmlSource): |
From: <sbi...@us...> - 2003-05-06 16:29:52
|
Update of /cvsroot/modeling/ZModeling In directory sc8-pr-cvs1:/tmp/cvs-serv27997 Modified Files: CHANGES INSTALL README Log Message: Updated & added informations about the products (README,INSTALL) Index: CHANGES =================================================================== RCS file: /cvsroot/modeling/ZModeling/CHANGES,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** CHANGES 22 Apr 2003 09:35:16 -0000 1.16 --- CHANGES 6 May 2003 16:29:48 -0000 1.17 *************** *** 1,5 **** -*- text -*- ! Current release is: 0.9-pre-6 * Updated ZModelizationTool: a field 'comment' was added for Model, Entity, --- 1,10 ---- -*- text -*- ! Current release is: 0.9-pre-7 ! ! 0.9-pre-7 (2003/05/06) ! --------- ! ! * mdl_validate_model.py: added '-Q' + slightly change the usage (see --help) * Updated ZModelizationTool: a field 'comment' was added for Model, Entity, Index: INSTALL =================================================================== RCS file: /cvsroot/modeling/ZModeling/INSTALL,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** INSTALL 30 Jul 2002 15:34:59 -0000 1.1.1.1 --- INSTALL 6 May 2003 16:29:48 -0000 1.2 *************** *** 1,2 **** ZModelizationTool: ! drop it into a Zope's Products/ directory, then create an instance --- 1,3 ---- ZModelizationTool: ! drop it into a Zope's Products/ directory, then create an instance in the ! Zope Management Interface (ZMI). Index: README =================================================================== RCS file: /cvsroot/modeling/ZModeling/README,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** README 30 Jul 2002 15:34:59 -0000 1.1.1.1 --- README 6 May 2003 16:29:48 -0000 1.2 *************** *** 1 **** ! For dependencies and general informations, see ProjectModeling/ --- 1,30 ---- ! This directory contains Zope products based on the Modeling framework: ! ! ZModelizationTool: ! ------------------ ! The ZModelization is a tool to help you design a model. ! ! It lets you create and edit the model through a web interface, that is ! to say that every single element being part of the xml-model can be ! modified through easy-to-use web forms. It has some niceties, such as ! the possibility to create a relationship and its inverse along with ! the foreign key if needed in a single operation, or the ability to ! create in a single click a sub-entity having all of its parent's ! attributes and relationships. ! ! Last, you may validate the model, generate the database schemas and ! the python code for your model, just by a few mouse clicks. ! ! ZEditingContextSessioning: ! -------------------------- ! ! Adds a new method to Zope session objects: defaultEditingContext(), which ! delivers a specific EditingContext in each session. ! ! ! The two other products, ZModelManager and ZClassDescriptionManager are for ! debugging purposes only and should probably not be used unless you're ! debugging the framework itself. Note that it is possible that they are ! out-of-sync with the current version of the framework. ! ! For dependencies and general informations, see the Modeling framework. |
From: <sbi...@us...> - 2003-05-06 16:29:52
|
Update of /cvsroot/modeling/ZModeling/ZEditingContextSessioning In directory sc8-pr-cvs1:/tmp/cvs-serv27997/ZEditingContextSessioning Modified Files: README.txt Log Message: Updated & added informations about the products (README,INSTALL) Index: README.txt =================================================================== RCS file: /cvsroot/modeling/ZModeling/ZEditingContextSessioning/README.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** README.txt 9 Mar 2003 20:46:39 -0000 1.1 --- README.txt 6 May 2003 16:29:48 -0000 1.2 *************** *** 8,9 **** --- 8,21 ---- there can be some time between the moment where the session expires and the actual unregistration/destruction of its EC. + + Installation + ------------ + + Simply drop ZEditingContextSessioning/ into a Zope's Products/ directory and + restart zope. + + Documentation + ------------- + + The current documentation can be found in the User's Guide at: + http://modeling.sourceforge.net/UserGuide/framework-integration-hints.html |
From: <sbi...@us...> - 2003-05-06 16:29:52
|
Update of /cvsroot/modeling/ZModeling/ZModelizationTool In directory sc8-pr-cvs1:/tmp/cvs-serv27997/ZModelizationTool Added Files: INSTALL README Log Message: Updated & added informations about the products (README,INSTALL) --- NEW FILE: INSTALL --- ZModelizationTool: drop this directory into a Zope's Products/ directory, then create an instance in the Zope Management Interface (ZMI). --- NEW FILE: README --- The ZModelization is a tool to help you design a model. It lets you create and edit the model through a web interface, that is to say that every single element being part of the xml-model can be modified through easy-to-use web forms. It has some niceties, such as the possibility to create a relationship and its inverse along with the foreign key if needed in a single operation, or the ability to create in a single click a sub-entity having all of its parent's attributes and relationships. Last, you may validate the model, generate the database schemas and the python code for your model, just by a few mouse clicks. Documentation ------------- The current documentation can be found in the User's Guide: http://modeling.sourceforge.net/UserGuide/define-model.html |
From: <sbi...@us...> - 2003-05-06 13:52:06
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/doc/HomePage In directory sc8-pr-cvs1:/tmp/cvs-serv11584/Modeling/doc/HomePage Modified Files: documentation.tex downloads.tex main.tex Log Message: Release 0.9-pre-7 Index: documentation.tex =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/doc/HomePage/documentation.tex,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** documentation.tex 23 Feb 2003 14:38:54 -0000 1.3 --- documentation.tex 6 May 2003 13:52:01 -0000 1.4 *************** *** 37,40 **** --- 37,42 ---- \end{enumerate} + + %% end \input{www/menu-inline-end} \end{document} Index: downloads.tex =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/doc/HomePage/downloads.tex,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** downloads.tex 14 Mar 2003 09:42:57 -0000 1.7 --- downloads.tex 6 May 2003 13:52:01 -0000 1.8 *************** *** 10,14 **** \begin{enumerate} ! \item[\bf Current version: 0.9-pre-4 (Second release candidate for 0.9)] Download it here:\begin{rawhtml}<a --- 10,14 ---- \begin{enumerate} ! \item[\bf Current version: 0.9-pre-7] Download it here:\begin{rawhtml}<a Index: main.tex =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/doc/HomePage/main.tex,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** main.tex 14 Mar 2003 09:42:57 -0000 1.12 --- main.tex 6 May 2003 13:52:01 -0000 1.13 *************** *** 7,11 **** % Increment the release number whenever significant changes are made. % The author and/or editor can define 'significant' however they like. ! %\release{0.9-pre-4} % At minimum, give your name and an email address. You can include a --- 7,11 ---- % Increment the release number whenever significant changes are made. % The author and/or editor can define 'significant' however they like. ! %\release{0.9-pre-7} % At minimum, give your name and an email address. You can include a *************** *** 13,17 **** \author{S\'ebastien Bigaret} \email{sbi...@us...} ! \date{March 14, 2003} %\date{\today} --- 13,17 ---- \author{S\'ebastien Bigaret} \email{sbi...@us...} ! \date{May 06, 2003} %\date{\today} |
From: <sbi...@us...> - 2003-05-06 13:52:05
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/doc In directory sc8-pr-cvs1:/tmp/cvs-serv11584/Modeling/doc Modified Files: UserGuide.tex Log Message: Release 0.9-pre-7 Index: UserGuide.tex =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/doc/UserGuide.tex,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** UserGuide.tex 14 Mar 2003 09:42:57 -0000 1.18 --- UserGuide.tex 6 May 2003 13:52:01 -0000 1.19 *************** *** 12,19 **** % the rest is at your discretion. \authoraddress{Email: \email{sbi...@us...}} ! \date{March 14, 2003} %\date{\today} ! \release{0.9-pre-4} ! %\setreleaseinfo{pre-4} \setshortversion{0.9} --- 12,19 ---- % the rest is at your discretion. \authoraddress{Email: \email{sbi...@us...}} ! \date{May 06, 2003} %\date{\today} ! \release{0.9-pre-7} ! %\setreleaseinfo{pre-7} \setshortversion{0.9} |
From: <sbi...@us...> - 2003-05-06 13:52:05
|
Update of /cvsroot/modeling/ProjectModeling/Modeling In directory sc8-pr-cvs1:/tmp/cvs-serv11584/Modeling Modified Files: CHANGES TODO Log Message: Release 0.9-pre-7 Index: CHANGES =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/CHANGES,v retrieving revision 1.99 retrieving revision 1.100 diff -C2 -d -r1.99 -r1.100 *** CHANGES 6 May 2003 12:20:31 -0000 1.99 --- CHANGES 6 May 2003 13:52:00 -0000 1.100 *************** *** 3,11 **** Module Modeling --------------- ! Current release is: 0.9-pre-6 / See also: TODO, INSTALL and doc/ * ** Distributed under the GNU General Public License ** -------------------------------------------------------- * Fixed DatabaseChannel.fetchObject(): it was not MT-safe wrt Database snapshots' caching in some circumstances (see comments in the code for --- 3,14 ---- Module Modeling --------------- ! Current release is: 0.9-pre-7 / See also: TODO, INSTALL and doc/ * ** Distributed under the GNU General Public License ** -------------------------------------------------------- + 0.9-pre-7 (2003/05/06) + --------- + * Fixed DatabaseChannel.fetchObject(): it was not MT-safe wrt Database snapshots' caching in some circumstances (see comments in the code for *************** *** 28,32 **** 0.9-pre-6 (2003/04/22) Project milestone -- no public release ! --------- Preparing 0.9 - ETA: 2003/04/28 * ModelMasons: added a new generation scheme. The existing one is named --- 31,35 ---- 0.9-pre-6 (2003/04/22) Project milestone -- no public release ! --------- * ModelMasons: added a new generation scheme. The existing one is named Index: TODO =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/TODO,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** TODO 17 Mar 2003 11:19:14 -0000 1.9 --- TODO 6 May 2003 13:52:00 -0000 1.10 *************** *** 296,297 **** --- 296,304 ---- seperate module. + * KeyValueCoding: + + - takeValuesFromDictionary unused in the framework -> should be used in + DatabaseContext.initializeObject() + + - voir aussi autre chose (??) entre KVC et (Entity)ClassDescription + \ No newline at end of file |
From: <sbi...@us...> - 2003-05-06 13:52:05
|
Update of /cvsroot/modeling/ProjectModeling In directory sc8-pr-cvs1:/tmp/cvs-serv11584 Modified Files: setup.py Log Message: Release 0.9-pre-7 Index: setup.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/setup.py,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** setup.py 25 Apr 2003 18:13:32 -0000 1.23 --- setup.py 6 May 2003 13:52:00 -0000 1.24 *************** *** 46,50 **** setup(name="ModelingCore", ! version="0.9-pre-6", licence ="GNU General Public License", description=short_description, --- 46,50 ---- setup(name="ModelingCore", ! version="0.9-pre-7", licence ="GNU General Public License", description=short_description, |