You can subscribe to this list here.
2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(57) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2003 |
Jan
(44) |
Feb
(151) |
Mar
(131) |
Apr
(171) |
May
(125) |
Jun
(43) |
Jul
(26) |
Aug
(19) |
Sep
(10) |
Oct
|
Nov
(4) |
Dec
(28) |
2004 |
Jan
(134) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <de...@us...> - 2003-12-18 00:29:38
|
Update of /cvsroot/pymerase/pymerase/examples In directory sc8-pr-cvs1:/tmp/cvs-serv24272 Added Files: .cvsignore Log Message: ignore uninteresting files --- NEW FILE: .cvsignore --- *.pyc *.class |
From: <de...@us...> - 2003-12-18 00:28:52
|
Update of /cvsroot/pymerase/pymerase/examples/school/school In directory sc8-pr-cvs1:/tmp/cvs-serv24148/school Log Message: Directory /cvsroot/pymerase/pymerase/examples/school/school added to the repository |
From: <de...@us...> - 2003-12-18 00:26:05
|
Update of /cvsroot/pymerase/pymerase/examples/school In directory sc8-pr-cvs1:/tmp/cvs-serv23741 Added Files: .cvsignore Log Message: ignore uninteresting files --- NEW FILE: .cvsignore --- *.pyc *.class *.xmi *.sql psql.log |
From: <de...@us...> - 2003-12-18 00:22:51
|
Update of /cvsroot/pymerase/pymerase/examples/ncbi In directory sc8-pr-cvs1:/tmp/cvs-serv23231 Added Files: .cvsignore Log Message: Tell cvs not to pay attention to uninteresting files --- NEW FILE: .cvsignore --- *.pyc *.class *.xmi |
From: <de...@us...> - 2003-12-18 00:21:32
|
Update of /cvsroot/pymerase/pymerase/examples/xmimof In directory sc8-pr-cvs1:/tmp/cvs-serv23096 Added Files: README createapi.py mof-1.4.xmi Log Message: add skeleton of an experiment for pymerase generating its own version of the MOF --- NEW FILE: README --- Can pymerase generate code for UML 1.4? --- NEW FILE: createapi.py --- #!/usr/bin/env python import sys import os import pymerase # NOTE: Jython can't use the python way to load modules based on their name # NOTE: so we have to manually import the modules we're using # NOTE: and pass them to pymerase.run import pymerase.input.parseXMI import pymerase.output.CreateDBAPI if __name__ == "__main__": schema = os.path.abspath("./mof-1.4.xmi") outputPath = os.path.abspath("./mof") #pymerase.run(schema, 'parseXMI', output, 'CreateDBAPI') pymerase.run(schema, pymerase.input.parseXMI, outputPath, pymerase.output.CreateDBAPI) --- NEW FILE: mof-1.4.xmi --- <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE XMI SYSTEM "Model.dtd"> <XMI xmlns:Model="org.omg.mof.Model" verified="false" xmi.version="1.1"> <XMI.header> <XMI.documentation> <XMI.contact> Questions and discussion: mo...@om...; Raising issues: http://www.omg.org/library/issuerpt.html The OMG specification on which this is based: http://www.omg.org/cgi-bin/doc?ad/2001-07-17 The official/latest version of this file: omg.org/models/MOF1.4/XMI1.1/Model1.4/Model.xml </XMI.contact> <XMI.exporter>ModelXMIProducer (switches -C -E)</XMI.exporter> <XMI.exporterVersion> Generated by dMOF 1.1 'mof_1_3_transition' (switches -g 1dot4) </XMI.exporterVersion> <XMI.longDescription> The MOF provides a set of modeling elements, including rules for [...2410 lines suppressed...] <Model:Classifier xmi.idref="a118"/> </Model:TypedElement.type> </Model:AssociationEnd> <Model:AssociationEnd aggregation="none" annotation="" isChangeable="true" isNavigable="true" name="typedElements" xmi.id="a289"> <Model:AssociationEnd.multiplicity> <XMI.field>0</XMI.field> <XMI.field>-1</XMI.field> <XMI.field>false</XMI.field> <XMI.field>true</XMI.field> </Model:AssociationEnd.multiplicity> <Model:TypedElement.type> <Model:Classifier xmi.idref="a113"/> </Model:TypedElement.type> </Model:AssociationEnd> </Model:Namespace.contents> </Model:Association> </Model:Namespace.contents> </Model:Package> </XMI.content> </XMI> |
From: <de...@us...> - 2003-12-18 00:20:20
|
Update of /cvsroot/pymerase/pymerase/examples/xmimof In directory sc8-pr-cvs1:/tmp/cvs-serv22823/xmimof Log Message: Directory /cvsroot/pymerase/pymerase/examples/xmimof added to the repository |
From: <de...@us...> - 2003-12-18 00:15:00
|
Update of /cvsroot/pymerase/pymerase/tests In directory sc8-pr-cvs1:/tmp/cvs-serv21411 Modified Files: .cvsignore Log Message: ignore debug logfile Index: .cvsignore =================================================================== RCS file: /cvsroot/pymerase/pymerase/tests/.cvsignore,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** .cvsignore 4 Aug 2003 18:42:20 -0000 1.1 --- .cvsignore 18 Dec 2003 00:14:57 -0000 1.2 *************** *** 1,2 **** --- 1,3 ---- *.pyc *.class + psql.log |
From: <de...@us...> - 2003-12-18 00:12:42
|
Update of /cvsroot/pymerase/pymerase/examples/school In directory sc8-pr-cvs1:/tmp/cvs-serv20835 Modified Files: school.smw Log Message: Updated school.smw (probably to keep current with new xmi schema) Index: school.smw =================================================================== RCS file: /cvsroot/pymerase/pymerase/examples/school/school.smw,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** school.smw 12 May 2003 23:19:47 -0000 1.1 --- school.smw 18 Dec 2003 00:12:39 -0000 1.2 *************** *** 380,384 **** aa(lp111 F290 ! aF120.5 aasg39 NsS'connector' --- 380,384 ---- aa(lp111 F290 ! aF142.59999999999999 aasg39 [...13435 lines suppressed...] g47 --- 9882,9886 ---- I0 I0 ! tp1798 sg15 g47 *************** *** 9218,9222 **** g1 sg17 ! (lp1692 g118 asbsb. --- 9888,9892 ---- g1 sg17 ! (lp1799 g118 asbsb. |
From: <de...@us...> - 2003-12-18 00:11:31
|
Update of /cvsroot/pymerase/pymerase/tests In directory sc8-pr-cvs1:/tmp/cvs-serv20692 Modified Files: TestSchool.py Log Message: Added test for bug 788408, not being able to test on the same object twice Index: TestSchool.py =================================================================== RCS file: /cvsroot/pymerase/pymerase/tests/TestSchool.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** TestSchool.py 23 Jul 2003 01:54:35 -0000 1.10 --- TestSchool.py 18 Dec 2003 00:11:28 -0000 1.11 *************** *** 316,320 **** finally: s.close() ! def testReadObject(self): import school --- 316,321 ---- finally: s.close() ! ! def testReadObject(self): import school *************** *** 550,553 **** --- 551,580 ---- finally: s.close() + + + def testDoubleCommit(self): + """Test committing one the same object twice + + Tests Bug 788408 + """ + import school + school.moduleReload() + s = school.DBSession(host, database) + + givenNameQuery = "%s = 'Erin'" % ( givenNameFieldName ) + erin_list = s.getObjectsWhere(s.Students, givenNameQuery) + self.failUnless(len(erin_list) == 1, "%d erins" % (len(erin_list))) + erin = erin_list[0] + uid = erin.getUid() + + erin.setUid('test') + erin.commit() + erin.setUid(uid) + erin.commit() + + erin_list = s.getObjectsWhere(s.Students, givenNameQuery) + self.failUnless(len(erin_list) == 1, "%d erins" % (len(erin_list))) + erin_loaded = erin_list[0] + self.failUnless(erin_loaded.getUid() == uid, "Couldn't commit twice") *************** *** 559,567 **** # CreateSchoolTestCases("testCreate_underscore_API"), # CreateSchoolTestCases("testCreateCapsAPI"), ! CreateSchoolTestCases("testPoseidon141CreateUML_underscore_API"), CreateSchoolTestCases("testPoseidon161CreateUML_underscore_API"), # bizarre, if SMW attempts to parse this first # it causes the XMI readers to fail ! CreateSchoolTestCases("testSMWCreateUML_underscore_API"), ] for api in api_tests: --- 586,594 ---- # CreateSchoolTestCases("testCreate_underscore_API"), # CreateSchoolTestCases("testCreateCapsAPI"), ! # CreateSchoolTestCases("testPoseidon141CreateUML_underscore_API"), CreateSchoolTestCases("testPoseidon161CreateUML_underscore_API"), # bizarre, if SMW attempts to parse this first # it causes the XMI readers to fail ! # CreateSchoolTestCases("testSMWCreateUML_underscore_API"), ] for api in api_tests: *************** *** 579,582 **** --- 606,610 ---- suite.addTest(CreateSchoolTestCases("testTreeInsert")) suite.addTest(CreateSchoolTestCases("testTreeRetrieval")) + suite.addTest(CreateSchoolTestCases("testDoubleCommit")) return suite |
From: <ki...@us...> - 2003-12-05 01:08:28
|
Update of /cvsroot/pymerase/pymerase/pymerase/output/dbAPI In directory sc8-pr-cvs1:/tmp/cvs-serv31302 Modified Files: dbAPI.pyt Log Message: Added safeDelete function to DBClass Index: dbAPI.pyt =================================================================== RCS file: /cvsroot/pymerase/pymerase/pymerase/output/dbAPI/dbAPI.pyt,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** dbAPI.pyt 11 Nov 2003 02:05:27 -0000 1.1 --- dbAPI.pyt 5 Dec 2003 01:08:24 -0000 1.2 *************** *** 674,677 **** --- 674,689 ---- self.loadSelf(self.id()) + def safeDelete(self): + """Only deletes the object if it has no associations with other objects + """ + for key in self.associations.keys(): + assoc = self.associations[key] + objList = assoc.getObjects() + if len(objList) > 0: + msg = 'CANNOT DELETE %s SAFELY, ABORTING DELETETION' % (self.getTableName()) + raise ValueError, msg + + self.delete() + def delete(self): """Delete the current object from the database. |
From: <ki...@us...> - 2003-12-04 03:16:06
|
Update of /cvsroot/pymerase/pymerase/pymerase/output/dbAPI In directory sc8-pr-cvs1:/tmp/cvs-serv3589 Modified Files: init.pyt Log Message: Added getObjectCount and getObjectCountWhere functions to DBSession class. Index: init.pyt =================================================================== RCS file: /cvsroot/pymerase/pymerase/pymerase/output/dbAPI/init.pyt,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** init.pyt 11 Nov 2003 02:05:27 -0000 1.1 --- init.pyt 4 Dec 2003 03:16:03 -0000 1.2 *************** *** 185,188 **** --- 185,234 ---- sql = "SELECT * FROM \"%s\" where %s" % (class_ref.table_name, where_clause) return self.loadRecords(class_ref, sql) + + def getObjectCount(self, class_functor): + """ + Returns the number of objects which exist for a given class + """ + class_ref = self.__getClassRef(class_functor) + + sql = "SELECT count(*) FROM \"%s\"" % (class_ref.table_name) + + try: + cursor = self.db.cursor() + try: + cursor.execute(sql) + record = cursor.fetchone() + finally: + cursor.close() + except Exception, e: + # pgdb isn't too informative about exception + sys.stderr.write(str(e)) + sys.stderr.write(os.linesep) + + return record.pop() + + def getObjectCountWhere(self, class_functor, where_clause): + """ + Returns the number of objects which exist for a given class, + given a where clause. + """ + class_ref = self.__getClassRef(class_functor) + + sql = "SELECT count(*) FROM \"%s\" where %s" % (class_ref.table_name, + where_clause) + + try: + cursor = self.db.cursor() + try: + cursor.execute(sql) + record = cursor.fetchone() + finally: + cursor.close() + except Exception, e: + # pgdb isn't too informative about exception + sys.stderr.write(str(e)) + sys.stderr.write(os.linesep) + + return record.pop() def loadRecords(self, class_ref, sql): |
From: <ki...@us...> - 2003-12-04 02:52:44
|
Update of /cvsroot/pymerase/pymerase/pymerase/output In directory sc8-pr-cvs1:/tmp/cvs-serv438 Modified Files: CreateDBAPI.py Log Message: 3 files changed names from .py to .pyt. Fixed hard coded paths. Index: CreateDBAPI.py =================================================================== RCS file: /cvsroot/pymerase/pymerase/pymerase/output/CreateDBAPI.py,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -d -r1.31 -r1.32 *** CreateDBAPI.py 10 Sep 2003 02:09:01 -0000 1.31 --- CreateDBAPI.py 4 Dec 2003 02:52:41 -0000 1.32 *************** *** 458,465 **** # get module_path # FIXME: this is for the better segmented version ! files_to_copy = [('dbAPI.py', 'dbAPI.py'), ! ('init.py', '__init__.py'), ('../../util/bool.py', 'bool.py'), ! ('fkeyTypes.py', 'fkeyTypes.py')] # files_to_copy = [('dbAPI.py', '__init__.py'), # ('fkeyTypes.py', 'fkeyTypes.py')] --- 458,465 ---- # get module_path # FIXME: this is for the better segmented version ! files_to_copy = [('dbAPI.pyt', 'dbAPI.py'), ! ('init.pyt', '__init__.py'), ('../../util/bool.py', 'bool.py'), ! ('fkeyTypes.pyt', 'fkeyTypes.py')] # files_to_copy = [('dbAPI.py', '__init__.py'), # ('fkeyTypes.py', 'fkeyTypes.py')] |
From: <de...@us...> - 2003-11-11 08:05:21
|
Update of /cvsroot/pymerase/pymerase/pymerase/util In directory sc8-pr-cvs1:/tmp/cvs-serv32122 Added Files: Template.py Log Message: Add new templating system. Uses Template base class to define a pseduo-dictionary for python % subsitution --- NEW FILE: Template.py --- import string import types from Functor import Functor class Template(object): """Base class for defining python templating objects. Derive from this base class and add functions to define the various keyword substituions you'd like to provide. """ def __init__(self, namespace=None): """Constructor namespace -- Provide a namespace to resolve variables in, defaults to class """ if namespace is None: namespace = self.__dict__ self.namespace = {} self.namespace.update(namespace) functionNameList = self.keys() for functionName in functionNameList: function = self.__class__.__dict__[functionName] self.namespace[functionName] = Functor(function, self) def keys(self): """Return list of template functions """ utilityFunctions = Template.__dict__.keys() allFunctions = self.__class__.__dict__.keys() templateFunctions = [] for f in allFunctions: if f not in utilityFunctions: templateFunctions.append(f) return templateFunctions def __getitem__(self, key): """Resolve dictionary lookup as function call, including parameter lookup """ if type(key) not in types.StringTypes: raise RuntimeError("Template expression must be a string") elif len(key) == 0: raise RuntimeError("Template expression must not be the empty string") return eval(key, self.namespace) |
From: <de...@us...> - 2003-11-11 08:03:45
|
Update of /cvsroot/pymerase/pymerase/pymerase/util In directory sc8-pr-cvs1:/tmp/cvs-serv31771 Added Files: Functor.py Log Message: Start refactoring Functor class out of dbAPI/init.pyt --- NEW FILE: Functor.py --- class Functor: def __init__(self, function, *args, **kargs): assert callable(function), "function should be a callable obj" self._function = function self._args = args self._kargs = kargs def __call__(self, *args, **kargs): """call function""" _args = list(self._args) _args.extend(args) _kargs = self._kargs.copy() _kargs.update(kargs) return apply(self._function,_args,_kargs) |
From: <de...@us...> - 2003-11-11 08:02:44
|
Update of /cvsroot/pymerase/pymerase/tests/pymerase/util In directory sc8-pr-cvs1:/tmp/cvs-serv31644/util Added Files: TestTemplate.py Log Message: Test Template engine base class --- NEW FILE: TestTemplate.py --- #!/usr/bin/env python import string import re import unittest from pymerase.util.Template import Template class TestTemplate(Template): def __init__(self, namespace=None): # define modules we want access to self.string = string self.re = re self.testParameter = "class" self.listParameter = ['hello','earth'] # call after we set up our namespace super(TestTemplate, self).__init__(namespace) def simple(self): return "simple" def parameter(self, x): return "%s" % (x) testParameter = "global" class TemplateTestCases(unittest.TestCase): def testKeys(self): tt = TestTemplate() keys = tt.keys() self.failUnless(len(keys) == 2) self.failUnless('simple' in keys) self.failUnless('parameter' in keys) def testSimple(self): tt = TestTemplate() result = "%(simple())s" % (tt) self.failUnless(result == "simple") def testParameterGlobal(self): tt = TestTemplate(globals()) result = "%(parameter(testParameter))s" % (tt) self.failUnless(result == "global", result) def testParameterClass(self): tt = TestTemplate() result = "%(parameter(testParameter))s" % (tt) self.failUnless(result == "class") def testParameterOther(self): d = {'testParameter': 'local'} tt = TestTemplate(d) result = "%(parameter(testParameter))s" % (tt) self.failUnless(result == "local") def testExpression(self): """Test expression using manually constructed namespace """ import string d = {'l': ['hello', 'world'], 'string': string} tt = TestTemplate(d) result = "%(string.join(map(parameter,l)))s" % (tt) self.failUnless(result == "hello world", "result was %s" % (result)) def testExpressionClass(self): """Test expression using namespace inherited from the Template class """ tt = TestTemplate() result = "%(string.join(map(parameter,listParameter)))s" % (tt) self.failUnless(result == "hello earth", "result was %s" % (result)) def suite(): return unittest.defaultTestLoader.loadTestsFromTestCase(TemplateTestCases) if __name__ == "__main__": unittest.main(defaultTest="suite") |
Update of /cvsroot/pymerase/pymerase/pymerase/output/dbAPI In directory sc8-pr-cvs1:/tmp/cvs-serv9769 Added Files: dbAPI.pyt fkeyTypes.pyt init.pyt Removed Files: dbAPI.py fkeyTypes.py init.py Log Message: renamed template files to make compileall.py script happier. --- NEW FILE: dbAPI.pyt --- ########################################################################### # # # C O P Y R I G H T N O T I C E # # Copyright (c) 2001 by: # # * California Institute of Technology # # # # All Rights Reserved. # # # # Permission is hereby granted, free of charge, to any person # # obtaining a copy of this software and associated documentation files # # (the "Software"), to deal in the Software without restriction, # # including without limitation the rights to use, copy, modify, merge, # # publish, distribute, sublicense, and/or sell copies of the Software, # # and to permit persons to whom the Software is furnished to do so, # # subject to the following conditions: # # # # The above copyright notice and this permission notice shall be # # included in all copies or substantial portions of the Software. # # # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS # # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN # # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # # SOFTWARE. # ########################################################################### # # Authors: Diane Trout # Last Modified: $Date: 2003/11/11 02:05:27 $ # from __future__ import nested_scopes import imp import os import pprint import re import string import sys import types import traceback import fkeyTypes from bool import Bool from mx import DateTime from mx.DateTime.Parser import DateTimeFromString import warnings from warnings import warn class DebugWarning(Warning): pass warnings.filterwarnings('ignore', category=DebugWarning, append=1) def sqlEscapeString(s): """Given a string escape any double quote marks \" """ if type(s) == types.StringType or type(s) == types.UnicodeType: s = re.sub('"', '\\\"', s) s = re.sub("'", "\\\'", s) return s else: return s class Field: """Stores information about database fields. Including name, type, null, and a cached copy of the value. """ def __init__(self, name, type=None, friendlyName=None): self.name = name self.friendlyName = friendlyName self.type = type self.null_allowed = 1 self.modified = 0 self.value = None self.loaded_value = None def setValue(self, value, loading = 0): """ Sets the value of the field after checking to make sure the types are compatible. """ # FIXME: type checking needs work # FIXME: if self.type isn't none we can type check # FIXME: if value is none, # FIXME: can we be null? # FIXME: if yes: skip remainder of type checking # FIXME: if no: throw error # FIXME: does values type match our # FIXME: if self.type is not None: # check for null if value is None: if not self.null_allowed: error_msg = "Field %s must not be null" % ( self.name ) raise ValueError(error_msg) # try to typecast datetime types elif self.type == DateTime.DateTimeType and (type(value) == types.StringType or type(value) == types.UnicodeType): value = DateTimeFromString(value) # FIXME: postgresql returns bigints for sequences # FIXME: which breaks this type checking code # FIXME: I'm not sure this coercion is a good idea since # FIXME: it might cause size problems elif self.type == types.IntType and type(value) == types.LongType: pass # FIXME: the following code fragment was added 'cause it # FIXME: it seems that you can't add subclassed objects to # FIXME: things expecting their base classes. # FIXME: also changed advisor link from faculty to employee to try # FIXME: and create some inheritance. #elif self.type == types.ClassType and issubclass(value, self.type): # pass elif type(self.type) == types.ClassType: # NOTE: if the class can't parse the passed in value it should # NOTE: throw the value error value = self.type(value) elif self.type != type(value): error_msg = "Incompatible type for field %s, expecting %s, got %s" error_msg = error_msg % (self.name, str(self.type), str(type(value))) raise ValueError(error_msg) # NOTE: this allows a class to be listed as a type if not loading: warn("modified %s to %s" % (self.name , str(value)), DebugWarning) self.modified = 1 self.value = value def isModified(self): if self.modified: return 1 else: return 0 def isNotNull(self): return not self.null_allowed def __str__(self): return pprint.pformat(self.__dict__) class DBAssociation: def __init__(self, thisObject, otherEndModule, otherEndHasFKey, otherEndMultiplicity): self.thisObject = thisObject self.otherEndMultiplicity = otherEndMultiplicity self.otherEndHasForeignKey = otherEndHasFKey self.otherEndModule = otherEndModule # FIXME: This probably needs to be converted to a weak reference self.loaded_objects = None self.appended_objects = [] def __len__(self): count = 0 if self.loaded_objects is not None: count += len(self.loaded_objects) count += len(self.appended_objects) return count def __loadObjects(self): sql = "SELECT * FROM \"%s\" WHERE \"%s\" = %s" if self.isLocalAssociation(): m = '1' keyName = self.otherEndModule.getPrimaryKeyName() keyValue = self.thisObject.fields[self.otherEndModule.getForeignKeyName()].value else: m = '*' keyName = self.thisObject.getForeignKeyName() keyValue = self.thisObject.fields[self.thisObject.getPrimaryKeyName()].value tableName = sqlEscapeString(self.otherEndModule.getTableName()) keyName = sqlEscapeString(keyName) keyValue = sqlEscapeString(keyValue) sql %= (tableName, keyName, keyValue) warn("__loadObjects{%s}: %s -> %s" % (m, sql, self.otherEndModule.getClassName()), DebugWarning) return self.thisObject.db_session.loadRecords(self.otherEndModule.getClass(), sql) def getObjects(self): if self.loaded_objects is None: self.loaded_objects = self.__loadObjects() return self.loaded_objects + self.appended_objects def setObjects(self, objects): """Replace the current contents of this association with the provided set. """ if self.otherEndMultiplicity == fkeyTypes.OneToOne: # we want a singleton item if type(object) == types.ListType: raise ValueError("One to one links cannot be lists") self.appended_objects = [objects] else: # we want a list if type(object) != types.ListType: raise ValueError("Many to one links must be lists") self.appended_objects = objects # erase any loaded objects self.loaded_objects = [] def appendObjects(self, object): if self.otherEndMultiplicity == fkeyTypes.OneToOne: if len(self) >= 1: msg = "One to one links cannot have more than one linked object" raise ValueError(msg) #if not isinstance(object, self.class_reference): elif type(object) != types.InstanceType: msg = "Requires class instance" raise ValueError(msg) # # FIXME: type checking is not working for subclasses # elif not issubclass(object.__class__, self.class_reference): # msg = "Got object [%s], was expecting [%s]" # msg %= (str(object.__class__), str(self.class_reference)) # # raise ValueError(msg) # self.appended_objects.append(object) def commit(self): """Commits changes made to linked objects """ # FIXME: this probably isn't thread safe appended_objects = self.appended_objects self.appended_objects = [] if self.loaded_objects is None: self.loaded_objects = appended_objects else: self.loaded_objects.extend(appended_objects) for object in self.loaded_objects: object.commit() def getPrimaryKeys(self): keys = [] if self.loaded_objects is None: return keys for object in self.loaded_objects: keys.append(object.id()) return keys def isLocalAssociation(self): """Attempt to determine if this class has the foreign key attribute """ # we have a self referential object return not self.otherEndHasForeignKey def updateLinks(self): if self.isLocalAssociation(): warn("saving local %s" % (self.thisObject.getTableName()), DebugWarning) # We are in the object containing the foreign key if len(self) > 1: warn("executing one to one code with too many choices", RuntimeWarning) elif len(self) == 0: warn("executing one to one code with no choices", RuntimeWarning) return m = '1' keyName = self.otherEndModule.getPrimaryKeyName() keyValue = self.loaded_objects[0].id() self.thisObject.fields[self.otherEndModule.getForeignKeyName()].setValue(keyValue) msg ='d[%s] = s[%s] = %s' % (self.thisObject.getClassName(), self.loaded_objects[0].getClassName(), str(keyValue)) warn(msg, DebugWarning) else: warn("saving remote %s" % (self.thisObject.getTableName()), DebugWarning) keyValue = self.thisObject.fields[self.thisObject.getPrimaryKeyName()].value # we're in the object that has the foreign key pointing to it. keyValue = self.thisObject.id() for object in self.appended_objects: object.fields[self.thisObject.getForeignKeyName()].setValue(keyValue) warn('d[%s] = s[%s] = %s' % (object.table_name, self.thisObject.table_name, str(keyValue)), DebugWarning) class ForeignKey: """Provides a method to follow a foreign key link to another DBClass. """ # FIXME: need to reduce the number of parameters here # FIXME: perhaps local table name and column can be determined from # FIXME: the link type and table reference. def __init__(self, column_id, local_table, foreign_table, pkey, type, table, class_reference): # Information about the foreign key self.column_id = column_id self.local_table = local_table self.foreign_table = foreign_table self.foreign_table_pkey = pkey self.fkey_type = type # information about the object we're embedded in self.table = table self.db_session = table.db_session self.class_reference = class_reference # FIXME: This probably needs to be converted to a weak reference self.loaded_objects = None self.appended_objects = [] def __len__(self): count = 0 if self.loaded_objects is not None: count += len(self.loaded_objects) count += len(self.appended_objects) return count def __loadObjects(self): sql = "SELECT * FROM \"%s\" WHERE \"%s\" = %s" warn("load %s %s" % (self.table.table_name, self.local_table), DebugWarning) if self.table.table_name == self.local_table: # We are in the object # select * from foreign_table where foreign_table_pkey = current.key from_table = self.foreign_table key_name = self.foreign_table_pkey key_value = self.table.fields[self.column_id].value else: # we're in the object that has the foreign key pointing to it. # select * from local_table where column_id = local_table.pkey from_table = self.local_table key_name = self.column_id key_value = self.table.id() if key_value is None: # can't lookup something that doesn't exist. # FIXME: how should I handle adding new objects to an object? return None from_table = sqlEscapeString(from_table) key_name = sqlEscapeString(key_name) sql = sql % (from_table, key_name, key_value) warn(sql, DebugWarning) return self.db_session.loadRecords(self.class_reference, sql) def getObjects(self): if self.loaded_objects is None: self.loaded_objects = self.__loadObjects() return self.loaded_objects + self.appended_objects def appendObjects(self, object): if self.fkey_type == fkeyTypes.OneToOne: if len(self) >= 1: msg = "One to one links cannot have more than one linked object" raise ValueError(msg) #if not isinstance(object, self.class_reference): elif type(object) != types.InstanceType: msg = "Requires class instance" raise ValueError(msg) # # FIXME: type checking is not working for subclasses # elif not issubclass(object.__class__, self.class_reference): # msg = "Got object [%s], was expecting [%s]" # msg %= (str(object.__class__), str(self.class_reference)) # # raise ValueError(msg) # self.appended_objects.append(object) def commit(self): """Commits changes made to linked objects """ # FIXME: this probably isn't thread safe appended_objects = self.appended_objects self.appended_objects = [] if self.loaded_objects is None: self.loaded_objects = appended_objects else: self.loaded_objects.extend(appended_objects) for object in self.loaded_objects: object.commit() def getPrimaryKeys(self): keys = [] if self.loaded_objects is None: return keys for object in self.loaded_objects: keys.append(object.id()) return keys def isLocalAssociation(self): """Attempt to determine which class the key to update is in. """ # we have a self referential object if self.local_table == self.foreign_table: # this code is getting ugly if self.fkey_type == fkeyTypes.OneToOne: return 1 else: return 0 # the containing class is the local class elif self.table.table_name == self.local_table: return 1 else: return 0 def updateLinks(self): if self.isLocalAssociation(): #if self.fkey_type == fkeyTypes.OneToOne: warn("saving local %s %s" % (self.table.table_name, self.local_table), DebugWarning) # We are in the object containing the foreign key if len(self) > 1: warn("executing one to one code with too many choices", RuntimeWarning) elif len(self) == 0: warn("executing one to one code with no choices", RuntimeWarning) return key_value = self.loaded_objects[0].id() self.table.fields[self.column_id].setValue(key_value) warn('d[%s] = s[%s] = %s' % (self.table.table_name, self.loaded_objects[0].table_name, str(key_value)), DebugWarning) else: warn("saving remote %s %s" % (self.table.table_name, self.local_table), DebugWarning) # we're in the object that has the foreign key pointing to it. key_value = self.table.id() for object in self.appended_objects: object.fields[self.column_id].setValue(key_value) warn('d[%s] = s[%s] = %s' % (object.table_name, self.table.table_name, str(key_value)), DebugWarning) class DBClass: """Base class for all the classes that are database backed. """ def __init__(self, db_session=None): self.loaded = 0 # FIXME: I don't like this code, but it prevents a base class from # FIXME: reinitializing the list of fields & links back to null # FIXME: perhaps we should seperate the class information # FIXME: from the writer interface? if not hasattr(self, 'fields'): self.fields = {} if not hasattr(self, 'links'): self.associations = {} self.db_session = db_session def setDefaultSession(self, db_session): """Set the default database session for anything derived from DBClass. """ DBClass.db_session = db_session def connect(self): self.db_session.connect() def id(self): """Return's the primary key value """ return self.fields[self.getPrimaryKeyName()].value def loadSelf(self, primary_key): """Given a primary key populate our fields from the database. """ try: try: cursor = self.db_session.cursor() select_sql = "SELECT * FROM \"%s\" WHERE \"%s\" = %s" table_name = sqlEscapeString(self.table_name) primary_key_name = sqlEscapeString(self.getPrimaryKeyName()) select_sql %= (table_name, primary_key_name, primary_key) cursor.execute(select_sql) # FIXME: what to do if this loads more than one record? record = cursor.fetchone() if record is None: warn("no item found", DebugWarning) raise KeyError("%s" % (str(primary_key))) else: self.loaded = 1 self.bindFields(cursor.description, record) finally: # Tag this object as having been loaded from the database cursor.close() # Yes the difference between commiting and rolling back on a select # statement is kind of irrelevant, but it does fit the database model # better except Exception, e: self.db_session.rollback() # once we've cleaned up the transaction pass the error on to the # rest of the code raise e else: self.db_session.commit() def bindFields(self, descriptions, record): """Given the PyDB 2.0 description dictionary of the fields and the fields themselves bind the field values to the corresponding Field objects in our class. """ for i in xrange(len(descriptions)): field_name = descriptions[i][0] try: self.fields[field_name].setValue(record[i], loading=self.loaded) except KeyError, e: err = "Query returned unrecognized field %s for table %s" % ( field_name, self.table_name) warn(err, RuntimeWarning) #raise KeyError(err) except TypeError, e: warn("FATAL: field %s is not type %s " % ( field_name, self.fields[field_name]), RuntimeWarning) raise e def getNextKey(self): """Get the next key value from a primary key sequence """ record = [None] try: cursor = self.db_session.cursor() # FIXME: this is a postgresql specific statement sql = "SELECT nextval('\"%s\"')" % (sqlEscapeString(self.getPrimaryKeyName()+"_seq")) warn("getNextKey: %s" % (sql), DebugWarning) cursor.execute(sql) record = cursor.fetchone() if record is None: raise KeyError("%s" % (str(self.id()))) finally: # Tag this object as having been loaded from the database cursor.close() return record[0] def insertSelf(self): """Inserts just the changes for this object If you want to actually update an object hierarchy, look at commit """ warn("Saving self[%s: %s]" % (self.table_name, self.id()), DebugWarning) cursor = self.db_session.cursor() try: # iterate over all fields and determine which have changed # construct an update for them update_names_list = [] update_values_list = [] warn("%d, %s, %d" % (self.loaded, self.getPrimaryKeyName(), self.isAutoSequence()), DebugWarning) # try and get a primary key # what should we do if there is no sequence? if not self.loaded and \ self.getPrimaryKeyName() is not None and \ self.isAutoSequence(): nextkey = self.getNextKey() self.fields[self.getPrimaryKeyName()].setValue(nextkey) # determine which fields have changed updated_fields = [] for field in self.fields.values(): warn("%s %d %d" % (field.name, field.isModified(), field.modified), DebugWarning) if field.isModified(): # save list of fields that we're committing. updated_fields.append(field) # append to list to update update_names_list.append('"'+field.name+'"') if field.type == types.StringType or field.type == types.UnicodeType: update_values_list.append("'%s'" % (sqlEscapeString(field.value))) elif field.type == DateTime.DateTimeType: update_values_list.append("'%s'" % (str(field.value))) elif field.type == Bool: update_values_list.append("'%s'" % (str(field.value))) else: update_values_list.append(str(field.value)) if len(update_values_list) > 0: # construct the query needed to update the database if self.loaded: update_tuples = zip(update_names_list, update_values_list) update_pairs_list = map(lambda (x,y): '%s=%s' % (x,y), update_tuples) update_pairs = string.join(update_pairs_list, ', ') sql = "UPDATE \"%s\" SET %s WHERE \"%s\" = %s" sql %=(sqlEscapeString(self.table_name), update_pairs, sqlEscapeString(self.getPrimaryKeyName()), self.id()) else: update_names = string.join(update_names_list, ", ") update_values = string.join(update_values_list, ", ") sql = "INSERT INTO \"%s\" (%s) VALUES (%s);" sql %= (sqlEscapeString(self.table_name), update_names, update_values) #execute the query warn(sql, DebugWarning) cursor.execute(sql) # once we've either saved ourselves or committed updates # we are in the "loaded" state. self.loaded = 1 except Exception, e: self.db_session.rollback() traceback.print_exc() raise e else: self.db_session.commit() for field in updated_fields: field.modified = 0 def commit(self, visited={}): """Attempt to write object hierarchy back to the database """ # Begin transaction if visited.has_key(self): return warn("DBClass.commit %s" % (self.table_name), DebugWarning) cursor = self.db_session.cursor() try: # save all linked objects whose primary keys are # stored in this table (one to one links) #local_test = lambda x: x.local_table == x.table.table_name local_links = filter(DBAssociation.isLocalAssociation, self.associations.values()) if local_links is not None: for link in local_links: # update the one-to-one objects link.commit() # update the local keys with values from the linked to objects link.updateLinks() visited[self] = 1 self.insertSelf() # store all links whose needs the current objects primary key # many-to-one #remote_test = lambda x: x.local_table != x.table.table_name remote_test = lambda x: not x.isLocalAssociation() remote_links = filter(remote_test, self.associations.values()) if remote_links is not None: for link in remote_links: # update the remote keys with the values from the local object link.updateLinks() # commit the many-to-one objects link.commit() except Exception, e: self.db_session.rollback() traceback.print_exc() raise e else: self.db_session.commit() warn("DBClass.commit %s done" % (self.table_name), DebugWarning) def rollback(self): """Return object back to the state loaded from the database """ # FIXME: perhaps we should be caching the original values instead self.refresh() def refresh(self): """Retrieve data out of the database again """ self.loadSelf(self.id()) def delete(self): """Delete the current object from the database. """ # FIXME: Should this actually even be an option? delete_sql = "DELETE FROM \"%s\" WHERE \"%s\" = %s" delete_sql %= (sqlEscapeString(self.table_name), sqlEscapeString(self.getPrimaryKeyName()), self.id()) try: cursor = self.db_session.cursor() cursor.execute(delete_sql) cursor.close() except Exception, e: self.db_session.rollback() raise e else: self.db_session.commit() def __str__(self): return pprint.pformat(self.__dict__) --- NEW FILE: fkeyTypes.pyt --- ########################################################################### # # # C O P Y R I G H T N O T I C E # # Copyright (c) 2001 by: # # * California Institute of Technology # # # # All Rights Reserved. # # # # Permission is hereby granted, free of charge, to any person # # obtaining a copy of this software and associated documentation files # # (the "Software"), to deal in the Software without restriction, # # including without limitation the rights to use, copy, modify, merge, # # publish, distribute, sublicense, and/or sell copies of the Software, # # and to permit persons to whom the Software is furnished to do so, # # subject to the following conditions: # # # # The above copyright notice and this permission notice shall be # # included in all copies or substantial portions of the Software. # # # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS # # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN # # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # # SOFTWARE. # ########################################################################### # # Authors: Diane Trout # Last Modified: $Date: 2003/11/11 02:05:27 $ # OneToOne = 0 ManyToOne = 1 ManyToMany = 2 OneToLots = 3 def getOppositeMultiplicity(multiplicity): """Give a particular multiplicity return a reasonable value for this association being viewed from the 'other' side. """ if multiplicity == OneToOne: return ManyToOne elif multiplicity == ManyToOne: return OneToOne elif multiplicity == ManyToMany: return ManyToMany elif multiplicity == OneToLots: return OneToOne else: raise ValueError("invalid fkey enumeration value") --- NEW FILE: init.pyt --- """Class factory for packages created by pymerase. """ import os import sys import types import pgdb as db_api %%IMPORT_MODULES%% def moduleReload(): """Reload all support modules This is needed if you want to reimport an API after regenerating it within the same python session. """ # if we're being reinitialized reload all of our modules modules = %%MODULES_LIST%% for module in modules: if sys.modules.has_key(module.__name__): #print "reloading module %s" % (module.__name__) reload(module) class Functor: def __init__(self, function, *args, **kargs): assert callable(function), "function should be a callable obj" self._function = function self._args = args self._kargs = kargs def __call__(self, *args, **kargs): """call function""" _args = list(self._args) _args.extend(args) _kargs = self._kargs.copy() _kargs.update(kargs) return apply(self._function,_args,_kargs) class DBSession: """Manages creating and closing a database session. """ default_dsn = "localhost" try: default_user = os.getlogin() except: default_user = None default_database = None default_password=None def __init__(self, dsn=None, database=None, user=None, password=None): if dsn is None: self.dsn = os.environ.get('DBHOST', DBSession.default_dsn) else: self.dsn = dsn if database is None: self.database = os.environ.get('DBDATABASE', DBSession.default_database) else: self.database = database if user is None: self.user = os.environ.get('DBUSER', DBSession.default_user) else: self.user = user if password is None: self.password = os.environ.get('DBPASSWORD', DBSession.default_password) else: self.password = password # object pointing to the low level database api self.db = None # class references is used to lookup the table class variable information # in getObjects and getAllObjects self.class_references = {} classes_to_load = %%CLASSES_LIST%% self.__loadClasses(classes_to_load) self.connect() def __del__(self): if self.db is not None: self.db.close() ############################# # Database session management def connect(self): if self.db is None: self.db = db_api.connect(dsn=self.dsn, user=self.user, database=self.database, password=self.password) def cursor(self): #if self.db is None: # self.connect() return self.db.cursor() def rollback(self): if self.db is not None: self.db.rollback() def commit(self): if self.db is not None: self.db.commit() def close(self): if self.db is not None: self.db.close() ############################ # attribute access def __loadClasses(self, module_list): for className, classRef in module_list: # construct arguments for functor _args = [classRef] kargs = {'db_session': self} # create class factory application function functor = apply(Functor, _args, kargs) # store reference to class reference, so we can # get access to the class variables when doing # certain types of lookups. (Yes this seems icky) self.class_references[functor] = classRef # add constructor to our class object setattr(self, className, functor) return for m in module_list: self.__loadClass(m) def __getClassRef(self, class_functor): """Given a class or class factory reference return a class reference """ if type(class_functor) == types.ClassType: class_ref = class_functor elif isinstance(class_functor, Functor): class_ref = self.class_references[class_functor] else: raise ValueError("unrecognized class type") return class_ref def getObjects(self, class_functor, keys): """Returns a list of objects from a list of primary keys. """ if keys is None or len(keys) == 0: # FIXME: Should this raise an error instead? return None class_ref = self.__getClassRef(class_functor) class_inst = class_ref() sql = "SELECT * FROM \"%s\" where \"%s\" in (" % ( class_ref.table_name, class_inst.getPrimaryKeyName()) sql += keys[0] for k in keys[1:]: sql += ", %s" % (k) sql += ")" return self.loadRecords(class_ref, sql) def getAllObjects(self, class_functor): """Return all records of type class_ref as a list. """ class_ref = self.__getClassRef(class_functor) sql = "SELECT * FROM \"%s\"" % (class_ref.table_name) return self.loadRecords(class_ref, sql) def getObjectsWhere(self, class_functor, where_clause): """Returns all records of type class ref that matches the sql where expr. """ class_ref = self.__getClassRef(class_functor) sql = "SELECT * FROM \"%s\" where %s" % (class_ref.table_name, where_clause) return self.loadRecords(class_ref, sql) def loadRecords(self, class_ref, sql): """Returns a list of objects selected by an sql statement. Given a class_reference and an sql statement for each record returned bind the values to an object instantiated from the class_ref. """ objects = [] try: cursor = self.db.cursor() try: cursor.execute(sql) record = cursor.fetchone() while record is not None: o = class_ref(db_session=self) # tag this object as having been loaded from the database o.loaded = 1 o.bindFields(cursor.description, record) objects.append(o) record = cursor.fetchone() finally: cursor.close() except Exception, e: # pgdb isn't too informative about exception sys.stderr.write(str(e)) sys.stderr.write(os.linesep) self.rollback() else: self.commit() return objects --- dbAPI.py DELETED --- --- fkeyTypes.py DELETED --- --- init.py DELETED --- |
From: <de...@us...> - 2003-09-10 02:11:10
|
Update of /cvsroot/pymerase/pymerase/pymerase/output/dbAPI In directory sc8-pr-cvs1:/tmp/cvs-serv11031 Modified Files: dbAPI.py Log Message: take advantage of new information about which association end has foreign key. Index: dbAPI.py =================================================================== RCS file: /cvsroot/pymerase/pymerase/pymerase/output/dbAPI/dbAPI.py,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** dbAPI.py 25 Jun 2003 05:16:26 -0000 1.25 --- dbAPI.py 10 Sep 2003 02:11:06 -0000 1.26 *************** *** 145,151 **** class DBAssociation: ! def __init__(self, thisObject, otherEndModule, otherEndMultiplicity): self.thisObject = thisObject self.otherEndMultiplicity = otherEndMultiplicity self.otherEndModule = otherEndModule --- 145,152 ---- class DBAssociation: ! def __init__(self, thisObject, otherEndModule, otherEndHasFKey, otherEndMultiplicity): self.thisObject = thisObject self.otherEndMultiplicity = otherEndMultiplicity + self.otherEndHasForeignKey = otherEndHasFKey self.otherEndModule = otherEndModule *************** *** 164,168 **** sql = "SELECT * FROM \"%s\" WHERE \"%s\" = %s" ! if self.otherEndMultiplicity == fkeyTypes.OneToOne: m = '1' keyName = self.otherEndModule.getPrimaryKeyName() --- 165,169 ---- sql = "SELECT * FROM \"%s\" WHERE \"%s\" = %s" ! if self.isLocalAssociation(): m = '1' keyName = self.otherEndModule.getPrimaryKeyName() *************** *** 246,264 **** def isLocalAssociation(self): ! """Attempt to determine which class the key to update is in. """ # we have a self referential object ! if self.thisObject.getClassName() == self.otherEndModule.getClassName(): ! # this code is getting ugly ! if self.otherEndMultiplicity == fkeyTypes.OneToOne: ! return 1 ! else: ! return 0 ! else: ! return self.otherEndMultiplicity == fkeyTypes.OneToOne def updateLinks(self): ! #if self.isLocalAssociation(): ! if self.otherEndMultiplicity == fkeyTypes.OneToOne: warn("saving local %s" % (self.thisObject.getTableName()), DebugWarning) --- 247,257 ---- def isLocalAssociation(self): ! """Attempt to determine if this class has the foreign key attribute """ # we have a self referential object ! return not self.otherEndHasForeignKey def updateLinks(self): ! if self.isLocalAssociation(): warn("saving local %s" % (self.thisObject.getTableName()), DebugWarning) |
From: <de...@us...> - 2003-09-10 02:09:04
|
Update of /cvsroot/pymerase/pymerase/pymerase/output In directory sc8-pr-cvs1:/tmp/cvs-serv10594 Modified Files: CreateDBAPI.py Log Message: take advantage of new information about which association end has foreign key. Index: CreateDBAPI.py =================================================================== RCS file: /cvsroot/pymerase/pymerase/pymerase/output/CreateDBAPI.py,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** CreateDBAPI.py 25 Apr 2003 23:55:36 -0000 1.30 --- CreateDBAPI.py 10 Sep 2003 02:09:01 -0000 1.31 *************** *** 203,209 **** init.append(u" import %s" % (otherEnd.getType().getName(TRANSLATOR_NAME))) ! init.append(u" self.associations[\"%s\"] = DBAssociation(self, %s, %s)" % ( otherEnd.getName(SQL_TRANSLATOR_NAME), otherEnd.getType().getName(TRANSLATOR_NAME), otherEnd.getMultiplicity() )) --- 203,210 ---- init.append(u" import %s" % (otherEnd.getType().getName(TRANSLATOR_NAME))) ! init.append(u" self.associations[\"%s\"] = DBAssociation(self, %s, %s, %s)" %( otherEnd.getName(SQL_TRANSLATOR_NAME), otherEnd.getType().getName(TRANSLATOR_NAME), + otherEnd.hasForeignKey(), otherEnd.getMultiplicity() )) *************** *** 350,354 **** classAssociationEnds = classMetaInfo.getAssociationEnds().values() classAttributes = classMetaInfo.getAttributes() ! classFilename = classMetaInfo.filename # FIXME: the second element in this tuple needs to contain the package --- 351,355 ---- classAssociationEnds = classMetaInfo.getAssociationEnds().values() classAttributes = classMetaInfo.getAttributes() ! classFilename = classMetaInfo.getFilename() # FIXME: the second element in this tuple needs to contain the package |
From: <de...@us...> - 2003-09-10 02:08:25
|
Update of /cvsroot/pymerase/pymerase/pymerase/input In directory sc8-pr-cvs1:/tmp/cvs-serv10514 Modified Files: parseXMI.py Log Message: Make model attributes private. Add support for knowing which association end has the foreign key. Index: parseXMI.py =================================================================== RCS file: /cvsroot/pymerase/pymerase/pymerase/input/parseXMI.py,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** parseXMI.py 9 Sep 2003 21:50:15 -0000 1.26 --- parseXMI.py 10 Sep 2003 02:08:21 -0000 1.27 *************** *** 107,118 **** def __init__(self, pymeraseConfig, name=None): AssociationEnd.__init__(self, pymeraseConfig, name) ! self.attributeName = None ! ! def setAttributeName(self, value): ! self.attributeName = value def getAttributeName(self, translatorName): ! mangler = self.config.getNameMangler(translatorName) ! if self.attributeName is None: #return "TargetAttributeName" --- 107,115 ---- def __init__(self, pymeraseConfig, name=None): AssociationEnd.__init__(self, pymeraseConfig, name) ! self.setAttributeName(None) def getAttributeName(self, translatorName): ! mangler = self.__config.getNameMangler(translatorName) ! if self.getAttributeName() is None: #return "TargetAttributeName" *************** *** 122,126 **** attributeName = self.getType().getBasePrimaryKeyName() else: ! attributeName = self.getName attributeName = self.getType().getRootClass().getName(None)+"_fk" else: --- 119,123 ---- attributeName = self.getType().getBasePrimaryKeyName() else: ! attributeName = self.getName() attributeName = self.getType().getRootClass().getName(None)+"_fk" else: *************** *** 158,162 **** """Given a name return its ClassAttribute structure """ ! if not self.primaryKeyConstructed: self.setPrimaryKeyName() --- 155,159 ---- """Given a name return its ClassAttribute structure """ ! if not self.isPrimaryKeyConstructed(): self.setPrimaryKeyName() *************** *** 167,171 **** definition. """ ! if not self.primaryKeyConstructed: self.setPrimaryKeyName() --- 164,168 ---- definition. """ ! if not self.isPrimaryKeyConstructed(): self.setPrimaryKeyName() *************** *** 176,180 **** # always return true return 1 ! def setPrimaryKeyName(self, name=None): """Indicate what field in the table should be the primary key. --- 173,177 ---- # always return true return 1 ! def setPrimaryKeyName(self, name=None): """Indicate what field in the table should be the primary key. *************** *** 194,213 **** # FIXME: we also need to allow the user some method of defining # FIXME: the primary key name ! if self.primaryKeyName is None: # Construct a primary key object ! self.primaryKeyName = self.name + "_pk" ! primaryKey = ClassAttribute(self.config, self.primaryKeyName) primaryKey.setType(PymeraseType('serial')) primaryKey.setPrimaryKey(1) self.addAttribute(primaryKey, insert=1) else: ! self.primaryKeyName = name ! warn("Setting primary_key_name: %s" % ( self.primaryKeyName ), DebugWarning) # well actually this indicates that we tried to construct a key, # if it's not needed we don't bother trying again. ! self.primaryKeyConstructed = 1 --- 191,210 ---- # FIXME: we also need to allow the user some method of defining # FIXME: the primary key name ! if self._ClassMetaInfo__primaryKeyName is None: # Construct a primary key object ! self.setPrimaryKeyName(self.getName(None) + "_pk") ! primaryKey = ClassAttribute(self.config, self._ClassMetaInfo__primaryKeyName) primaryKey.setType(PymeraseType('serial')) primaryKey.setPrimaryKey(1) self.addAttribute(primaryKey, insert=1) else: ! self._ClassMetaInfo__primaryKeyName = name ! warn("Setting primary_key_name: %s" % ( self._ClassMetaInfo__primaryKeyName ), DebugWarning) # well actually this indicates that we tried to construct a key, # if it's not needed we don't bother trying again. ! self.setPrimaryKeyConstructed(1) *************** *** 218,222 **** ## # check to see if the field is going to automatically get an index ## column_name = index.getColumnName() ! ## column_field = self.attributes.get(column_name, None) ## if column_field is not None : ## if column_field.isUnique(): --- 215,219 ---- ## # check to see if the field is going to automatically get an index ## column_name = index.getColumnName() ! ## column_field = self.__attributes.get(column_name, None) ## if column_field is not None : ## if column_field.isUnique(): *************** *** 229,244 **** ## DebugWarning) ## # tag field as being indexed, and append it to the list of indexes. ! ## self.indices.append(index) ## ## def getIndices(self): ! ## return self.indices ## ## def getSecurity(self): ! ## return self.security ## ## def appendSecurity(self, attributes): ## """Add information about user security to table ## """ ! ## self.security.append(XMISecurity(attributes)) # End extended classes --- 226,241 ---- ## DebugWarning) ## # tag field as being indexed, and append it to the list of indexes. ! ## self.__indices.append(index) ## ## def getIndices(self): ! ## return self.__indices ## ## def getSecurity(self): ! ## return self.__security ## ## def appendSecurity(self, attributes): ## """Add information about user security to table ## """ ! ## self.__security.append(XMISecurity(attributes)) # End extended classes *************** *** 273,276 **** --- 270,285 ---- # Handle: one to many # put the key in the other end + hasKey = otherEnd + elif thisEnd.getMultiplicity() != fkeyTypes.OneToOne: + # Handle: many to one + # put the key in this end + hasKey = thisEnd + else: + if thisEnd.getUUID() <= otherEnd.getUUID(): + hasKey = thisEnd + else: + hasKey = otherEnd + + if hasKey == otherEnd: #fkeyName = thisEndType.getRootClass().getName(None) + "_fk" # FIXME: should we use the association name or the primary key name? *************** *** 283,289 **** fkeyName) otherEndType.addAttribute(foreignKey) else: - # Handel: many to one or one to one - # put the key in this end # FIXME: should we use the association name or the primary key name? #fkeyName = otherEndType.getRootClass().getName(None) + "_fk" --- 292,297 ---- fkeyName) otherEndType.addAttribute(foreignKey) + otherEnd.setHasForeignKey(1) else: # FIXME: should we use the association name or the primary key name? #fkeyName = otherEndType.getRootClass().getName(None) + "_fk" *************** *** 295,300 **** fkeyName) thisEndType.addAttribute(foreignKey) ! ! return classesInModel --- 303,308 ---- fkeyName) thisEndType.addAttribute(foreignKey) ! thisEnd.setHasForeignKey(1) ! return classesInModel *************** *** 346,354 **** association = createAssociation(pymeraseConfig, thisEnd, otherEnd, attribute.getName(None)) ! # modify current attribute to be of FK type? ! attribute.setType(PymeraseType('integer')) # FIXME: converting to fk type needs to have a more general solution ! attribute.setName(attribute.getName(None) + "_fk") else: warn("Attribute %s of type %s and uuid %s in class %s was not defined in model" % ( --- 354,362 ---- association = createAssociation(pymeraseConfig, thisEnd, otherEnd, attribute.getName(None)) ! thisEndType.removeAttributeByName(attribute.getName(None)) # modify current attribute to be of FK type? ! #attribute.setType(PymeraseType('integer')) # FIXME: converting to fk type needs to have a more general solution ! #attribute.setName(attribute.getName(None) + "_fk") else: warn("Attribute %s of type %s and uuid %s in class %s was not defined in model" % ( |
From: <de...@us...> - 2003-09-10 02:08:13
|
Update of /cvsroot/pymerase/pymerase/pymerase/input In directory sc8-pr-cvs1:/tmp/cvs-serv10492 Modified Files: parseGenexSchemaXML.py Log Message: Make model attributes private. Add support for knowing which association end has the foreign key. Index: parseGenexSchemaXML.py =================================================================== RCS file: /cvsroot/pymerase/pymerase/pymerase/input/parseGenexSchemaXML.py,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** parseGenexSchemaXML.py 21 Jun 2003 01:34:27 -0000 1.30 --- parseGenexSchemaXML.py 10 Sep 2003 02:08:09 -0000 1.31 *************** *** 40,53 **** self.config = pymeraseConfig ! self.attributes = {} for k, v in attributes.items(): ! self.attributes[k] = v def getName(self, translatorName): ! return self.attributes[u"name"] def getColumnName(self, translatorName): mangler = self.config.getNameMangler(translatorName) ! return mangler.mangle(self.attributes[u"column_id"]) --- 40,53 ---- self.config = pymeraseConfig ! self.__attributes = {} for k, v in attributes.items(): ! self.__attributes[k] = v def getName(self, translatorName): ! return self.__attributes[u"name"] def getColumnName(self, translatorName): mangler = self.config.getNameMangler(translatorName) ! return mangler.mangle(self.__attributes[u"column_id"]) *************** *** 56,68 **** """ def __init__(self, attributes): ! self.attributes = {} for k, v in attributes.items(): ! self.attributes[k] = v def getUser(self): ! return self.attributes[u"user"] def getPrivilege(self): ! return self.attributes[u"privileges"] #class ERAssociation(Association): --- 56,68 ---- """ def __init__(self, attributes): ! self.__attributes = {} for k, v in attributes.items(): ! self.__attributes[k] = v def getUser(self): ! return self.__attributes[u"user"] def getPrivilege(self): ! return self.__attributes[u"privileges"] #class ERAssociation(Association): *************** *** 72,83 **** # def __init__(self, pymeraseConfig, name=None): # Association.__init__(self, pymeraseConfig, name) ! # self.targetAttributeName = None # # def setTargetAttributeName(self, value): ! # self.targetAttributeName = value # # def getTargetAttributeName(self, translatorName): # mangler = self.config.getNameMangler(translatorName) ! # return mangler.mangle(self.targetAttributeName) # class ERClassAttribute(ClassAttribute): --- 72,83 ---- # def __init__(self, pymeraseConfig, name=None): # Association.__init__(self, pymeraseConfig, name) ! # self.__targetAttributeName = None # # def setTargetAttributeName(self, value): ! # self.__targetAttributeName = value # # def getTargetAttributeName(self, translatorName): # mangler = self.config.getNameMangler(translatorName) ! # return mangler.mangle(self.__targetAttributeName) # class ERClassAttribute(ClassAttribute): *************** *** 86,110 **** def __init__(self, pymeraseConfig, name=None): ClassAttribute.__init__(self, pymeraseConfig, name) ! self.indexed = 0 # FIXME: Do we need to know that a field is indexed # FIXME: if we also keep a list of ERIndex classes? def setIndexed(self, value): ! self.indexed = parseBoolValue(value) def isIndexed(self): ! return self.indexed class ERClassMetaInfo(ClassMetaInfo): def __init__(self, pymeraseConfig, name=None): ClassMetaInfo.__init__(self, pymeraseConfig, name) ! self.autoSequence = 0 ! self.indicies = [] ! self.security = [] def setAutoSequence(self, value): """set flag to indicate if the dbAPI should auto-create primary key values """ ! self.autoSequence = parseBoolValue(value) def isAutoSequence(self): --- 86,110 ---- def __init__(self, pymeraseConfig, name=None): ClassAttribute.__init__(self, pymeraseConfig, name) ! self.__indexed = 0 # FIXME: Do we need to know that a field is indexed # FIXME: if we also keep a list of ERIndex classes? def setIndexed(self, value): ! self.__indexed = parseBoolValue(value) def isIndexed(self): ! return self.__indexed class ERClassMetaInfo(ClassMetaInfo): def __init__(self, pymeraseConfig, name=None): ClassMetaInfo.__init__(self, pymeraseConfig, name) ! self.__autoSequence = 0 ! self.__indicies = [] ! self.__security = [] def setAutoSequence(self, value): """set flag to indicate if the dbAPI should auto-create primary key values """ ! self.__autoSequence = parseBoolValue(value) def isAutoSequence(self): *************** *** 112,116 **** values """ ! return self.autoSequence def appendIndices(self, pymeraseConfig, attributes): --- 112,116 ---- values """ ! return self.__autoSequence def appendIndices(self, pymeraseConfig, attributes): *************** *** 120,124 **** # check to see if the field is going to automatically get an index column_name = index.getColumnName(None) ! column_field = self.attributes.get(column_name, None) if column_field is not None : if column_field.isUnique(): --- 120,124 ---- # check to see if the field is going to automatically get an index column_name = index.getColumnName(None) ! column_field = self.__attributes.get(column_name, None) if column_field is not None : if column_field.isUnique(): *************** *** 131,135 **** DebugWarning) # tag field as being indexed, and append it to the list of indexes. ! self.indices.append(index) --- 131,135 ---- DebugWarning) # tag field as being indexed, and append it to the list of indexes. ! self.__indices.append(index) *************** *** 138,142 **** """ # Override default that throws an unimplemented error ! self.security.append(ERSecurity(attributes)) def parseGenexFKeyType(fkey_type, tableName): --- 138,142 ---- """ # Override default that throws an unimplemented error ! self.__security.append(ERSecurity(attributes)) def parseGenexFKeyType(fkey_type, tableName): *************** *** 367,371 **** thisEnd.setAttributeName(attributes.get('column_id', None)) thisEnd.setNavigable(1) ! # construct other end otherAssociationEnds = otherEndType.getAssociationEnds() --- 367,372 ---- thisEnd.setAttributeName(attributes.get('column_id', None)) thisEnd.setNavigable(1) ! thisEnd.setHasForeignKey(1) ! # construct other end otherAssociationEnds = otherEndType.getAssociationEnds() |
From: <de...@us...> - 2003-09-10 02:07:17
|
Update of /cvsroot/pymerase/pymerase/pymerase In directory sc8-pr-cvs1:/tmp/cvs-serv10258 Modified Files: ClassMembers.py Log Message: Support one to one associations. Make class attributes private Index: ClassMembers.py =================================================================== RCS file: /cvsroot/pymerase/pymerase/pymerase/ClassMembers.py,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** ClassMembers.py 9 Sep 2003 23:14:12 -0000 1.27 --- ClassMembers.py 10 Sep 2003 02:07:13 -0000 1.28 *************** *** 115,130 **** self.setName(name) # setName calls NameMangler.mangle #self.name = name ! self.friendlyName = None ! self.description = None ! self.type = None ! self.uuid = None # utility ! self.location = [] ! self.defined = 0 # ER related ! self.indexed = 0 ! self.primaryKey = 0 def setName(self, value): --- 115,130 ---- self.setName(name) # setName calls NameMangler.mangle #self.name = name ! self.__friendlyName = None ! self.__description = None ! self.__type = None ! self.__uuid = None # utility ! self.__location = [] ! self.__defined = 0 # ER related ! self.__indexed = 0 ! self.__primaryKey = 0 def setName(self, value): *************** *** 135,157 **** def setFriendlyName(self, value): ! self.friendlyName = value def getFriendlyName(self): ! if self.friendlyName is None: return self.name else: ! return self.friendlyName def setDescription(self, value): ! self.description = value def getDescription(self): ! return self.description def setType(self, value): ! self.type = value def getType(self): ! return self.type def setUUID(self, uuid): --- 135,157 ---- def setFriendlyName(self, value): ! self.__friendlyName = value def getFriendlyName(self): ! if self.__friendlyName is None: return self.name else: ! return self.__friendlyName def setDescription(self, value): ! self.__description = value def getDescription(self): ! return self.__description def setType(self, value): ! self.__type = value def getType(self): ! return self.__type def setUUID(self, uuid): *************** *** 159,176 **** raise RuntimeError("UUID must not be None") ! self.uuid = uuid def getUUID(self): ! return self.uuid def appendLocation(self, location): """Append a location describing where we saw this Element """ ! self.location.append(location) def getLocations(self): """Return list of locations describing where we saw this element """ ! return self.location def setDefined(self, flag): --- 159,176 ---- raise RuntimeError("UUID must not be None") ! self.__uuid = uuid def getUUID(self): ! return self.__uuid def appendLocation(self, location): """Append a location describing where we saw this Element """ ! self.__location.append(location) def getLocations(self): """Return list of locations describing where we saw this element """ ! return self.__location def setDefined(self, flag): *************** *** 179,188 **** As opposed to just having been created by a dangling association reference. """ ! self.defined = flag def getDefined(self): """ """ ! return self.defined def __str__(self): --- 179,188 ---- As opposed to just having been created by a dangling association reference. """ ! self.__defined = flag def getDefined(self): """ """ ! return self.__defined def __str__(self): *************** *** 217,233 **** # add base class vars, name, type, description, friendlyName ModelElement.__init__(self, pymeraseConfig, name) ! self.required = 0 ! self.unique = 0 ! self.primaryKey = 0 ! self.foreignKey = 0 def setRequired(self, value): ! self.required = parseBoolValue(value) def isRequired(self): ! return self.required def setUnique(self, value): ! self.unique = parseBoolValue(value) def isUnique(self): --- 217,235 ---- # add base class vars, name, type, description, friendlyName ModelElement.__init__(self, pymeraseConfig, name) ! self.__required = 0 ! self.__unique = 0 ! self.__primaryKey = 0 ! self.__foreignKey = 0 ! ! self.__indexed = 0 def setRequired(self, value): ! self.__required = parseBoolValue(value) def isRequired(self): ! return self.__required def setUnique(self, value): ! self.__unique = parseBoolValue(value) def isUnique(self): *************** *** 236,246 **** NOTE: primary keys are unique so return true in that case to """ ! return self.unique or self.primaryKey def setIndexed(self, value): ! self.indexed = parseBoolValue(value) def isIndexed(self): ! return self.indexed # FIXME: can something be a primary key and a foreign key? --- 238,248 ---- NOTE: primary keys are unique so return true in that case to """ ! return self.__unique or self.__primaryKey def setIndexed(self, value): ! self.__indexed = parseBoolValue(value) def isIndexed(self): ! return self.__indexed # FIXME: can something be a primary key and a foreign key? *************** *** 253,262 **** raise ValueError("An attribute cannot be both a primary key and a foreign key") else: ! self.primaryKey = flag def isPrimaryKey(self): """Does this attribute model an ER Primary key relationship """ ! return self.primaryKey def setForeignKey(self, value): --- 255,264 ---- raise ValueError("An attribute cannot be both a primary key and a foreign key") else: ! self.__primaryKey = flag def isPrimaryKey(self): """Does this attribute model an ER Primary key relationship """ ! return self.__primaryKey def setForeignKey(self, value): *************** *** 267,281 **** raise ValueError("An attribute cannot be both a primary key and a foreign key") else: ! self.foreignKey = flag def isForeignKey(self): """Does this attribute model an ER foreign key relationship """ ! return self.foreignKey def isKey(self): """Does this attribute model an ER key relationship """ ! return (self.primaryKey or self.foreignKey) def createAssociation(pymeraseConfig, thisEnd, otherEnd, associationName=None, associationUUID=None): --- 269,283 ---- raise ValueError("An attribute cannot be both a primary key and a foreign key") else: ! self.__foreignKey = flag def isForeignKey(self): """Does this attribute model an ER foreign key relationship """ ! return self.__foreignKey def isKey(self): """Does this attribute model an ER key relationship """ ! return (self.__primaryKey or self.__foreignKey) def createAssociation(pymeraseConfig, thisEnd, otherEnd, associationName=None, associationUUID=None): *************** *** 308,312 **** else: # everything is already set up ! pass return association --- 310,315 ---- else: # everything is already set up ! assert thisEnd.getAssociation() == otherEnd.getAssociation() ! association = thisEnd.getAssociation() return association *************** *** 323,341 **** self.name = name ! self.associationEnds = [] def addAssociationEnd(self, associationEnd): ! if len(self.associationEnds) <= 2: # mark the AssociationEnd as being owned by this Association # we were using a dictionary to prevent multiple references # from being added to the associationEnd list ! #self.associationEnds[associationEnd] = associationEnd ! self.associationEnds.append(associationEnd) else: raise IndexError("Only allowed to have 2 AssociationEnd per Association") def removeAssociationEnd(self, associationEnd): ! if associationEnd in self.associationEnds: ! self.associationEnds.remove(associationEnd) associationEnd.setAssociation(None) else: --- 326,344 ---- self.name = name ! self.__associationEnds = [] def addAssociationEnd(self, associationEnd): ! if len(self.__associationEnds) <= 2: # mark the AssociationEnd as being owned by this Association # we were using a dictionary to prevent multiple references # from being added to the associationEnd list ! #self.__associationEnds[associationEnd] = associationEnd ! self.__associationEnds.append(associationEnd) else: raise IndexError("Only allowed to have 2 AssociationEnd per Association") def removeAssociationEnd(self, associationEnd): ! if associationEnd in self.__associationEnds: ! self.__associationEnds.remove(associationEnd) associationEnd.setAssociation(None) else: *************** *** 346,354 **** """Return the list of association ends attached to this association """ ! #return self.associationEnds.values() ! return self.associationEnds def __len__(self): ! return len(self.associationEnds) def __str__(self): --- 349,357 ---- """Return the list of association ends attached to this association """ ! #return self.__associationEnds.values() ! return self.__associationEnds def __len__(self): ! return len(self.__associationEnds) def __str__(self): *************** *** 356,363 **** firstEndName = "--" secondEndName = "--" ! if len(self.associationEnds) > 0: ! firstEndName = self.association[0].getName(None) ! elif len(self.associationEnds) > 1: ! secondEndName = self.association[1].getName(None) return "Association: %s (%s, %s)" % (associationName, firstEndName, --- 359,366 ---- firstEndName = "--" secondEndName = "--" ! if len(self.__associationEnds) > 0: ! firstEndName = self.__association[0].getName(None) ! elif len(self.__associationEnds) > 1: ! secondEndName = self.__association[1].getName(None) return "Association: %s (%s, %s)" % (associationName, firstEndName, *************** *** 377,392 **** # point to our containing association ! self.association = None - # names - self.attributeName = "unamed_attribute" - # class references ! self.type = None # status information ! self.navigable = 0 ! self.multiplicity = None ! self.aggregation = 0 def __str__(self): --- 380,398 ---- # point to our containing association ! self.__association = None # class references ! self.__type = None # status information ! self.__navigable = 0 ! self.__multiplicity = None ! self.__aggregation = 0 ! ! # things to make ER easier ! # name of attribute providing the link ! self.__attributeName = "unamed_attribute" ! # define which association end has the foreign key ! self.__hasForeignKey = 0 def __str__(self): *************** *** 397,404 **** """ if value is None: ! self.association = None elif isinstance(value, Association): ! if self.association != value: ! self.association = value else: raise ValueError("expected Association type") --- 403,410 ---- """ if value is None: ! self.__association = None elif isinstance(value, Association): ! if self.__association != value: ! self.__association = value else: raise ValueError("expected Association type") *************** *** 407,414 **** """return the Association this AssociationEnd is attached to """ ! return self.association def setAttributeName(self, name): ! self.attributeName = name def getAttributeName(self, translatorName): --- 413,420 ---- """return the Association this AssociationEnd is attached to """ ! return self.__association def setAttributeName(self, name): ! self.__attributeName = name def getAttributeName(self, translatorName): *************** *** 418,432 **** """ mangler = self.config.getNameMangler(translatorName) ! return mangler.mangle(self.attributeName) def setType(self, value): """Set type of this association (usually a class) """ ! self.type = value def getType(self): """return type of this association (usually a class) """ ! return self.type def getClassName(self, translatorName): --- 424,438 ---- """ mangler = self.config.getNameMangler(translatorName) ! return mangler.mangle(self.__attributeName) def setType(self, value): """Set type of this association (usually a class) """ ! self.__type = value def getType(self): """return type of this association (usually a class) """ ! return self.__type def getClassName(self, translatorName): *************** *** 434,464 **** """ # FIXME: should we check to see if it exits? ! return self.type.getName(translatorName) def setMultiplicity(self, value): ! self.multiplicity = value def getMultiplicity(self): ! return self.multiplicity def setNavigable(self, value): ! self.navigable = parseBoolValue(value) def isNavigable(self): ! return self.navigable def getOppositeEnd(self): ! if self.association is None or len(self.association) == 1: return None else: ! otherEnd = filter(lambda x: x != self, self.association.getLinks()) if len(otherEnd) == 1: return otherEnd[0] ! elif len(otherEnd) == 0 and len(self.association.getLinks()) == 2: # we have a self referental (object where both ends are the same # object. So it doesn't matter which one we return ! return self.association.getLinks()[0] else: ! raise RuntimeError("association had the wrong number of links %d instead of 2" % len(self.association.getLinks())) --- 440,484 ---- """ # FIXME: should we check to see if it exits? ! return self.__type.getName(translatorName) ! ! def setHasForeignKey(self, value): ! """set to true if the class this association end is the one containing ! the foreign key ! """ ! # FIXME: how can we check to make sure that only one side has hasForeignKey ! # FIXME: set? ! self.__hasForeignKey = parseBoolValue(value) + def hasForeignKey(self): + """set to true if the class this association end is the one containing + the foreign key + """ + return self.__hasForeignKey + def setMultiplicity(self, value): ! self.__multiplicity = value def getMultiplicity(self): ! return self.__multiplicity def setNavigable(self, value): ! self.__navigable = parseBoolValue(value) def isNavigable(self): ! return self.__navigable def getOppositeEnd(self): ! if self.__association is None or len(self.__association) == 1: return None else: ! otherEnd = filter(lambda x: x != self, self.__association.getLinks()) if len(otherEnd) == 1: return otherEnd[0] ! elif len(otherEnd) == 0 and len(self.__association.getLinks()) == 2: # we have a self referental (object where both ends are the same # object. So it doesn't matter which one we return ! return self.__association.getLinks()[0] else: ! raise RuntimeError("association had the wrong number of links %d instead of 2" % len(self.__association.getLinks())) *************** *** 497,537 **** # source file for class meta info ! self.path = None ! self.filename = None # Information about this class, # base classes, elements contained, linked to by this class ! self.packageName = pymeraseConfig.getDefaultPackage() ! self.attributes = {} ! self.attributes_order = [] ! self.associationEnds = {} # inheritance info ! self.abstract = 0 ! self.baseClasses = [] ! self.rootClassName = None # things useful for ER/SQL Modules ! self.primaryKeyName = None ! self.primaryKeyConstructed = 0 ! self.foreignKeyName = None ! self.security = [] ! self.indices = [] def setFilename(self, pathname): """Set source filename for the definition of this object """ ! self.path, self.filename = os.path.split(pathname) def getFilename(self): """Get source filename for the definition of this object """ ! return self.filename def setAbstract(self, value): ! self.abstract = parseBoolValue(value) def isAbstract(self): ! return self.abstract def setAssociationEnd(self, value): --- 517,557 ---- # source file for class meta info ! self.__path = None ! self.__filename = None # Information about this class, # base classes, elements contained, linked to by this class ! self.__packageName = pymeraseConfig.getDefaultPackage() ! self.__attributes = {} ! self.__attributes_order = [] ! self.__associationEnds = {} # inheritance info ! self.__abstract = 0 ! self.__baseClasses = [] ! self.__rootClassName = None # things useful for ER/SQL Modules ! self.__primaryKeyName = None ! self.__primaryKeyConstructed = 0 ! self.__foreignKeyName = None ! # self.__security = [] ! # self.__indices = [] def setFilename(self, pathname): """Set source filename for the definition of this object """ ! self.__path, self.__filename = os.path.split(pathname) def getFilename(self): """Get source filename for the definition of this object """ ! return self.__filename def setAbstract(self, value): ! self.__abstract = parseBoolValue(value) def isAbstract(self): ! return self.__abstract def setAssociationEnd(self, value): *************** *** 539,543 **** """ if isinstance(value, AssociationEnd): ! self.associationEnds[value.getUUID()] = value else: raise ValueError("expected AssociationEnd type") --- 559,563 ---- """ if isinstance(value, AssociationEnd): ! self.__associationEnds[value.getUUID()] = value else: raise ValueError("expected AssociationEnd type") *************** *** 546,550 **** """Return named association end attached to this object """ ! return self.associationEnds[uuid] def getAssociationEnds(self): --- 566,570 ---- """Return named association end attached to this object """ ! return self.__associationEnds[uuid] def getAssociationEnds(self): *************** *** 555,559 **** """ ! return self.associationEnds --- 575,579 ---- """ ! return self.__associationEnds *************** *** 562,566 **** """ mangler = self.config.getNameMangler(translatorName) ! return self.attributes.get(mangler.mangle(name), None) def getAttributes(self): --- 582,586 ---- """ mangler = self.config.getNameMangler(translatorName) ! return self.__attributes.get(mangler.mangle(name), None) def getAttributes(self): *************** *** 568,572 **** definition. """ ! return map(lambda x: self.attributes[x], self.attributes_order) def getAttributeNames(self, translatorName): --- 588,592 ---- definition. """ ! return map(lambda x: self.__attributes[x], self.__attributes_order) def getAttributeNames(self, translatorName): *************** *** 584,597 **** # addition, as when we return things in the order added # we'll return multiple instances ! if self.attributes.has_key(class_attribute.getName(None)): return if not insert: ! self.attributes_order.append(class_attribute.getName(None)) else: ! self.attributes_order.insert(0, class_attribute.getName(None)) ! self.attributes[class_attribute.getName(None)] = class_attribute def appendBaseClass(self, classToAdd): """append the name of super class to the list of classes --- 604,622 ---- # addition, as when we return things in the order added # we'll return multiple instances ! if self.__attributes.has_key(class_attribute.getName(None)): return if not insert: ! self.__attributes_order.append(class_attribute.getName(None)) else: ! self.__attributes_order.insert(0, class_attribute.getName(None)) ! self.__attributes[class_attribute.getName(None)] = class_attribute + def removeAttributeByName(self, attributeName): + """Remove attribute from class meta info + """ + del self.__attributes[attributeName] + self.__attributes_order.remove(attributeName) def appendBaseClass(self, classToAdd): """append the name of super class to the list of classes *************** *** 599,603 **** #FIXME: should we be following the MAGE convention of using 'add'? if isinstance(classToAdd, ClassMetaInfo): ! self.baseClasses.append(classToAdd) else: raise ValueError("appendBaseClass requires an object of type"\ --- 624,628 ---- #FIXME: should we be following the MAGE convention of using 'add'? if isinstance(classToAdd, ClassMetaInfo): ! self.__baseClasses.append(classToAdd) else: raise ValueError("appendBaseClass requires an object of type"\ *************** *** 610,639 **** raise ValueError("setBaseClass requires list") ! self.baseClasses = None for c in classListToReplace: ! self.appendBaseClass(c) def getBaseClasses(self): """Return list of super class references """ ! return self.baseClasses def getBaseClassNames(self, translatorName): """Returns list of super class names """ ! return map(lambda x: x.getName(translatorName), self.baseClasses) def setPackage(self, packageName): if type(packageName) == types.StringType or \ type(packageName) == types.UnicodeType: ! self.packageName = packageName def getPackage(self): ! return self.packageName def isRootClass(self): """Return true if we don't inherit from any other class. """ ! return not len(self.baseClasses) def getRootClass(self): --- 635,664 ---- raise ValueError("setBaseClass requires list") ! self.__baseClasses = None for c in classListToReplace: ! self.__appendBaseClass(c) def getBaseClasses(self): """Return list of super class references """ ! return self.__baseClasses def getBaseClassNames(self, translatorName): """Returns list of super class names """ ! return map(lambda x: x.getName(translatorName), self.__baseClasses) def setPackage(self, packageName): if type(packageName) == types.StringType or \ type(packageName) == types.UnicodeType: ! self.__packageName = packageName def getPackage(self): ! return self.__packageName def isRootClass(self): """Return true if we don't inherit from any other class. """ ! return not len(self.__baseClasses) def getRootClass(self): *************** *** 645,649 **** return self ! for c in self.baseClasses: rootClass = c.getRootClass() if rootClass is not None: --- 670,674 ---- return self ! for c in self.__baseClasses: rootClass = c.getRootClass() if rootClass is not None: *************** *** 690,708 **** # FIXME: we also need to allow the user some method of defining # FIXME: the primary key name ! if self.primaryKeyName is None: # Construct a primary key object ! self.primaryKeyName = self.name + "_pk" ! primaryKey = ClassAttribute(self.config, self.primaryKeyName) primaryKey.setType(PymeraseType('serial')) self.addAttribute(primaryKey, insert=1) else: ! self.primaryKeyName = name ! warn("Setting primary_key_name: %s" % ( self.primaryKeyName ), DebugWarning) # well actually this indicates that we tried to construct a key, # if it's not needed we don't bother trying again. ! self.primaryKeyConstructed = 1 --- 715,733 ---- # FIXME: we also need to allow the user some method of defining # FIXME: the primary key name ! if self.__primaryKeyName is None: # Construct a primary key object ! self.__primaryKeyName = self.name + "_pk" ! primaryKey = ClassAttribute(self.config, self.__primaryKeyName) primaryKey.setType(PymeraseType('serial')) self.addAttribute(primaryKey, insert=1) else: ! self.__primaryKeyName = name ! warn("Setting primary_key_name: %s" % ( self.__primaryKeyName ), DebugWarning) # well actually this indicates that we tried to construct a key, # if it's not needed we don't bother trying again. ! self.__primaryKeyConstructed = 1 *************** *** 714,743 **** """ ! if self.primaryKeyName is not None: ! primaryKeyName = self.primaryKeyName ! elif self.isRootClass() and not self.primaryKeyConstructed: self.setPrimaryKeyName() ! primaryKeyName = self.primaryKeyName else: return self.getBasePrimaryKeyName(translatorName) mangler = self.config.getNameMangler(translatorName) ! return mangler.mangle(self.primaryKeyName) def setForeignKeyName(self, keyName=None): """Set the foreign key name that should be used for this class. """ if keyName is None: ! if self.foreignKeyName is None: # Construct a primary key object ! self.foreignKeyName = self.name + "_fk" ! self.foreignKeyNameConstructed = 1 else: ! self.foreignKeyName = keyName ! warn("Setting foreign_key_name: %s" % ( self.foreignKeyName ), DebugWarning) ! return self.foreignKeyName def getForeignKeyName(self, translatorName): --- 739,777 ---- """ ! if self.__primaryKeyName is not None: ! primaryKeyName = self.__primaryKeyName ! elif self.isRootClass() and not self.__primaryKeyConstructed: self.setPrimaryKeyName() ! primaryKeyName = self.__primaryKeyName else: return self.getBasePrimaryKeyName(translatorName) mangler = self.config.getNameMangler(translatorName) ! return mangler.mangle(self.__primaryKeyName) + def setPrimaryKeyConstructed(self, value): + """set if primary key has been constructed + """ + self.__primaryKeyConstructed = parseBoolValue(value) + def isPrimaryKeyConstructed(self): + """indicate state of primary key construction + """ + return self.__primaryKeyConstructed + def setForeignKeyName(self, keyName=None): """Set the foreign key name that should be used for this class. """ if keyName is None: ! if self.__foreignKeyName is None: # Construct a primary key object ! self.__foreignKeyName = self.name + "_fk" ! self.__foreignKeyNameConstructed = 1 else: ! self.__foreignKeyName = keyName ! warn("Setting foreign_key_name: %s" % ( self.__foreignKeyName ), DebugWarning) ! return self.__foreignKeyName def getForeignKeyName(self, translatorName): *************** *** 746,760 **** mangler = self.config.getNameMangler(translatorName) ! if self.foreignKeyName is not None: ! return mangler.mangle(self.foreignKeyName) elif not self.isRootClass(): return mangler.mangle(self.setForeignKeyName()) else: primaryKeyName = self.getPrimaryKeyName(translatorName) ! self.foreignKeyName = pymerase.util.NameMangling.RelationalKey().getForeignKey(primaryKeyName) warn("No foreign key name set for %s, making one up %s" % (self.name, ! self.foreignKeyName), InfoWarning) ! return self.foreignKeyName --- 780,794 ---- mangler = self.config.getNameMangler(translatorName) ! if self.__foreignKeyName is not None: ! return mangler.mangle(self.__foreignKeyName) elif not self.isRootClass(): return mangler.mangle(self.setForeignKeyName()) else: primaryKeyName = self.getPrimaryKeyName(translatorName) ! self.__foreignKeyName = pymerase.util.NameMangling.RelationalKey().getForeignKey(primaryKeyName) warn("No foreign key name set for %s, making one up %s" % (self.name, ! self.__foreignKeyName), InfoWarning) ! return self.__foreignKeyName |
From: <de...@us...> - 2003-09-10 02:06:10
|
Update of /cvsroot/pymerase/pymerase/tests/pymerase In directory sc8-pr-cvs1:/tmp/cvs-serv10076 Added Files: .cvsignore Log Message: boring file --- NEW FILE: .cvsignore --- *.pyc *.class |
From: <de...@us...> - 2003-09-10 02:05:35
|
Update of /cvsroot/pymerase/pymerase/tests/pymerase In directory sc8-pr-cvs1:/tmp/cvs-serv9934 Modified Files: TestClassMembers.py Log Message: be more informative when failing filename testcase Index: TestClassMembers.py =================================================================== RCS file: /cvsroot/pymerase/pymerase/tests/pymerase/TestClassMembers.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** TestClassMembers.py 4 Aug 2003 18:42:20 -0000 1.1 --- TestClassMembers.py 10 Sep 2003 02:05:30 -0000 1.2 *************** *** 199,204 **** cmi = ClassMembers.ClassMetaInfo(self.config, "testClassMetaInfo") ! cmi.setFilename("/a/b/c/d") ! self.failUnless(cmi.getFilename() == "/a/b/c/d") self.failUnless(not cmi.getAbstract()) --- 199,206 ---- cmi = ClassMembers.ClassMetaInfo(self.config, "testClassMetaInfo") ! testFilename = "/a/b/c/d" ! cmi.setFilename(testFilename) ! ! self.failUnless(cmi.getFilename() == testFilename, "%s was not %s" % (cmi.getFilename(), testFilename) ) self.failUnless(not cmi.getAbstract()) |
From: <de...@us...> - 2003-09-09 23:14:16
|
Update of /cvsroot/pymerase/pymerase/pymerase In directory sc8-pr-cvs1:/tmp/cvs-serv10738 Modified Files: ClassMembers.py Log Message: Add extra error checking to test to make sure something is not both a primary and foreign key. Removed some dead code. Index: ClassMembers.py =================================================================== RCS file: /cvsroot/pymerase/pymerase/pymerase/ClassMembers.py,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** ClassMembers.py 25 Jul 2003 00:40:34 -0000 1.26 --- ClassMembers.py 9 Sep 2003 23:14:12 -0000 1.27 *************** *** 185,188 **** --- 185,189 ---- """ return self.defined + def __str__(self): return str(self.__dict__) *************** *** 242,250 **** def isIndexed(self): return self.indexed def setPrimaryKey(self, value): """Flag this attribute as being a primary key """ ! self.primaryKey = parseBoolValue(value) def isPrimaryKey(self): --- 243,257 ---- def isIndexed(self): return self.indexed + + # FIXME: can something be a primary key and a foreign key? def setPrimaryKey(self, value): """Flag this attribute as being a primary key """ ! flag = parseBoolValue(value) ! if self.isForeignKey() and flag: ! raise ValueError("An attribute cannot be both a primary key and a foreign key") ! else: ! self.primaryKey = flag def isPrimaryKey(self): *************** *** 256,260 **** """Flag this attribute as being a foreign key """ ! self.foreignKey = parseBoolValue(value) def isForeignKey(self): --- 263,271 ---- """Flag this attribute as being a foreign key """ ! flag = parseBoolValue(value) ! if self.isPrimaryKey() and flag: ! raise ValueError("An attribute cannot be both a primary key and a foreign key") ! else: ! self.foreignKey = flag def isForeignKey(self): *************** *** 299,302 **** --- 310,315 ---- pass + return association + class Association(ModelElement): """Describe the meta info regarding the between two objects *************** *** 323,328 **** def removeAssociationEnd(self, associationEnd): ! if self.association.has_key(associationEnd): ! del self.association[associationEnd] else: raise ValueError("Attempted to remove association end that is not part"+ --- 336,342 ---- def removeAssociationEnd(self, associationEnd): ! if associationEnd in self.associationEnds: ! self.associationEnds.remove(associationEnd) ! associationEnd.setAssociation(None) else: raise ValueError("Attempted to remove association end that is not part"+ *************** *** 382,386 **** """set the Association this AssociationEnd is attached to """ ! if isinstance(value, Association): if self.association != value: self.association = value --- 396,402 ---- """set the Association this AssociationEnd is attached to """ ! if value is None: ! self.association = None ! elif isinstance(value, Association): if self.association != value: self.association = value *************** *** 471,511 **** return mangler.createAppender(self.getName(translatorName)) - - # def setClassToCreate(self, classReference): - # """Sets the object that this foreign key link should create - # """ - ### # if we're using the class to create name as the name of this object - ### # update it if it gets changed while resolving foreign keys - ### if self.classToCreate is not None and self.name == self.classToCreate.name: - ### self.setName(classReference.getName(None)) - ### - # self.classToCreate = classReference - # - # def getClassToCreate(self): - # """Returns a reference to the ClassMetaInfo object for the class - # that this association should create. - # """ - # return self.classToCreate - # - # def getClassToCreateName(self, translatorName): - # """Get the name of what object this association should create. - # - # The class to create can be either the foreign or local table depending - # on which table needs to be queried. - # """ - # return self.classToCreate.getName(translatorName) - # - # def setContainingClass(self, value): - # self.containingClass = value - # - # def getContainingClass(self): - # return self.containingClass - # - # def getContainingClassName(self, translatorName): - # """Returns the name of the table that has the foreign key local to it - # """ - # mangler = self.config.getNameMangler(translatorName) - # return mangler.mangle(self.containingClass.getName(None)) - # class ClassMetaInfo(ModelElement): --- 487,490 ---- *************** *** 578,627 **** return self.associationEnds - # def getAssociations(self): - # """Return list of object associations in the order declared in the object - # definition. - # """ - # return self.associations - # - # def addAssociation(self, association): - # """Add association to list and determine if we need to add to others as - # well. - # """ - # # FIXME: This is seeming specialized for the table.dtd version - # self.associations.append(association) - # - # localClassName = association.getContainingClassName(None) - # targetClassName = association.getTargetClassName(None) - # warn("TargetClassName: %s" % (targetClassName), DebugWarning) - # warn("LocalClassName : %s" % (localClassName), DebugWarning) - # - # localAssociationName = association.getLocalAssociationName(None) - # foreignAssociationName = association.getForeignAssociationName(None) - # - # # return this association if it should be appended to another - # # list of class associations as well (genex related, maybe mage as well) - # if self.name != targetClassName: - # return (self.name, copy.deepcopy(association)) - # # special case self referential objects - # elif targetClassName == localClassName: - # reversed = copy.deepcopy(association) - # # swap association names - # tempAssociation = reversed.getLocalAssociationName(None) - # reversed.setLocalAssociationName(reversed.getForeignAssociationName(None)) - # reversed.setForeignAssociationName(tempAssociation) - # # swap key/columns - # attribute = reversed.getTargetAttributeName(None) - # reversed.setTargetAttributeName(reversed.getAssociationAttributeName(None)) - # reversed.setAssociationAttributeName(attribute) - # - # # swap multiplicity - # if reversed.getMultiplicity() == fkeyTypes.OneToOne: - # reversed.setMultiplicity(fkeyTypes.ManyToOne) - # elif reversed.getMultiplicity() == fkeyTypes.ManyToOne: - # reversed.setMultiplicity(fkeyTypes.OneToOne) - # - # return (self.name, reversed) - # else: - # return None def getAttributeByName(self, name, translatorName): --- 557,560 ---- |
From: <ki...@us...> - 2003-09-09 22:00:19
|
Update of /cvsroot/pymerase/pymerase/examples/umlExamples In directory sc8-pr-cvs1:/tmp/cvs-serv27900 Added Files: createsql4house.py Log Message: creates sql for house.zargo example --- NEW FILE: createsql4house.py --- #!/usr/bin/env python import sys import os import pymerase if __name__ == "__main__": schema = os.path.abspath("./house.xmi") outputPath = os.path.abspath("./house.sql") pymerase.run(schema, "parseXMI", outputPath, "CreateSQL") |