[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
r5196 - in trunk: gnue-appserver/src/classrep gnue-common/src/schema
From: |
johannes |
Subject: |
r5196 - in trunk: gnue-appserver/src/classrep gnue-common/src/schema |
Date: |
Sun, 29 Feb 2004 11:24:13 -0600 (CST) |
Author: johannes
Date: 2004-02-29 11:24:11 -0600 (Sun, 29 Feb 2004)
New Revision: 5196
Modified:
trunk/gnue-appserver/src/classrep/SchemaSupport.py
trunk/gnue-common/src/schema/GSData.py
trunk/gnue-common/src/schema/GSParser.py
trunk/gnue-common/src/schema/Objects.py
Log:
Added a data-definition section to the gsd-files, making an explicit
type-argument in value-tags obsolet.
Modified: trunk/gnue-appserver/src/classrep/SchemaSupport.py
===================================================================
--- trunk/gnue-appserver/src/classrep/SchemaSupport.py 2004-02-29 00:34:46 UTC
(rev 5195)
+++ trunk/gnue-appserver/src/classrep/SchemaSupport.py 2004-02-29 17:24:11 UTC
(rev 5196)
@@ -182,32 +182,36 @@
moddata = GSTableData (gsData)
moddata.name = 'gnue_module_dump'
moddata.tablename = 'gnue_module'
+ self.__addColumnDefinition (moddata, 'gnue_module')
modrows = GSRows (moddata)
for moduledef in modules.values ():
mProp = self.__classes ["gnue_module"].properties
row = GSRow (modrows)
- self.__buildValue (row, mProp ["gnue_id"], moduledef.gnue_id)
- self.__buildValue (row, mProp ["gnue_name"], moduledef.gnue_name)
+ self.__buildValue (row, mProp ["gnue_id"] , moduledef.gnue_id)
+ self.__buildValue (row, mProp ["gnue_name"] , moduledef.gnue_name)
self.__buildValue (row, mProp ["gnue_comment"], moduledef.gnue_comment)
# dump all gnue_class rows for the requested tables
tabledata = GSTableData (gsData)
tabledata.name = 'gnue_class_dump'
tabledata.tablename = 'gnue_class'
+ tableDef = self.__addColumnDefinition (tabledata, 'gnue_class')
tablerows = GSRows (tabledata)
# and all their properties
propdata = GSTableData (gsData)
propdata.name = 'gnue_property_dump'
propdata.tablename = 'gnue_property'
+ tableDef = self.__addColumnDefinition (propdata, 'gnue_property')
proprows = GSRows (propdata)
# and all their procedures
procdata = GSTableData (gsData)
procdata.name = 'gnue_procedure_dump'
procdata.tablename = 'gnue_procedure'
+ tableDef = self.__addColumnDefinition (procdata, 'gnue_procedure')
procrows = GSRows (procdata)
for classdef in classdefs:
@@ -216,9 +220,9 @@
# save tabledata
row = GSRow (tablerows)
- self.__buildValue (row, cProp ["gnue_id"], classdef.gnue_id)
- self.__buildValue (row, cProp ["gnue_module"], classdef.gnue_module)
- self.__buildValue (row, cProp ["gnue_name"], classdef.gnue_name)
+ self.__buildValue (row, cProp ["gnue_id"] , classdef.gnue_id)
+ self.__buildValue (row, cProp ["gnue_module"] , classdef.gnue_module)
+ self.__buildValue (row, cProp ["gnue_name"] , classdef.gnue_name)
self.__buildValue (row, cProp ["gnue_comment"], classdef.gnue_comment)
for propdef in classdef.properties.values ():
@@ -226,13 +230,13 @@
pProp = self.__classes ["gnue_property"].properties
row = GSRow (proprows)
- self.__buildValue (row, pProp ["gnue_id"], propdef.gnue_id)
- self.__buildValue (row, pProp ["gnue_module"], propdef.gnue_module)
- self.__buildValue (row, pProp ["gnue_class"], propdef.gnue_class)
- self.__buildValue (row, pProp ["gnue_name"], propdef.gnue_name)
- self.__buildValue (row, pProp ["gnue_type"], propdef.gnue_type)
- self.__buildValue (row, pProp ["gnue_length"], propdef.gnue_length)
- self.__buildValue (row, pProp ["gnue_scale"], propdef.gnue_scale)
+ self.__buildValue (row, pProp ["gnue_id"] , propdef.gnue_id)
+ self.__buildValue (row, pProp ["gnue_module"] , propdef.gnue_module)
+ self.__buildValue (row, pProp ["gnue_class"] , propdef.gnue_class)
+ self.__buildValue (row, pProp ["gnue_name"] , propdef.gnue_name)
+ self.__buildValue (row, pProp ["gnue_type"] , propdef.gnue_type)
+ self.__buildValue (row, pProp ["gnue_length"] , propdef.gnue_length)
+ self.__buildValue (row, pProp ["gnue_scale"] , propdef.gnue_scale)
self.__buildValue (row, pProp ["gnue_comment"], propdef.gnue_comment)
for procdef in classdef.procedures.values ():
@@ -255,12 +259,27 @@
def __buildValue (self, row, prop, data):
value = GSValue (row)
value.field = prop.column
- value.type = prop.dbFullType
GContent (value,
unicode (self.__nativeToString (data, prop.dbFullType), 'utf-8'))
# ---------------------------------------------------------------------------
+ # Add a column definition section to the given tabledata for classname
+ # ---------------------------------------------------------------------------
+
+ def __addColumnDefinition (self, tableData, classname):
+ tableDef = GSDefinition (tableData)
+
+ classdef = self.__classes [classname]
+ for prop in classdef.properties.values ():
+ column = GSColumn (tableDef)
+ column.field = prop.column
+ column.type = prop.dbFullType
+
+ return tableDef
+
+
+ # ---------------------------------------------------------------------------
# Convert a native python object to a string according to datatype
# ---------------------------------------------------------------------------
Modified: trunk/gnue-common/src/schema/GSData.py
===================================================================
--- trunk/gnue-common/src/schema/GSData.py 2004-02-29 00:34:46 UTC (rev
5195)
+++ trunk/gnue-common/src/schema/GSData.py 2004-02-29 17:24:11 UTC (rev
5196)
@@ -30,6 +30,9 @@
# =============================================================================
_LENGTH_SCALE = re.compile ('^\w+\s*\((\d+)[\.]{0,1}(\d*)\)\s*')
+_VALID_TYPES = ["string", "number", "boolean", "date", "time", "datetime"]
+_TRANS_TYPES = { "text": "string",
+ "timestamp": "datetime" }
# =============================================================================
@@ -190,12 +193,52 @@
+# -----------------------------------------------------------------------------
+# verify a given datatype
+# -----------------------------------------------------------------------------
+def verifyDataType (gsColumn):
+ """
+ This function checks if the @gsColumn instance has a vaild type attribute.
+ If the datatype is valid, this function creates a tuple of '(typename,
lenght,
+ scale)', otherwise an EInvalidType exception will be raised.
+ """
+ fieldType = gsColumn.type.lower ().strip ()
+ tpMatch = re.compile ('^(\w+)').match (fieldType)
+ tpList = _VALID_TYPES + _TRANS_TYPES.keys ()
+
+ # check if we know the given type
+ if tpMatch is None or not tpMatch.groups () [0] in tpList:
+ raise EInvalidType (gsColumn, fieldType)
+
+ # and eventually translate it
+ typename = tpMatch.groups () [0]
+ if _TRANS_TYPES.has_key (typename):
+ typename = _TRANS_TYPES [typename]
+
+ flength = 0
+ fscale = 0
+
+ # try to extract length and scale from fieldType
+ lsMatch = _LENGTH_SCALE.match (fieldType)
+ if lsMatch is not None:
+ (lstr, sstr) = lsMatch.groups ()
+
+ if len (lstr):
+ flength = int (lstr)
+ if len (sstr):
+ fscale = int (sstr)
+
+ return (typename, flength, fscale)
+
+
+
+
# -----------------------------------------------------------------------------
# Convert a value from a GSValue instance to a native python object
# -----------------------------------------------------------------------------
-def valueToNative (gsValue):
+def valueToNative (gsValue, gsColumn):
"""
This function takes a GSValue instance and creates a native python object
representing it's value according to it's type. If the value is an empty
@@ -209,128 +252,107 @@
gsValue.dataType = None
return None
- # if gsValue has no type information we assume it to be string
- if not hasattr (gsValue, "type"):
- gsValue.dataType = "string"
- return fieldValue
+ # if we have a gsColumn instance supplied, we use it's datatype definition
+ if gsColumn is not None:
+ gsValue.dataType = gsColumn.typename
+ gsValue.length = gsColumn.length
+ gsValue.scale = gsColumn.scale
else:
- # extract the datatype first
- ftm = re.compile ('^(\w+)').match (gsValue.type.lower ())
- if ftm is None:
- raise EInvalidType (gsValue, gsValue.type)
-
- fieldType = ftm.groups () [0]
-
- # default type is text (if no explicit type attribute is given)
- if fieldType == "text":
- fieldType = "string"
-
- if fieldType == "timestamp":
- fieldType = "datetime"
-
+ (fieldType, length, scale) = verifyDataType (gsValue)
gsValue.dataType = fieldType
+ gsValue.length = length
+ gsValue.scale = scale
- # a string type must stay in it's bounds (if known)
- if fieldType == "string":
- # if the fieldtype contains a length, we've to check it
- if _LENGTH_SCALE.match (gsValue.type) is not None:
- flen = int (_LENGTH_SCALE.match (gsValue.type).groups () [0])
+ # a string type must stay in it's bounds (if known)
+ if gsValue.dataType == "string":
+ if gsValue.length > 0 and len (fieldValue) > gsValue.length:
+ raise EOutOfRange (gsValue, fieldValue, gsValue.length)
- if len (fieldValue) > flen:
- raise EOutOfRange (gsValue, fieldValue, flen)
+ return fieldValue
- return fieldValue
+ # create a number according to length and scale
+ elif gsValue.dataType == "number":
+ value = fieldValue.strip ()
+ if gsValue.length or gsValue.scale:
+ vmatch = re.compile ('^([+-]{0,1})(\d+)[\.]{0,1}(\d*)$').match (value)
+ if vmatch is None:
+ raise EInvalidNumber (gsValue, value, gsValue.length, gsValue.scale)
- # create a number according to length and scale
- elif fieldType == "number":
- value = fieldValue.strip ()
+ sign = vmatch.groups () [0]
+ pre = vmatch.groups () [1]
+ frac = vmatch.groups () [2]
- if _LENGTH_SCALE.match (gsValue.type) is not None:
- fmatch = _LENGTH_SCALE.match (gsValue.type)
- (fml, fms) = fmatch.groups ()
+ if len (pre) > (gsValue.length - gsValue.scale) or \
+ len (frac) > gsValue.scale:
+ raise EOutOfRange (gsValue, value, gsValue.length, gsValue.scale)
- flength = int (fml)
- fscale = 0
- if len (fms):
- fscale = int (fms)
+ if len (frac):
+ return float ("%s%s.%s" % (sign, pre, frac))
- vmatch = re.compile ('^([+-]{0,1})(\d+)[\.]{0,1}(\d*)$').match (value)
- if vmatch is None:
- raise EInvalidNumber (gsValue, value, flength, fscale)
+ else:
+ return int ("%s%s" % (sign, pre))
- sign = vmatch.groups () [0]
- pre = vmatch.groups () [1]
- frac = vmatch.groups () [2]
+ # we know nothing about precision
+ else:
+ if "." in value:
+ return float (value)
- if len (pre) > (flength-fscale) or len (frac) > fscale:
- raise EOutOfRange (gsValue, value, flength, fscale)
-
- if len (frac):
- return float ("%s%s.%s" % (sign, pre, frac))
-
- else:
- return int ("%s%s" % (sign, pre))
-
- # we know nothing about precision
else:
- if "." in value:
- return float (value)
- else:
- return int (value)
+ return int (value)
- # booleans must be 'TRUE' or 'FALSE', otherwise they're "None"
- elif fieldType == "boolean":
- bool = fieldValue.upper ().strip ()
+ # booleans must be 'TRUE' or 'FALSE', otherwise they're "None"
+ elif gsValue.dataType == "boolean":
+ bool = fieldValue.upper ().strip ()
- if bool in ["TRUE", "FALSE"]:
- return bool == "TRUE"
- else:
- raise EInvalidBoolean (gsValue, fieldValue)
+ if bool in ["TRUE", "FALSE"]:
+ return bool == "TRUE"
+ else:
+ raise EInvalidBoolean (gsValue, fieldValue)
- # Dates must conform with the ISO spec: YYYY-MM-DD
- elif fieldType == "date":
- try:
- return mx.DateTime.ISO.ParseDate (fieldValue.strip ())
+ # Dates must conform with the ISO spec: YYYY-MM-DD
+ elif gsValue.dataType == "date":
+ try:
+ return mx.DateTime.ISO.ParseDate (fieldValue.strip ())
- except ValueError:
- raise EInvalidDate (gsValue, fieldValue)
+ except ValueError:
+ raise EInvalidDate (gsValue, fieldValue)
- except:
- raise
+ except:
+ raise
- # Times must conform with the ISO spec: HH:[MM[:SS[.ss]]]
- elif fieldType == "time":
- try:
- return mx.DateTime.ISO.ParseTime (fieldValue.strip ())
+ # Times must conform with the ISO spec: HH:[MM[:SS[.ss]]]
+ elif gsValue.dataType == "time":
+ try:
+ return mx.DateTime.ISO.ParseTime (fieldValue.strip ())
- except ValueError:
- raise EInvalidTime (gsValue, fieldValue)
+ except ValueError:
+ raise EInvalidTime (gsValue, fieldValue)
- except:
- raise
+ except:
+ raise
- # DateTime values must conform with the ISO spec: YYYY-MM-DD HH:MM:SS.ss
- elif fieldType == "datetime":
- try:
- return mx.DateTime.ISO.ParseDateTime (fieldValue.strip ())
+ # DateTime values must conform with the ISO spec: YYYY-MM-DD HH:MM:SS.ss
+ elif gsValue.dataType == "datetime":
+ try:
+ return mx.DateTime.ISO.ParseDateTime (fieldValue.strip ())
- except ValueError:
- raise EInvalidDateTime (gsValue, fieldValue)
+ except ValueError:
+ raise EInvalidDateTime (gsValue, fieldValue)
- except:
- raise
+ except:
+ raise
- # unhandled types
- else:
- raise EInvalidType (gsValue, gsValue.type)
+ # unhandled types
+ else:
+ raise EInvalidType (gsValue, gsValue.dataType)
Modified: trunk/gnue-common/src/schema/GSParser.py
===================================================================
--- trunk/gnue-common/src/schema/GSParser.py 2004-02-29 00:34:46 UTC (rev
5195)
+++ trunk/gnue-common/src/schema/GSParser.py 2004-02-29 17:24:11 UTC (rev
5196)
@@ -235,7 +235,23 @@
'Typecast': GTypecast.name } },
'ParentTags': ('data',) },
+ 'definition': {
+ 'BaseClass': Objects.GSDefinition,
+ 'SingleInstance': True,
+ 'ParentTags': ('tabledata',) },
+ 'column': {
+ 'BaseClass': Objects.GSColumn,
+ 'Attributes': {
+ 'field': {
+ 'Required': True,
+ 'Typecast': GTypecast.name },
+ 'type': {
+ 'Required': True,
+ 'Typecast': GTypecast.name }
+ },
+ 'ParentTags': ('definition',)},
+
'rows': {
'BaseClass': Objects.GSRows,
'SingleInstance': 1,
Modified: trunk/gnue-common/src/schema/Objects.py
===================================================================
--- trunk/gnue-common/src/schema/Objects.py 2004-02-29 00:34:46 UTC (rev
5195)
+++ trunk/gnue-common/src/schema/Objects.py 2004-02-29 17:24:11 UTC (rev
5196)
@@ -30,8 +30,9 @@
from gnue.common.definitions.GObjects import GObj
from gnue.common.definitions.GRootObj import GRootObj
-from gnue.common.schema.GSData import valueToNative
+from gnue.common.schema.GSData import verifyDataType, valueToNative
import GSParser
+import types
class EFoundErrors (Exception):
def __init__ (self):
@@ -130,17 +131,35 @@
def __init__(self, parent):
GSObject.__init__(self, parent, type='GSRow')
+# =============================================================================
+# Field-Values
+# =============================================================================
class GSValue(GSObject):
-
+ """
+ This class implements a single data value of a row-collection. On
+ Phase-I-init the values' datatype is determined - either by a matching
+ column-definition, or by a direct type-argument - and a native python object
+ is created for it.
+ """
def __init__(self, parent):
GSObject.__init__(self, parent, type='GSValue')
self.dataType = None
+ self.lenght = None
+ self.scale = None
+ self.value = None
+
self._inits.append (self._validate)
+
def _validate (self):
+ if hasattr (self, "field"):
+ column = self._findColumn (self.field)
+ else:
+ column = self._findColumn (self._getIndex ())
+
try:
- self.value = valueToNative (self)
+ self.value = valueToNative (self, column)
except Exception, message:
self.value = None
@@ -154,7 +173,104 @@
parent = parent._parent
+ # ---------------------------------------------------------------------------
+ # Find a column definition either by it's index or by it's fieldname
+ # ---------------------------------------------------------------------------
+ def _findColumn (self, fieldSpec):
+ """
+ This function searches for a given field in a GSTableData's column
+ definition. If @fieldSpec is an integer this number will be used as index
+ to the column-definition collection. Ohterwise @fieldSpec is treated as the
+ field name of the column to be returned.
+ """
+ tableData = self.findParentOfType ('GSTableData')
+ if tableData is not None:
+ colDefs = tableData.findChildOfType ('GSDefinition')
+ if colDefs is not None:
+ return colDefs.getColumn (fieldSpec)
+
+ return None
+
+
+ # ---------------------------------------------------------------------------
+ # get the index of an instance in it's parent's child-collection
+ # ---------------------------------------------------------------------------
+
+ def _getIndex (self):
+ """
+ This function get's the objects index in it's parents child-collection
+ """
+ if self._parent is not None:
+ for index in range (0, len (self._parent._children)):
+ if self._parent._children [index] == self:
+ return index
+
+ raise Exception (_("GSD-Error: can't find myself in the XML tree?!"))
+
+
+
class GSDescription(GSObject):
def __init__(self, parent):
GSObject.__init__(self, parent, type='GSDescription')
+
+
+
+# =============================================================================
+# Column definitions
+# =============================================================================
+
+class GSDefinition (GSObject):
+ """
+ GSDefinition holds a collection of column definition instances. In
+ Phase-I-init a dictionary with all columns is created as well as a sequence
+ of columns (for index-based access).
+ """
+ def __init__ (self, parent):
+ GSObject.__init__ (self, parent, type = "GSDefinition")
+ self.columns = {}
+ self.collist = []
+ self._inits.append (self.__buildColumnDict)
+
+ def __buildColumnDict (self):
+ self.collist = self.findChildrenOfType ('GSColumn')
+ self.columns = {}
+
+ for col in self.collist:
+ self.columns [col.field] = col
+
+
+ def getColumn (self, fieldSpec):
+ """
+ If @fieldSpec is an integer type '@fieldSpec' is treated as an index to the
+ columns-sequence, otherwise @fieldSpec is used as key into the
+ columns-dictionary.
+ """
+ if isinstance (fieldSpec, types.IntType) and fieldSpec < len
(self.collist):
+ return self.collist [fieldSpec]
+
+ elif self.columns.has_key (fieldSpec):
+ return self.columns [fieldSpec]
+
+ return None
+
+
+# =============================================================================
+# Column definitions
+# =============================================================================
+
+class GSColumn (GSObject):
+ """
+ This class implements a column definition. Phase-I-init verifies the datatype
+ of the column definition and set's the properties 'typename', 'length' and
+ 'scale'.
+ """
+ def __init__ (self, parent):
+ GSObject.__init__ (self, parent, type = "GSColumn")
+ self.typename = None
+ self.length = None
+ self.scale = None
+ self._inits.append (self._validate)
+
+ def _validate (self):
+ (self.typename, self.length, self.scale) = verifyDataType (self)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- r5196 - in trunk: gnue-appserver/src/classrep gnue-common/src/schema,
johannes <=