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")
|