modeling-cvs Mailing List for Object-Relational Bridge for python (Page 3)
Status: Abandoned
Brought to you by:
sbigaret
You can subscribe to this list here.
2003 |
Jan
|
Feb
|
Mar
(54) |
Apr
(29) |
May
(94) |
Jun
(47) |
Jul
(156) |
Aug
(132) |
Sep
(40) |
Oct
(6) |
Nov
(18) |
Dec
(24) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
(18) |
Feb
(59) |
Mar
(7) |
Apr
|
May
(8) |
Jun
(2) |
Jul
(12) |
Aug
(15) |
Sep
(12) |
Oct
(6) |
Nov
(25) |
Dec
(1) |
2005 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2006 |
Jan
|
Feb
(27) |
Mar
|
Apr
(16) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Sebastien B. <sbi...@us...> - 2004-11-30 17:11:56
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1000/Modeling/ModelMasons Modified Files: PyModelMason.py Log Message: * ModelMasons/PyModelMason.py (PyModelMason.build): added parameter 'pymodel_path', that should be equal to the full path of the file containing the PyModel from which 'model' was built, or None otherwise. If supplied, the method copies the original pymodel into the generated package, otherwise it generates the xml files from the 'model' as usual. Index: PyModelMason.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons/PyModelMason.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** PyModelMason.py 29 Nov 2004 16:47:50 -0000 1.12 --- PyModelMason.py 30 Nov 2004 17:11:46 -0000 1.13 *************** *** 102,106 **** class PyModelMason(ModelMason): "See the module's documentation for details" ! def __init__(self, model, rootPath=None, verbose_mode=0, generation_scheme='compact', fake_mode=0): """ --- 102,106 ---- class PyModelMason(ModelMason): "See the module's documentation for details" ! def __init__(self, model, pymodel_path, rootPath=None, verbose_mode=0, generation_scheme='compact', fake_mode=0): """ *************** *** 108,122 **** supplied model. ! Parameters: ! ! model -- see ModelMason.__init__() ! ! rootPath -- see ModelMason.__init__() ! ! verbode_mode -- see ModelMason.__init__() ! ! use_scheme -- 'compact' or 'base' ! ! fake_mode -- see ModelMason.__init__() """ --- 108,118 ---- supplied model. ! :Parameters: ! - `model`: see ModelMason.__init__() ! - `pymodel_path`: ! - `rootPath`: see ModelMason.__init__() ! - `verbode_mode`: see ModelMason.__init__() ! - `generation_scheme`: either string ``"compact"`` or ``"base"`` ! - `fake_mode`: see ModelMason.__init__() """ *************** *** 131,134 **** --- 127,131 ---- self.generation_scheme=generation_scheme self.base_dir=generation_scheme=='base' and 'MDL' or '' + self.pymodel_path=pymodel_path def tmpl_namespace(self): *************** *** 149,153 **** "-" #----------------------------------------------------------------- ! def create_model_files(self, xml_path, py_path): "Creates or overwrite the model (.xml and .py)" # model_<modelName>.xml --- 146,150 ---- "-" #----------------------------------------------------------------- ! def create_xmlmodel_files(self, xml_path, py_path): "Creates or overwrite the model (.xml and .py)" # model_<modelName>.xml *************** *** 173,176 **** --- 170,185 ---- del modelStr #----------------------------------------------------------------- + def create_pymodel_file(self, pymodel_path_ori, pymodel_path): + "Creates or overwrite the pymodel" + if os.path.exists(pymodel_path): + self.log('Overwriting %s'%pymodel_path) + else: + self.log('Generating %s'%pymodel_path) + if not self.fake_mode: + import shutil + shutil.copy(pymodel_path_ori, pymodel_path) + self.log('... done') + self.log('\n') + #----------------------------------------------------------------- # Build as many directories with __init__.py as needed *************** *** 191,199 **** # COMPACT generation scheme if self.generation_scheme=='compact': ! # Create model files (.xml/.py) ! xmlp=self.fullPathForGeneratedFile('model_'+self.model.name()+'.xml') ! pyp="model_%s.py"%self.model.name() ! create_model_files(self, xmlp, pyp) ! # modules for self._entities in self.entitiesSet(): --- 200,215 ---- # COMPACT generation scheme if self.generation_scheme=='compact': ! if not self.pymodel_path: ! # Create model files (.xml/.py) ! xmlp=self.fullPathForGeneratedFile('model_'+self.model.name()+'.xml') ! pyp="model_%s.py"%self.model.name() ! create_xmlmodel_files(self, xmlp, pyp) ! else: ! basePath=self.fullPathForGeneratedFile(self.base_dir) ! create_pymodel_file(self, ! self.pymodel_path, ! os.path.join(basePath, ! "pymodel_%s.py"%self.model.name())) ! # modules for self._entities in self.entitiesSet(): *************** *** 218,226 **** overwrite=1) ! create_model_files(self, ! os.path.join(basePath, ! 'model_'+self.model.name()+'.xml'), ! os.path.join(self.base_dir, ! "model_%s.py"%self.model.name())) # modules for self._entities in self.entitiesSet(): --- 234,249 ---- overwrite=1) ! if not self.pymodel_path: ! create_xmlmodel_files(self, ! os.path.join(basePath, ! 'model_'+self.model.name()+'.xml'), ! os.path.join(self.base_dir, ! "model_%s.py"%self.model.name())) ! else: ! create_pymodel_file(self, ! self.pymodel_path, ! os.path.join(basePath, ! "pymodel_%s.py"%self.model.name())) ! # modules for self._entities in self.entitiesSet(): |
From: Sebastien B. <sbi...@us...> - 2004-11-30 17:11:54
|
Update of /cvsroot/modeling/ProjectModeling/Modeling In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1000/Modeling Modified Files: ChangeLog Log Message: * ModelMasons/PyModelMason.py (PyModelMason.build): added parameter 'pymodel_path', that should be equal to the full path of the file containing the PyModel from which 'model' was built, or None otherwise. If supplied, the method copies the original pymodel into the generated package, otherwise it generates the xml files from the 'model' as usual. Index: ChangeLog =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/ChangeLog,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** ChangeLog 30 Nov 2004 17:07:37 -0000 1.4 --- ChangeLog 30 Nov 2004 17:11:45 -0000 1.5 *************** *** 1,4 **** --- 1,11 ---- 2004-11-30 Sebastien Bigaret <sbi...@us...> + * ModelMasons/PyModelMason.py (PyModelMason.build): added + parameter 'pymodel_path', that should be equal to the full path of + the file containing the PyModel from which 'model' was built, or + None otherwise. If supplied, the method copies the original + pymodel into the generated package, otherwise it generates the xml + files from the 'model' as usual. + * Model.py (_loadModel): Added: now contains the code that was initially in loadModel(), and returns the model AND the detected |
From: Sebastien B. <sbi...@us...> - 2004-11-30 17:07:47
|
Update of /cvsroot/modeling/ProjectModeling/Modeling In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv32448/Modeling Modified Files: ChangeLog Model.py ModelSet.py Log Message: * Model.py (_loadModel): Added: now contains the code that was initially in loadModel(), and returns the model AND the detected model_type (xml- or py-model) --this is in particular for future use by mdl_generate_python_code.py * ModelSet.py (ModelSet.addModelFromXML): moved the code which does load the model to Model.loadXMLModel() Index: Model.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/Model.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** Model.py 20 Jul 2004 06:21:37 -0000 1.17 --- Model.py 30 Nov 2004 17:07:37 -0000 1.18 *************** *** 60,70 **** See also: ModelSet.addModel() ! Parameters: ! ! model -- the model whose conn.dict. should be updated ! ! cfg_path -- the full path to the configuration file, or if omitted or ! None, defaults to the value stored in the env. variable ! MDL_DB_CONNECTIONS_CFG """ --- 60,68 ---- See also: ModelSet.addModel() ! :Parameters: ! - `model`: the model whose conn.dict. should be updated ! - `cfg_path`: the full path to the configuration file, or if omitted or ! ``None``, defaults to the value stored in the env. variable ! ``MDL_DB_CONNECTIONS_CFG`` """ *************** *** 103,136 **** def loadModel(path): """ ! Load a model stored in the file 'path'. The lookup procedure is: ! - if path ends with '.py', we assume it is a python module. This module is ! imported and the following attributes are searched within it, in that order: ! 1. 'model' (either an attribute or a function): if found, we assume ! this is an instance of Modeling.Model.Model and we return the value ! 2. 'pymodel' (id.): if found, we assume this is an instance of ! Modeling.PyModel.Model and we return its 'component' attribute ! If the PyModel has not been built yet, it is build() here. ! 3. 'model_src' (id.): if found, we assume this is a string and return ! the model build from it with ModelSet.addModelFromXML() ! ! - if path ends with '.xml', we assume this is a xml-file and we return the ! model build with ModelSet.addModelFromXML() ! Returns: the loaded Modeling.Model.Model instance ! Raises ValueError if file 'path' cannot be handled, or IOError or ! ImportError if the files does no exists, has errors, etc. ! Parameter: ! path -- the path of the file where the model is stored """ ! if path[-3:]=='.py': import os,imp dir,filename=os.path.dirname(path),os.path.basename(path) --- 101,158 ---- def loadModel(path): """ ! Load a model stored in the file `path`. The lookup procedure is: ! - if `path` ends with ``.py``, we assume it is a python module. This module ! is imported and the following attributes are searched within it, in that order: + + 1. ``model`` (either an attribute or a function): if found, the method + determines whether this is a `Model.Model` or a `PyModel.Model`. + If the PyModel has not been built yet, it is build() here. + + 2. ``pymodel`` (either an attribute or a function): if found, we + assume this is an instance of PyModel.Model and we return + its 'component' attribute. If the PyModel has not been built yet, + it is build() here. + + 3. ``model_src`` (id.): if found, we assume this is a string and the + returned model is built from that xml stream with `loadXMLModel()` + + - if `path` ends with ``.xml``, we assume this is a xml-file and we return + the model build with loadXMLModel() ! Note: this method calls `updateModelWithCFG()` on the model before returning ! it. If you want to have the non-updated model, use `_loadModel` instead. ! :param path: the path of the file where the model is stored ! :return: the loaded Modeling.Model.Model instance ! :raise ValueError: if file 'path' cannot be handled, or IOError or ! ImportError if the files does no exists, has errors, etc. ! """ ! model, model_type = _loadModel(path) ! updateModelWithCFG(model) ! return model ! def _loadModel(path): ! """ ! Note: this method does NOT call updateModelWithCFG() ! ! :return: a tuple ``(model, model_type)``, where ``model`` is the model ! itself, and ``model_type`` a string being either ``"xmlmodel"`` or ! ``"pymodel"`` indicating whether the model was found in a xml stream or in ! a `PyModel`. + """ ! model_type = "xmlmodel" ! ! if path[-4:]=='.xml': ! model=loadXMLModel(open(path, 'rb').read()) ! ! elif path[-3:]=='.py': import os,imp dir,filename=os.path.dirname(path),os.path.basename(path) *************** *** 151,178 **** import PyModel if isinstance(model, PyModel.Model): if not model.is_built: model.build() model=model.component - updateModelWithCFG(model) - return model ! if hasattr(module, 'pymodel'): pymodel=module.pymodel if callable(pymodel): pymodel=pymodel() ! pymodel.build() ! updateModelWithCFG(pymodel.component) ! return pymodel.component ! if hasattr(module, 'model_src'): model_src=module.model_src if callable(model_src): model_src=model_src() from ModelSet import ModelSet ! model=ModelSet().addModelFromXML({'string': model_src}) ! updateModelWithCFG(model) ! return model ! raise ValueError, "Couldn't find any of these attributes in python file '%s': model, pymodel (PyModel) or model_src (xml)"%path except ImportError: --- 173,199 ---- import PyModel if isinstance(model, PyModel.Model): + model_type = "pymodel" if not model.is_built: model.build() model=model.component ! elif hasattr(module, 'pymodel'): ! model_type = "pymodel" pymodel=module.pymodel if callable(pymodel): pymodel=pymodel() ! if not model.is_built: ! pymodel.build() ! model=pymodel.component ! elif hasattr(module, 'model_src'): model_src=module.model_src if callable(model_src): model_src=model_src() from ModelSet import ModelSet ! model=loadXMLModel(model_src) ! else: ! raise ValueError, "Couldn't find any of these attributes in python file '%s': model, pymodel (PyModel) or model_src (xml)"%path except ImportError: *************** *** 186,203 **** finally: if file: file.close() ! elif path[-4:]=='.xml': ! from ModelSet import ModelSet ! return ModelSet().addModelFromXML({'file': path}) ! else: raise ValueError, 'Unable to handle file %s: unrecognized format (filename should end with either with .py or .xml)'%path def searchModel(modelName, path=None, verbose=0): """ ! Searches for the model named 'modelName' by trying loadModel() with the ! following paths: 'pymodel_<modelName>.py', 'model_<modelName>.py' and ! 'model_<modelName>.xml' in the current directory and the MDL/ directory. ! Returns the model, or None if it cannot be found/loaded """ --- 207,250 ---- finally: if file: file.close() ! else: raise ValueError, 'Unable to handle file %s: unrecognized format (filename should end with either with .py or .xml)'%path + return model, model_type + + def loadXMLModel(xml_content): + """ + Loads an xml-model and returns the corresponding Model. + + :param xml_content: a string containing the whole xml stream. If the xml is + stored in a file, it is suggested that the file is opened in binary mode + (for example, ``loadXMLModel(open(file_path, 'rb').read())``) + + + """ + from XMLutils import autoDetectXMLEncoding, XMLImportError, unicodeToStr + from xml.dom.minidom import parseString + + encoding=autoDetectXMLEncoding(xml_content) + xmldoc=parseString(xml_content) + + # Do we have only one model? _TBD: a DTD should be responsible for this! + modelNode=xpath.Evaluate('/model', contextNode=xmldoc) + if len(modelNode)!=1: + raise XMLImportError, 'Only one model in a xml file!' + # Ok, go! + modelNode=modelNode[0] + modelName=modelNode.getAttribute('name') + model=Model(unicodeToStr(modelName, encoding)) + model.initWithXMLDOMNode(modelNode, encoding) + return model + def searchModel(modelName, path=None, verbose=0): """ ! Searches for the model named `modelName` by trying `loadModel()` with the ! following paths: ``pymodel_<modelName>.py``, ``model_<modelName>.py`` and ! ``model_<modelName>.xml`` in the current directory and the MDL/ directory. ! :return: the model, or None if it cannot be found/loaded """ Index: ChangeLog =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/ChangeLog,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** ChangeLog 24 Nov 2004 11:26:30 -0000 1.3 --- ChangeLog 30 Nov 2004 17:07:37 -0000 1.4 *************** *** 1,2 **** --- 1,12 ---- + 2004-11-30 Sebastien Bigaret <sbi...@us...> + + * Model.py (_loadModel): Added: now contains the code that was + initially in loadModel(), and returns the model AND the detected + model_type (xml- or py-model) --this is in particular for future + use by mdl_generate_python_code.py + + * ModelSet.py (ModelSet.addModelFromXML): moved the code which + does load the model to Model.loadXMLModel() + 2004-11-24 Sebastien Bigaret <sbi...@us...> Index: ModelSet.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/ModelSet.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** ModelSet.py 20 Jul 2004 06:21:37 -0000 1.13 --- ModelSet.py 30 Nov 2004 17:07:37 -0000 1.14 *************** *** 16,20 **** The framework'core can only handle one ModelSet at a time: the one returned by ! defaultModelSet(). The module & class main responsabilities are: 1. making sure that all the entities defined in a ModelSet instance have --- 16,20 ---- The framework'core can only handle one ModelSet at a time: the one returned by ! `defaultModelSet()`. The module & class main responsabilities are: 1. making sure that all the entities defined in a ModelSet instance have *************** *** 25,30 **** 2. registering the object returned by defaultModelSet() as the default receiver for the notification ! ClassDescriptionNeededForEntityNameNotification posted by ! classDescriptionForName() in module ClassDescription. --- 25,30 ---- 2. registering the object returned by defaultModelSet() as the default receiver for the notification ! `ClassDescriptionNeededForEntityNameNotification` posted by ! `ClassDescription.classDescriptionForName()`. *************** *** 38,42 **** from Modeling.utils import isaValidName, base_persistent_object - from Modeling.XMLutils import * from Modeling.Model import ModelError, Model from Modeling.ClassDescription import ClassDescriptionNeededForEntityNameNotification --- 38,41 ---- *************** *** 45,49 **** from Modeling import ClassDescription import types - from xml.dom.minidom import parseString from Modeling.logging import error, warn --- 44,47 ---- *************** *** 160,181 **** #import pdb; pdb.set_trace() if xmlSource.has_key('string'): ! encoding=autoDetectXMLEncoding(xmlSource['string']) ! xmldoc=parseString(xmlSource['string']) elif xmlSource.has_key('file'): f=open(xmlSource['file'], 'rb') ! encoding=autoDetectXMLEncoding(f.read()) f.close() - xmldoc=parseString(open(xmlSource['file']).read()) else: raise AttributeError, "xmlSource parameter has no key 'string' or 'file'" ! # Do we have only one model? _TBD: a DTD should be responsible for this! ! modelNode=xpath.Evaluate('/model', contextNode=xmldoc) ! if len(modelNode)!=1: ! raise XMLImportError, 'Only one model in a xml file!' ! # Ok, go! ! modelNode=modelNode[0] ! modelName=modelNode.getAttribute('name') ! model=Model(unicodeToStr(modelName, encoding)) ! model.initWithXMLDOMNode(modelNode, encoding) self.addModel(model) return model --- 158,170 ---- #import pdb; pdb.set_trace() if xmlSource.has_key('string'): ! xml_content=xmlSource['string'] elif xmlSource.has_key('file'): f=open(xmlSource['file'], 'rb') ! xml_content=f.read() f.close() else: raise AttributeError, "xmlSource parameter has no key 'string' or 'file'" ! ! model=Model.loadXMLModel(xml_content) self.addModel(model) return model *************** *** 206,211 **** if not _model: return None - #doc=createDOMDocumentObject() - #root = doc.documentElement return _model.getXMLDOM(doc=None, parentNode=None, encoding=encoding) --- 195,198 ---- |
From: Sebastien B. <sbi...@us...> - 2004-11-29 17:18:29
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/doc/UserGuide In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5114/doc/UserGuide Modified Files: CodeRequirements.tex Log Message: misc. correction Index: CodeRequirements.tex =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/doc/UserGuide/CodeRequirements.tex,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** CodeRequirements.tex 29 Nov 2004 17:08:43 -0000 1.4 --- CodeRequirements.tex 29 Nov 2004 17:18:19 -0000 1.5 *************** *** 144,148 **** \begin{itemize} ! \item for quick testing a model, but in this case, you'll probably prefer to dynamically build the package and modules (see section~\ref{from-model-to-python-dynamic-approach}, below), --- 144,148 ---- \begin{itemize} ! \item to quickly test a model, but in this case, you'll probably prefer to dynamically build the package and modules (see section~\ref{from-model-to-python-dynamic-approach}, below), |
From: Sebastien B. <sbi...@us...> - 2004-11-29 17:08:54
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/doc/UserGuide In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2881/Modeling/doc/UserGuide Modified Files: CodeRequirements.tex Log Message: Documentation: added full documentation concerning: 1. the static generation, or the dynamic building of python package and modules from a model, 2. the requirements the framework imposes on python modules and classes. Index: CodeRequirements.tex =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/doc/UserGuide/CodeRequirements.tex,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** CodeRequirements.tex 21 Sep 2003 18:50:37 -0000 1.3 --- CodeRequirements.tex 29 Nov 2004 17:08:43 -0000 1.4 *************** *** 32,43 **** ! \section{The python package generated from an XML model \label{basics-CustomObject}} ! We take the model \code{AuthorBooks} as an example--you'll find it at:\\ ! \file{Modeling/tests/testPackages/AuthorBooks/model_AuthorBooks.xml}, as ! defined in section~\ref{model-author-books}. ! In this model, we have two entities, \class{Writer} and \class{Book}: \begin{verbatim} --- 32,61 ---- ! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ! \section{From model to python code\label{from-model-to-python}} ! A (valid!) model contains all the necessary informations to generate a usable ! python package that can be used immediately to store and retrieve informations ! in a database. + In this section, we examine the different ways offered in the framework to + derive usable python code from a model; the model we'll use is + \code{AuthorBooks}, that you'll find it in:\\ + \file{Modeling/tests/testPackages/AuthorBooks} (either the pymodel in + \code{pymodel_AuthorBooks.py}, or the xml-model in + \code{model_AuthorBooks.xml}), and which is described in + section~\ref{model-author-books}. ! \begin{notice} ! Even if the framework offers different ways of deriving python code from ! models, you do not {\em have to} use these tools: they are provided for ! convenience but you can choose to write your package and code by other means ! of your own. If you choose to do so, you'll find below in the ! section~\ref{class-code-requirements} the few requirements needed to ! bind your classes to a model and to the framework. ! \end{notice} ! ! Quick reminder: in this model, we have two entities, \class{Writer} and ! \class{Book}: \begin{verbatim} *************** *** 52,125 **** \end{verbatim} ! When you generate the python code for that model, you get a ! \module{AuthorBooks} package. \begin{itemize} ! \item \module{__init__.py} takes care to load the model within the default ! \class{ModelSet}, ! \item the model xml file is dropped within the package, ! \item you get two modules, \module{Writer} and \module{Book}, containing, ! respectively the classes \class{Book} and \class{Writer}. \end{itemize} ! Let's have a look at the \class{Book} class -- I won't copy it here, go to ! \file{Modeling/tests/testPackages/AuthorBooks/Book.py} and keep an eye on ! it (or generate your own copy using the ZModelizationTool or the provided ! scripts). ! ! Let's take a look at the code. After the initial imports, we get: ! \begin{enumerate} ! \item class declaration: ! \begin{verbatim} ! class Book (CustomObject): ! \end{verbatim} ! i.e.: every object should derive from \class{CustomObject}, which ! defines the appropriate methods. ! \item Initializer: defines some default values for your attributes. ! {\bf Note}: It {\bf must} be possible to call the \method{__init__} ! with no arguments at all. If you want to add arguments to ! \method{__init__}, each one should have default values. The reason for this is ! that the framework relies on a call to \code{__init__()}, without any ! arguments, when it needs to create an instance before populating it with data ! fetched from the database. ! \item \code{def entityName(self)}: this is the way the framework currently ! binds an object to its entity. This should be changed (see TODO) ! \item Then you get setters and getters for the attributes, whose exact form ! depends on their nature (attributes, to-one or to-many relationships). ! There is also some validation code ready to be used. See ! \ref{customobject-validation}, ``Validation'' for details. ! In getters and setters, notice the methods \method{willRead()} and ! \method{willChange()}. These methods are defined by \class{CustomObject}. \begin{itemize} - \item \method{willRead} informs the object that we need the values stored in - the database. This is because objects can be ``{\em faults}'' (ZODB - speaking, they are ghosts). This method's job is to initialize the - object. ! \item \method{willChange} informs the object that it is about to change. This ! is part of the \class{Observing} interface, and its purpose is to notify ! the \class{EditingContext} that an object is about to change; the ! \class{EditingContext} needs this to keep track of changes in its graph ! of objects. ZODB speaking, this is what the mix-in class ! \class{Persistent} does transparently for immutable attributes (see ! also: TODO). ! Of course, \method{willChange} invokes \method{willRead} when ! appropriate. \begin{notice}[warning] It is your responsability to call \method{willRead} and \method{willChange} when you are about to, respectively, access or ! change a class attribute corresponding to a Model's Attribute or Relationship; if you do not, the \class{EditingContext}, which is responsible for examining the changes and making them persistent, is --- 70,389 ---- \end{verbatim} ! \subsection{Generating the python code\label{from-model-to-python-static-approach}} ! ! \subsubsection{The minimum\label{from-model-to-python-static-approach-compact}} ! ! The first option you have is to generate the whole python package ! \code{AuthorBooks} and its modules \code{Writer.py} and \code{Book.py}. ! ! For that purpose, you'll use the script \program{mdl_generate_python_code.py} ! (note that the same functionalities are also offered in the ZModeler). ! ! On the command-line, type: ! \begin{verbatim} ! mdl_generate_python_code.py model_AuthorBooks.xml ! \end{verbatim} ! ! We'll see in the next paragraph that there exists two different way of ! generating the code. That one is the simplest and uses the default option of ! the script \program{mdl_generate_python_code.py}: \programopt{-C} or ! \longprogramopt{compact-generation-scheme}\footnote{Please refer to ! \program{mdl_generate_python_code.py}~\longprogramopt{help} for a ! comprehensive view on the script's usage and options}. ! ! The script creates the python package \code{AuthorBooks} in the current ! directory, in which you'll find the following files: ! ! \begin{verbatim} ! AuthorBooks/ ! |-- Book.py ! |-- Writer.py ! |-- __init__.py ! |-- * model_AuthorBooks.py ! |-- * model_AuthorBooks.xml ! `-- setup.py ! \end{verbatim} ! ! Note: the files marked with a star~(\code{*}) are the only one that are ! overwritten by the script, if they already exist. ! \begin{itemize} ! \item \module{__init__.py}, which takes care to load the model within the ! default \class{ModelSet}, ! \item a copy of the model in the corresponding xml file which is used, and a ! python file containing a copy of the xml model as well; the reason for which ! the model is copied into a python file is that it makes it easy to ! distribute and install it along w/ the other modules using the standard ! distutils. ! Also note: even if you generate the python module from a pymodel, you'll ! only get those two xml-models in the generated package. This might change in ! the future, in the meantime, feel free to replace them with your pymodel, ! the code generated in \file{__init__.py} loading the model is capable of ! finding either a pymodel or an xml-model (see ! \ulink{Model.searchModel()}{http://modeling.sourceforge.net/API/Modeling-API/public/Modeling.Model-module.html\#searchModel} ! ! \item \module{Writer} and \module{Book}: they contain the classes \class{Book} ! and \class{Writer}, ready to be used ! ! \item \module{setup.py}: a \module{distutils} script that you can use to ! install the package, to distribute it, etc. (see \ulink{Distributing Python ! Modules} {http://www.python.org/doc/current/dist/dist.html} and ! \ulink{Installing Python Modules} ! {http://www.python.org/doc/current/inst/inst.html} for details about the ! Python Distribution Utilities). \end{itemize} ! This bunch of files gives a minimalist view of what is needed to bind python ! code to a model and to the framework --this subject is fully discussed in the ! dedicated section~\ref{framework-code-requirements}. You can use it: ! \begin{itemize} ! \item for quick testing a model, but in this case, you'll probably prefer to ! dynamically build the package and modules (see ! section~\ref{from-model-to-python-dynamic-approach}, below), ! \item or to start coding your classes from that point. Now if you want to use ! the generated code as a basis for your own development, we strongly advise ! you to consider using the other generation scheme exposed in the next ! paragraph. ! \end{itemize} ! \subsubsection{Separating the generated code from your own work\label{from-model-to-python-static-approach-base}} ! During development, especially at early stages, the model is likely to change ! at a high rate, and so does the code which is automatically derived from the ! model. In such situations (and, in fact, each time the model change), it is ! quite easy to see that the so-called ``compact scheme'' used in the paragraph ! above is not very convenient: the script does not overwrite any existing file, ! so integrating the new changes consists in, for example, moving the python ! file elsewhere, regenrate the code, then integrate any code you may have ! written by hand from the previsouly moved python file to the new one... ! ! ! That's why the script \program{mdl_generate_python_code.py} has an other ! option: \programopt{-B} or ~\longprogramopt{base-generation-scheme}, which is ! specially designed to keep the generated code separated from the business ! logic you add, so that you'll never have to worry mixing your own logic with ! automatically derived portions of code. ! ! ! As an example, let's see the generated files by this scheme: ! ! \begin{verbatim} ! AuthorBooks/ ! |-- Book.py ! |-- MDL ! | |-- * Book.py ! | |-- * Writer.py ! | |-- * __init__.py ! | |-- * model_AuthorBooks.py ! | `-- * model_AuthorBooks.xml ! |-- Writer.py ! |-- __init__.py ! `-- setup.py ! \end{verbatim} ! ! As you can see, a new subpackage \code{MDL} is created, where the files are ! always overwritten when regenerating the code --and more: the files within ! that directory are the only ones that can be overwritten by the script. ! ! ! The modules \module{Book} and \module{Writer} in the top-level directory are ! the place where you'll put your own code; the classes within directly inherit ! from the ones in the \code{MDL} subpackage, keeping the automatically ! generated portion of codes completely separated from your own code. ! ! ! \subsection{Building the python package dynamically, at run-time\label{from-model-to-python-dynamic-approach}} ! ! You also have the option to derive all necessary modules and classes directly ! from a model, at runtime. The module \module{Modeling.dynamic} has been added ! for that purpose, and offers two different options. ! ! \subsubsection{Dynamic generating of ``standard'' python code} ! ! The first method simply consists in building the exact same code as the one ! generated by \code{mdl_generate_python_code.py}: ! ! \begin{verbatim} ! ### Load the model ! def load_model(): ! from Modeling import ModelSet, Model ! model=Model.searchModel('AuthorBooks', '.', verbose=1) ! ModelSet.defaultModelSet().addModel(model) ! ! # build and use it! ! from Modeling import dynamic ! dynamic.build(model, define_properties=0) ! from AuthorBooks.Book import Book ! \end{verbatim} ! ! As expected, if you call \method{build} with \code{define_properties=1}, the ! method adds python properties (see \ulink{\code{property')} in built-in ! functions}{http://docs.python.org/lib/built-in-funcs.html} for each attribute ! or relationship in the entity, so that you do not need anymore to use ! e.g. \code{book.getTitle()} or \code{book.setTitle}, but simply \code{print ! book.title} or \code{book.title="my title"}. ! ! ! \subsubsection{Dynamic generation using metaclass} ! ! The second method makes use of the metaclass \class{dynamic.CustomObjectMeta}: ! ! \begin{verbatim} ! # file: Book.py ! # We assume that the model is already loaded ! from Modeling import dynamic ! ! class Book: ! __metaclass__=dynamic.CustomObjectMeta ! entityName='Book' ! mdl_define_properties=1 ! ! # your own code here ! ! \end{verbatim} ! ! % note: class Book should be accessible w/ 'from package.module import class' ! ! The metaclass \class{CustomObjectMeta} automatically adds all the necessary ! methods to a class for integration with the modeling framework. It looks for ! the following attributes in the class: \begin{itemize} ! \item \code{entityNamed}`: mandatory, this is the name of the class' ! entity. The corresponding model should have been loaded prior to the class ! declaration, or you'll get a \exception{dynamic.EntityNotFound} exception. ! ! \item \code{verbose_metaclass}: if set, the metaclass prints on ! \code{sys.stderr} some info while building the class. ! ! \item \code{mdl_define_properties}: if set, the metaclass will also add ! properties for each attribute on relationship in the entity. ! ! \end{itemize} ! ! Last, then \module{dynamic} module also offers a method ! \method{build_with_metaclass(model, define_properties=0, verbose=0)} which you ! can use to derive the necessary package and modules from a model just like ! \code{dynamic.build()} we saw above, the ony difference being that the classes ! created at runtime use the metaclass approach. ! ! ! \subsection{Static vs. dynamic: what's best?\label{from-model-to-python-static-vs-dynamic-discussion}} ! ! The question of which option one should use is an opened question! In fact, ! it highly depends on your own preferences: some people do not want to hear of ! code generators, others keep metaclasses away from their code. Some argue ! that it is best to maintain the model only, deriving the necessary modules at ! runtime, while others prefer to statically generate the code so that it can be ! put under version control, for example, or because they want to keep an eye on ! the generated parts. ! ! This being said, here are a few comments: ! ! \begin{itemize} ! ! \item if you go for the static generation of python code, better choose the ! ``base'' scheme if you use the script \code{mdl_generate_python_code.py} (or ! a similar approach if you build the code by your own means). ! ! \item whichever method you choose, static generation, dynamic build with or ! without metaclasses, it is ``officially'' supported. Some people have ! argued that having all these possible ways available makes it difficult to ! make a choice; our position is that since we are here speaking about the ! code people write, we shouldn't force anyone to follow a given path if they ! prefer the other one. We think (and hope!) that the offered possibilities ! cover most code pratices --if you think we forgot something, we'll be happy ! to hear from you. ! ! Now if you're really looking for an advice, let's say that our personal ! preference consists in dynamically building the modules, using metaclass and ! properties. ! ! \end{itemize} ! ! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ! \section{The framework's requirements on python code\label{framework-code-requirements}} ! ! \subsection{Package's, modules' and classes' names} ! ! When it fetches objects from the database, the framework needs to be able to ! instantiate every classes referenced in a model, so it also needs to find ! them! It does so by simply importing the class with a statement equivalent ! to: ! \begin{verbatim} ! >>> from package_name.module_name import class_name ! \end{verbatim} ! where the package's name, the module's name and the class' name are the one ! provided in the model (the package's name is in the model's properties while ! the two others are in the crresponding entity's properties, see ! sections~\ref{model-props} and \ref{entity-props}). ! ! Thus, these three properties should always be kept in sync with the ! corresponding code. ! ! \subsection{Within classes} ! ! A class corresponding to an entity must meet the following requirements: ! ! \begin{description} ! ! \item[Inheritance:] the class must include \class{CustomObject} in its ! inheritance list ! ! \item[Initializer:] the method \code{__init__()} should be designed so that it ! is possible to call it with no arguments at all: for example, if the method ! accepts arguments, each one should have default values. The reason for this ! is that the framework relies on a call to \code{__init__()} without any ! arguments, when it needs to create an instance before populating it with ! data fetched from the database. ! ! \item[Entity's name:] the class must define a method \code{entityName()} taking ! no argument: this is the way the framework currently binds an object to its ! entity. This should be changed (see TODO) ! ! \item[\method{willRead()}:] this method defined in \class{CustomObject} must ! be called prior to accessing an object's property\footnote{i.e. either an ! attribute or a relationship defined in the entity}. It informs the object ! that it is time to fetch the values stored in the database if it's not done ! yet. This is because objects can be ``{\em faults}'' (ZODB speaking, they ! are ghosts), i.e. they have been instantiated but not fully initialized yet ! (lazily initialization) ! ! \item[\method{willChange()}:] defined in \code{CustomObject} as well, this ! method should be called prior to modifying an object's property. This is ! part of the \class{Observing} interface, and its purpose is to notify the ! \class{EditingContext} that the object is about to change: the ! \class{EditingContext} needs to keep track of changes in its graph of ! objects in order to be able to save the changes (ZODB speaking, this is what ! the mix-in class \class{Persistent} does transparently for immutable ! attributes (see also: TODO)). ! Of course, \method{willChange} automatically invokes \method{willRead}. ! ! \item[Getters, setters:] although the python code derived from a model stores ! its properties in attributes beginning with an underscore (for example, ! \code{_lastName} for attribute \code{lastName}), the framework itself does ! not require this. Instead, it accesses and sets the values using the ! so-called private API of KeyValueCoding; shortly said, this means that in ! order to read a property 'name' for example, it tries to find either an ! attribute or a method called '_name', '_name()', '_getName()', 'name', ! 'getName()'. Refer to \ref{customobject-key-value-coding} for a complete ! overview. ! ! \end{description} \begin{notice}[warning] It is your responsability to call \method{willRead} and \method{willChange} when you are about to, respectively, access or ! change an object's property corresponding to a Model's Attribute or Relationship; if you do not, the \class{EditingContext}, which is responsible for examining the changes and making them persistent, is *************** *** 128,139 **** \end{notice} - \end{itemize} - \end{enumerate} - - That's it. You can then start coding your own business logic. Objects are - always inserted, deleted or updated in a database via an instance of the - \class{EditingContext} class (see chapter \ref{editing-context}, ``Working - with your objects: insert, changes, deletion''). \section{Automatic validation of referential and business-logic constraints \label {customobject-validation}} --- 392,397 ---- \end{notice} + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Automatic validation of referential and business-logic constraints \label {customobject-validation}} |
From: Sebastien B. <sbi...@us...> - 2004-11-29 17:08:53
|
Update of /cvsroot/modeling/ProjectModeling In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2881 Modified Files: CHANGES Log Message: Documentation: added full documentation concerning: 1. the static generation, or the dynamic building of python package and modules from a model, 2. the requirements the framework imposes on python modules and classes. Index: CHANGES =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/CHANGES,v retrieving revision 1.62 retrieving revision 1.63 diff -C2 -d -r1.62 -r1.63 *** CHANGES 29 Nov 2004 16:47:50 -0000 1.62 --- CHANGES 29 Nov 2004 17:08:42 -0000 1.63 *************** *** 10,13 **** --- 10,20 ---- * Now distributed under a 3-clause BSD-style license, see LICENSE for details + * Documentation: added full documentation concerning: + + 1. the static generation, or the dynamic building of python package and + modules from a model, + + 2. the requirements the framework imposes on python modules and classes. + * Script mdl_generate_python_code.py does not create the empty files TODO.txt, README.txt, VERSION.txt, INSTALL.txt, DEPEDENCIES.txt anymore |
From: Sebastien B. <sbi...@us...> - 2004-11-29 17:03:11
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons/Python_bricks In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1472/Modeling/ModelMasons/Python_bricks Modified Files: module_base.tmpl Log Message: Msg. "# Generated by..." is now on the 1st line of the file Index: module_base.tmpl =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons/Python_bricks/module_base.tmpl,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** module_base.tmpl 15 Nov 2003 13:26:28 -0000 1.6 --- module_base.tmpl 29 Nov 2004 17:02:58 -0000 1.7 *************** *** 1,4 **** --- 1,5 ---- ## This template will build the module #import time + # Generated by mdl_generate_python_code.py / $(time.strftime("%Y/%m/%d %H:%M")) #for entity in $entities: *************** *** 8,12 **** #end for - # Generated by mdl_generate_python_code.py / $(time.strftime("%Y/%m/%d %H:%M")) from Modeling.Validation import ValidationException from mx.DateTime import DateTimeFrom --- 9,12 ---- |
From: Sebastien B. <sbi...@us...> - 2004-11-29 16:55:48
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons/Python_bricks In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30392/Modeling/ModelMasons/Python_bricks Modified Files: setup_tmpl.tmpl Log Message: Fixed: a whitespace between '#' and '!' on 1st line prevented it from being interpreted as the interpreter Index: setup_tmpl.tmpl =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons/Python_bricks/setup_tmpl.tmpl,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** setup_tmpl.tmpl 26 Aug 2002 21:19:31 -0000 1.1 --- setup_tmpl.tmpl 29 Nov 2004 16:55:38 -0000 1.2 *************** *** 1,3 **** ! # !/usr/bin/env python from distutils.core import setup --- 1,3 ---- ! #! /usr/bin/env python from distutils.core import setup |
From: Sebastien B. <sbi...@us...> - 2004-11-29 16:48:02
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28489/Modeling/ModelMasons Modified Files: PyModelMason.py Log Message: Script mdl_generate_python_code.py does not create the empty files TODO.txt, README.txt, VERSION.txt, INSTALL.txt, DEPEDENCIES.txt anymore Index: PyModelMason.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons/PyModelMason.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** PyModelMason.py 20 Jul 2004 06:21:40 -0000 1.11 --- PyModelMason.py 29 Nov 2004 16:47:50 -0000 1.12 *************** *** 178,186 **** # empty files ! self.createEmptyFile("TODO.txt",overwrite=0) ! self.createEmptyFile("README.txt",overwrite=0) ! self.createEmptyFile("VERSION.txt",overwrite=0) ! self.createEmptyFile("INSTALL.txt",overwrite=0) ! self.createEmptyFile("DEPENDENCIES.txt",overwrite=0) # package's __init__.py --- 178,186 ---- # empty files ! #self.createEmptyFile("TODO.txt",overwrite=0) ! #self.createEmptyFile("README.txt",overwrite=0) ! #self.createEmptyFile("VERSION.txt",overwrite=0) ! #self.createEmptyFile("INSTALL.txt",overwrite=0) ! #self.createEmptyFile("DEPENDENCIES.txt",overwrite=0) # package's __init__.py |
From: Sebastien B. <sbi...@us...> - 2004-11-29 16:48:00
|
Update of /cvsroot/modeling/ProjectModeling In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28489 Modified Files: CHANGES MIGRATION Log Message: Script mdl_generate_python_code.py does not create the empty files TODO.txt, README.txt, VERSION.txt, INSTALL.txt, DEPEDENCIES.txt anymore Index: CHANGES =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/CHANGES,v retrieving revision 1.61 retrieving revision 1.62 diff -C2 -d -r1.61 -r1.62 *** CHANGES 24 Nov 2004 15:53:41 -0000 1.61 --- CHANGES 29 Nov 2004 16:47:50 -0000 1.62 *************** *** 10,13 **** --- 10,16 ---- * Now distributed under a 3-clause BSD-style license, see LICENSE for details + * Script mdl_generate_python_code.py does not create the empty files + TODO.txt, README.txt, VERSION.txt, INSTALL.txt, DEPEDENCIES.txt anymore + * Fixed bug #1032577: undetected syntax errors in qualifier strings. Thanks to Marcos Dione for the report Index: MIGRATION =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/MIGRATION,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** MIGRATION 28 Jan 2004 14:54:09 -0000 1.3 --- MIGRATION 29 Nov 2004 16:47:50 -0000 1.4 *************** *** 4,7 **** --- 4,13 ---- newer version. + Upgrading to 0.9pre18 + --------------------- + + * Script mdl_generate_python_code.py does not create the empty files + TODO.txt, README.txt, VERSION.txt, INSTALL.txt, DEPEDENCIES.txt anymore + Upgrading to 0.9pre17 --------------------- |
From: Sebastien B. <sbi...@us...> - 2004-11-24 15:54:09
|
Update of /cvsroot/modeling/ProjectModeling In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11192 Modified Files: CHANGES Log Message: Fixed bug #1032577: undetected syntax errors in qualifier strings Index: CHANGES =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/CHANGES,v retrieving revision 1.60 retrieving revision 1.61 diff -C2 -d -r1.60 -r1.61 *** CHANGES 24 Nov 2004 15:11:18 -0000 1.60 --- CHANGES 24 Nov 2004 15:53:41 -0000 1.61 *************** *** 10,13 **** --- 10,16 ---- * Now distributed under a 3-clause BSD-style license, see LICENSE for details + * Fixed bug #1032577: undetected syntax errors in qualifier strings. Thanks + to Marcos Dione for the report + * Fixed bug #981123 reported by Ernesto Revilla: dynamic.build() now accepts PyModels |
From: Sebastien B. <sbi...@us...> - 2004-11-24 15:54:08
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/tests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11192/Modeling/tests Modified Files: test_Qualifier.py Log Message: Fixed bug #1032577: undetected syntax errors in qualifier strings Index: test_Qualifier.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/tests/test_Qualifier.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** test_Qualifier.py 24 Nov 2004 11:30:38 -0000 1.14 --- test_Qualifier.py 24 Nov 2004 15:53:42 -0000 1.15 *************** *** 332,337 **** self.failUnless(isinstance(q, KeyValueQualifier)) ! def test_10_andornot(self): ! "[Qualifier] " q=qualifierWithQualifierFormat('orbit == 1') self.failUnless(isinstance(q, KeyValueQualifier)) --- 332,337 ---- self.failUnless(isinstance(q, KeyValueQualifier)) ! def test_11_andornot(self): ! "[Qualifier] attributes'names beginning w/ AND, OR, NOT are valid!" q=qualifierWithQualifierFormat('orbit == 1') self.failUnless(isinstance(q, KeyValueQualifier)) *************** *** 340,344 **** q=qualifierWithQualifierFormat('NOTIFICATION == "WARNING"') self.failUnless(isinstance(q, KeyValueQualifier)) ! # Build the test suite def test_suite(): --- 340,350 ---- q=qualifierWithQualifierFormat('NOTIFICATION == "WARNING"') self.failUnless(isinstance(q, KeyValueQualifier)) ! ! def test_12_syntax_error_detection(self): ! "[Qualifier] detection of syntax errors / bug #1032577" ! self.assertRaises(ValueError, ! qualifierWithQualifierFormat, ! 'name like "you" AND isActive=1') ! # Build the test suite def test_suite(): |
From: Sebastien B. <sbi...@us...> - 2004-11-24 15:54:04
|
Update of /cvsroot/modeling/ProjectModeling/Modeling In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11192/Modeling Modified Files: QualifierParser.py Log Message: Fixed bug #1032577: undetected syntax errors in qualifier strings Index: QualifierParser.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/QualifierParser.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** QualifierParser.py 20 Jul 2004 06:21:37 -0000 1.16 --- QualifierParser.py 24 Nov 2004 15:53:41 -0000 1.17 *************** *** 72,76 **** def trace(msg, *args): ! #print msg%args pass --- 72,79 ---- def trace(msg, *args): ! #if args: ! # print msg%args ! #else: ! # print msg pass *************** *** 234,237 **** --- 237,249 ---- self.rv.append(Token(type='comma')) + def t_zz_error(self, s): + r' .* ' + raise ValueError, "Syntax Error: %s"%s + # TBD Implementation note: + # TBD this is needed to detect the case where not all the string is parsed + # TBD such as in: 'name like "you" AND isActive=1' which is NOT detected + # TBD as a syntax error otherwise + + #def t_simplekeypath(self, s): # r' \c+ ' |
From: Sebastien B. <sbi...@us...> - 2004-11-24 15:11:53
|
Update of /cvsroot/modeling/ProjectModeling/Modeling In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv570/Modeling Modified Files: dynamic.py Log Message: Fixed bug #981123 reported by Ernesto Revilla: dynamic.build() now accepts PyModels In the same method: also fixed the generated module's '__name__', and added attribute '__module__' to the generated classes Index: dynamic.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/dynamic.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** dynamic.py 20 Jul 2004 06:21:37 -0000 1.2 --- dynamic.py 24 Nov 2004 15:11:19 -0000 1.3 *************** *** 140,143 **** --- 140,160 ---- def build(model, define_properties=0): + """ + Takes a model and builds the corresponding package and modules + + :Parameters: + + - `model`: either a `Modeling.Model.Model` or a + `Modeling.PyModel.Model`. Please note that if it is a pymodel, its + method build() is called + + - `define_properties`: + + """ + from Modeling import PyModel + if isinstance(model, PyModel.Model): + if not model.is_built: + model.build() + model=model.component module_name=model.packageName() classes={} *************** *** 149,153 **** classes[e.name()]=c modules[e.name()]=m ! m.__name__='AB.'+e.name() # Not required? but in accordance to observations add_init(c, e) add_entityName(c, e) --- 166,170 ---- classes[e.name()]=c modules[e.name()]=m ! m.__name__= module_name+'.'+e.name() add_init(c, e) add_entityName(c, e) *************** *** 156,160 **** if define_properties: add_properties(c, e) ! p=new.module(module_name) --- 173,177 ---- if define_properties: add_properties(c, e) ! c.__module__=module_name+'.'+e.name() p=new.module(module_name) |
From: Sebastien B. <sbi...@us...> - 2004-11-24 15:11:52
|
Update of /cvsroot/modeling/ProjectModeling In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv570 Modified Files: CHANGES Log Message: Fixed bug #981123 reported by Ernesto Revilla: dynamic.build() now accepts PyModels In the same method: also fixed the generated module's '__name__', and added attribute '__module__' to the generated classes Index: CHANGES =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/CHANGES,v retrieving revision 1.59 retrieving revision 1.60 diff -C2 -d -r1.59 -r1.60 *** CHANGES 23 Nov 2004 17:41:50 -0000 1.59 --- CHANGES 24 Nov 2004 15:11:18 -0000 1.60 *************** *** 10,13 **** --- 10,18 ---- * Now distributed under a 3-clause BSD-style license, see LICENSE for details + * Fixed bug #981123 reported by Ernesto Revilla: dynamic.build() now accepts + PyModels + In the same method: also fixed the generated module's '__name__', and + added attribute '__module__' to the generated classes + * Fixed bug #1008615: disabled the FutureWarning raised by python2.3 for negative value in hex(). Thanks to Lorenzo Gil Sanchez for reporting. |
From: Sebastien B. <sbi...@us...> - 2004-11-24 15:11:47
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/tests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv570/Modeling/tests Modified Files: run.py Added Files: test_dynamic.py Log Message: Fixed bug #981123 reported by Ernesto Revilla: dynamic.build() now accepts PyModels In the same method: also fixed the generated module's '__name__', and added attribute '__module__' to the generated classes --- NEW FILE: test_dynamic.py --- #! /usr/bin/env python # -*- coding: iso-8859-1 -*- #----------------------------------------------------------------------------- # Modeling Framework: an Object-Relational Bridge for python # # Copyright (c) 2001-2004 Sébastien Bigaret <sbi...@us...> # All rights reserved. # # This file is part of the Modeling Framework. # # This code is distributed under a "3-clause BSD"-style license; # see the LICENSE file for details. #----------------------------------------------------------------------------- """ Tests for module delegation CVS Information $Id: test_dynamic.py,v 1.1 2004/11/24 15:11:19 sbigaret Exp $ """ __version__= '$Revision: 1.1 $'[11:-2] import unittest if __name__ == "__main__": import utils, sys utils.fixpath() from Modeling import dynamic def sample_pymodel(modelname): "Builds a sample pymodel" from Modeling.PyModel import Model, Entity, AString pymodel=Model(modelname) # a PyModel.Model pymodel.version='0.1' # This is mandatory!! e=Entity("Person",properties=[AString("name")]) pymodel.entities.append(e) return pymodel class TestDynamic(unittest.TestCase): "Tests for module dynamic" def test_01_build_accepts_pymodel(self): "[dynamic] build() accepts PyModels - bug #981123" pymodel=sample_pymodel("TestDynamic_test_01_pymodel_a") dynamic.build(pymodel) # should not fail import TestDynamic_test_01_pymodel_a self.failUnless(TestDynamic_test_01_pymodel_a.Person) # an already built pymodel should be ok as well pymodel=sample_pymodel("TestDynamic_test_01_pymodel_b") pymodel.build() dynamic.build(pymodel) # should not fail import TestDynamic_test_01_pymodel_b self.failUnless(TestDynamic_test_01_pymodel_b.Person) # Build the test suite def test_suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(TestDynamic, "test_")) return suite if __name__ == "__main__": errs = utils.run_suite(test_suite()) sys.exit(errs and 1 or 0) Index: run.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/tests/run.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** run.py 21 Sep 2004 18:03:27 -0000 1.12 --- run.py 24 Nov 2004 15:11:19 -0000 1.13 *************** *** 59,62 **** --- 59,64 ---- import test_SchemaGeneration + import test_dynamic + def usage(prgName, exitStatus=None): _usage="""%s [-v] [-V] *************** *** 105,108 **** --- 107,111 ---- suite.addTest(test_SQLExpression.test_suite()) suite.addTest(test_SchemaGeneration.test_suite()) + suite.addTest(test_dynamic.test_suite()) # global if global_tests: |
From: Sebastien B. <sbi...@us...> - 2004-11-24 11:30:54
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/tests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15080/tests Modified Files: test_Qualifier.py Log Message: Added tests for bug #938096, already fixed in QualifierParser.py v1.15 Index: test_Qualifier.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/tests/test_Qualifier.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** test_Qualifier.py 20 Jul 2004 06:21:57 -0000 1.13 --- test_Qualifier.py 24 Nov 2004 11:30:38 -0000 1.14 *************** *** 332,335 **** --- 332,344 ---- self.failUnless(isinstance(q, KeyValueQualifier)) + def test_10_andornot(self): + "[Qualifier] " + q=qualifierWithQualifierFormat('orbit == 1') + self.failUnless(isinstance(q, KeyValueQualifier)) + q=qualifierWithQualifierFormat('notification == "warning"') + self.failUnless(isinstance(q, KeyValueQualifier)) + q=qualifierWithQualifierFormat('NOTIFICATION == "WARNING"') + self.failUnless(isinstance(q, KeyValueQualifier)) + # Build the test suite def test_suite(): |
From: Sebastien B. <sbi...@us...> - 2004-11-24 11:27:17
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/tests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14248/tests Modified Files: test_SQLExpression.py Log Message: Fixed two tests in test_SQLExpression so that it does not fail when Entity.attributesToFetch() changes the order of the returned attributes Index: test_SQLExpression.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/tests/test_SQLExpression.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** test_SQLExpression.py 21 Sep 2004 19:18:17 -0000 1.12 --- test_SQLExpression.py 24 Nov 2004 11:26:36 -0000 1.13 *************** *** 156,161 **** sqlExpr.prepareSelectExpressionWithAttributes(book.attributesToFetch(), lock=0, fetchSpec=fs) self.assertEqual(sqlExpr.statement(), ! "SELECT DISTINCT t0.id, t0.title, t0.FK_WRITER_ID, t0.PRICE FROM BOOK t0 INNER JOIN ( WRITER t1 INNER JOIN WRITER t2 ON t1.FK_WRITER_ID=t2.ID ) ON t0.FK_WRITER_ID=t1.ID WHERE t2.LAST_NAME = 'Rabelais'") # None/NULL value --- 156,167 ---- sqlExpr.prepareSelectExpressionWithAttributes(book.attributesToFetch(), lock=0, fetchSpec=fs) + + # Note: the result is directly dependant on the order in which attributes + # are returned by Entity.attributesToFetch() (which in turn depends on + # other things, such as attributes that are used for locking, etc.) + attrs=', '.join(['t0.%s'%a.columnName() for a in book.attributesToFetch()]) + self.assertEqual(sqlExpr.statement(), ! "SELECT DISTINCT %s FROM BOOK t0 INNER JOIN ( WRITER t1 INNER JOIN WRITER t2 ON t1.FK_WRITER_ID=t2.ID ) ON t0.FK_WRITER_ID=t1.ID WHERE t2.LAST_NAME = 'Rabelais'"%attrs) # None/NULL value *************** *** 167,171 **** lock=0, fetchSpec=fs) self.assertEqual(sqlExpr.statement(), ! "SELECT DISTINCT t0.id, t0.title, t0.FK_WRITER_ID, t0.PRICE FROM BOOK t0 INNER JOIN ( WRITER t1 INNER JOIN ( WRITER t2 INNER JOIN BOOK t3 ON t2.ID=t3.FK_WRITER_ID ) ON t1.FK_WRITER_ID=t2.ID ) ON t0.FK_WRITER_ID=t1.ID WHERE t3.PRICE IS NULL") def test_07_prepareSelectExpressionWithAttributes_02(self): --- 173,177 ---- lock=0, fetchSpec=fs) self.assertEqual(sqlExpr.statement(), ! "SELECT DISTINCT %s FROM BOOK t0 INNER JOIN ( WRITER t1 INNER JOIN ( WRITER t2 INNER JOIN BOOK t3 ON t2.ID=t3.FK_WRITER_ID ) ON t1.FK_WRITER_ID=t2.ID ) ON t0.FK_WRITER_ID=t1.ID WHERE t3.PRICE IS NULL"%attrs) def test_07_prepareSelectExpressionWithAttributes_02(self): *************** *** 179,184 **** lock=0, fetchSpec=fetchSpec) self.assertEqual(sqlExpr.statement(), ! "SELECT DISTINCT t0.id, t0.title, t0.FK_WRITER_ID, t0.PRICE FROM BOOK t0 INNER JOIN ( WRITER t1 INNER JOIN WRITER t2 ON t1.FK_WRITER_ID=t2.ID ) ON t0.FK_WRITER_ID=t1.ID WHERE t2.LAST_NAME = t1.LAST_NAME") def test_suite(): --- 185,194 ---- lock=0, fetchSpec=fetchSpec) + + # See note in test_06_prepareSelectExpressionWithAttributes_01() + attrs=', '.join(['t0.%s'%a.columnName() for a in book.attributesToFetch()]) + self.assertEqual(sqlExpr.statement(), ! "SELECT DISTINCT %s FROM BOOK t0 INNER JOIN ( WRITER t1 INNER JOIN WRITER t2 ON t1.FK_WRITER_ID=t2.ID ) ON t0.FK_WRITER_ID=t1.ID WHERE t2.LAST_NAME = t1.LAST_NAME"%attrs) def test_suite(): |
From: Sebastien B. <sbi...@us...> - 2004-11-24 11:26:59
|
Update of /cvsroot/modeling/ProjectModeling/Modeling In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14248 Modified Files: ChangeLog Log Message: Fixed two tests in test_SQLExpression so that it does not fail when Entity.attributesToFetch() changes the order of the returned attributes Index: ChangeLog =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/ChangeLog,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** ChangeLog 2 Aug 2004 20:54:47 -0000 1.2 --- ChangeLog 24 Nov 2004 11:26:30 -0000 1.3 *************** *** 1,2 **** --- 1,13 ---- + 2004-11-24 Sebastien Bigaret <sbi...@us...> + + * tests/test_SQLExpression.py + (TestSQLExpression_2.test_06_prepareSelectExpressionWithAttributes_01): + * tests/test_SQLExpression.py + (TestSQLExpression_2.test_07_prepareSelectExpressionWithAttributes_02): + Fixed so that it does not fail when Entity.attributesToFetch() + changes the order of the returned attributes (which, in + particular, depends on which attribuest are marked as + 'usedForLocking') + 2004-08-02 Sebastien Bigaret <sbi...@us...> |
From: Sebastien B. <sbi...@us...> - 2004-11-23 17:42:05
|
Update of /cvsroot/modeling/ProjectModeling In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10011 Modified Files: CHANGES Log Message: Fixed bug #1008615: disabled the FutureWarning raised by python2.3 for negative value in hex(). Thanks to Lorenzo Gil Sanchez for reporting. Index: CHANGES =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/CHANGES,v retrieving revision 1.58 retrieving revision 1.59 diff -C2 -d -r1.58 -r1.59 *** CHANGES 18 Oct 2004 20:35:28 -0000 1.58 --- CHANGES 23 Nov 2004 17:41:50 -0000 1.59 *************** *** 10,13 **** --- 10,16 ---- * Now distributed under a 3-clause BSD-style license, see LICENSE for details + * Fixed bug #1008615: disabled the FutureWarning raised by python2.3 for + negative value in hex(). Thanks to Lorenzo Gil Sanchez for reporting. + * Applied <<trivial>> patch #1040045 submitted by John R. Lenton --typo corrections in the documentation |
From: Sebastien B. <sbi...@us...> - 2004-11-23 17:42:04
|
Update of /cvsroot/modeling/ProjectModeling/Modeling In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10011/Modeling Modified Files: __init__.py Log Message: Fixed bug #1008615: disabled the FutureWarning raised by python2.3 for negative value in hex(). Thanks to Lorenzo Gil Sanchez for reporting. Index: __init__.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/__init__.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** __init__.py 20 Jul 2004 06:21:37 -0000 1.9 --- __init__.py 23 Nov 2004 17:41:52 -0000 1.10 *************** *** 32,33 **** --- 32,38 ---- migration_warnings() + import sys + if sys.version_info >= (2, 3): + import warnings + warnings.filterwarnings("ignore", "hex\(\)/oct\(\) of negative int will return a signed string in Python 2.4 and up", FutureWarning, "Modeling.*") + del sys |
From: Sebastien B. <sbi...@us...> - 2004-10-18 20:35:38
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/doc/UserGuide In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26393/Modeling/doc/UserGuide Modified Files: DefiningaModel.tex Log Message: Applied <<trivial>> patch #1040045 submitted by John R. Lenton --typo corrections in the documentation Index: DefiningaModel.tex =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/doc/UserGuide/DefiningaModel.tex,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -d -r1.40 -r1.41 *** DefiningaModel.tex 21 Sep 2004 17:12:09 -0000 1.40 --- DefiningaModel.tex 18 Oct 2004 20:35:29 -0000 1.41 *************** *** 972,976 **** \subsubsection{AString\label{pymodel-attribute-props-string}} ! The component \class{AFloat} redefines the following defaults: \begin{longtableiv}{p{3cm}p{1.5cm}p{4cm}p{5.5cm}}{code}{Prop.}{Type}{Default}{Comment} --- 972,976 ---- \subsubsection{AString\label{pymodel-attribute-props-string}} ! The component \class{AString} redefines the following defaults: \begin{longtableiv}{p{3cm}p{1.5cm}p{4cm}p{5.5cm}}{code}{Prop.}{Type}{Default}{Comment} |
From: Sebastien B. <sbi...@us...> - 2004-10-18 20:35:37
|
Update of /cvsroot/modeling/ProjectModeling/Modeling In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26393/Modeling Modified Files: SQLExpression.py Log Message: Applied <<trivial>> patch #1040045 submitted by John R. Lenton --typo corrections in the documentation Index: SQLExpression.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/SQLExpression.py,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** SQLExpression.py 20 Jul 2004 06:21:37 -0000 1.29 --- SQLExpression.py 18 Oct 2004 20:35:28 -0000 1.30 *************** *** 415,419 **** def assembleDeleteStatementWithQualifier(self, aQualifier, tableList, whereClause): """ ! Generates the SQL INSERT statement and assigns it to self's statement() The generated statement has the following format:: --- 415,419 ---- def assembleDeleteStatementWithQualifier(self, aQualifier, tableList, whereClause): """ ! Generates the SQL DELETE statement and assigns it to self's statement() The generated statement has the following format:: |
From: Sebastien B. <sbi...@us...> - 2004-10-18 20:35:36
|
Update of /cvsroot/modeling/ProjectModeling In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26393 Modified Files: CHANGES Log Message: Applied <<trivial>> patch #1040045 submitted by John R. Lenton --typo corrections in the documentation Index: CHANGES =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/CHANGES,v retrieving revision 1.57 retrieving revision 1.58 diff -C2 -d -r1.57 -r1.58 *** CHANGES 18 Oct 2004 20:31:44 -0000 1.57 --- CHANGES 18 Oct 2004 20:35:28 -0000 1.58 *************** *** 10,13 **** --- 10,16 ---- * Now distributed under a 3-clause BSD-style license, see LICENSE for details + * Applied <<trivial>> patch #1040045 submitted by John R. Lenton --typo + corrections in the documentation + * Applied a patch contributed by Lorenzo Gil Sanchez, fixing a bug where a valid model could be rejected by mdl_generate_DB_schema.py |
From: Sebastien B. <sbi...@us...> - 2004-10-18 20:31:54
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/scripts In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25165/Modeling/scripts Modified Files: mdl_generate_DB_schema.py Log Message: Applied a patch contributed by Lorenzo Gil Sanchez, fixing a bug where a valid model could be rejected by mdl_generate_DB_schema.py cf. https://sf.net/mailarchive/forum.php?thread_id=5660203&forum_id=10674 Index: mdl_generate_DB_schema.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/scripts/mdl_generate_DB_schema.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** mdl_generate_DB_schema.py 22 Sep 2004 18:56:31 -0000 1.12 --- mdl_generate_DB_schema.py 18 Oct 2004 20:31:45 -0000 1.13 *************** *** 352,356 **** errors=MV.ModelValidationException(ignore_levels=[DEBUG,INFO,WARNING]) MV.validateModel(model, errors) ! if errors: _model_err_log=force_flag and log or err if verbose: --- 352,356 ---- errors=MV.ModelValidationException(ignore_levels=[DEBUG,INFO,WARNING]) MV.validateModel(model, errors) ! if errors.has_errors(): _model_err_log=force_flag and log or err if verbose: |