[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
r5753 - in trunk: gnue-appserver/samples gnue-appserver/src gnue-appserv
From: |
johannes |
Subject: |
r5753 - in trunk: gnue-appserver/samples gnue-appserver/src gnue-appserver/src/classrep gnue-appserver/src/language gnue-common/src/datasources/drivers/appserver/appserver |
Date: |
Wed, 21 Apr 2004 09:23:52 -0500 (CDT) |
Author: johannes
Date: 2004-04-21 09:23:50 -0500 (Wed, 21 Apr 2004)
New Revision: 5753
Modified:
trunk/gnue-appserver/samples/sample.gfd
trunk/gnue-appserver/samples/sample.gsd
trunk/gnue-appserver/src/classrep/Class.py
trunk/gnue-appserver/src/classrep/Property.py
trunk/gnue-appserver/src/data.py
trunk/gnue-appserver/src/geasInstance.py
trunk/gnue-appserver/src/geasSession.py
trunk/gnue-appserver/src/language/Object.py
trunk/gnue-common/src/datasources/drivers/appserver/appserver/RecordSet.py
Log:
Added calculated fields to appserver
Modified: trunk/gnue-appserver/samples/sample.gfd
===================================================================
--- trunk/gnue-appserver/samples/sample.gfd 2004-04-21 10:55:10 UTC (rev
5752)
+++ trunk/gnue-appserver/samples/sample.gfd 2004-04-21 14:23:50 UTC (rev
5753)
@@ -9,6 +9,9 @@
retval = dtsPerson.call("address_show", {})
if retval is not None:
print "retval =", retval
+
+ newret = dtsPerson.call ("address_test", {})
+ print "New=", repr (newret)
]]></trigger>
<logic>
<block name="blkPerson" datasource="dtsPerson">
@@ -26,6 +29,8 @@
<field name="inpMeetTime" field="address_meettime" typecast="date"/>
<field name="inpLastMeeting" field="address_lastmeeting"
typecast="date"/>
<field name="inpHuman" field="address_human" max_length="1"/>
+ <field name="inpNextMeeting" field="address_nextmeeting"
+ typecast="date" readonly="Y"/>
</block>
<block name="blkCountry" datasource="dtsMCountry" rows="10">
<field name="inpCCode" field="address_code" max_length="2"/>
@@ -55,8 +60,10 @@
Char:y="9" text="Meeting Time:"/>
<label name="lblLastMeeting" Char:height="1" Char:width="13" Char:x="1"
Char:y="10" text="Last Meeting:"/>
+ <label name="lblNextMeeting" Char:height="1" Char:width="13" Char:x="1"
+ Char:y="11" text="Next Meeting:"/>
<label name="lblHuman" Char:height="1" Char:width="6" Char:x="1"
- Char:y="11" text="Human:"/>
+ Char:y="12" text="Human:"/>
<entry name="entName" Char:height="1" Char:width="35" Char:x="14"
Char:y="1" block="blkPerson" field="inpName"/>
<entry name="entStreet" Char:height="1" Char:width="35" Char:x="14"
@@ -84,8 +91,11 @@
<entry name="entLastMeeting" Char:height="1" Char:width="25" Char:x="14"
Char:y="10" block="blkPerson" field="inpLastMeeting"
displaymask="%x %X" inputmask="%x %X"/>
+ <entry name="entNextMeeting" Char:height="1" Char:width="25" Char:x="14"
+ Char:y="11" block="blkPerson" field="inpNextMeeting"
+ displaymask="%x %X" inputmask="%x %X" navigable="N"/>
<entry name="entHuman" Char:height="1" Char:width="2" Char:x="14"
- Char:y="11" block="blkPerson" field="inpHuman" style="checkbox"/>
+ Char:y="12" block="blkPerson" field="inpHuman" style="checkbox"/>
<button name="Call" Char:height="1" Char:width="25" Char:x="14"
Char:y="13" label="Show record">
<trigger src="showRecord" name="Trigger1" type="ON-ACTION"/>
Modified: trunk/gnue-appserver/samples/sample.gsd
===================================================================
--- trunk/gnue-appserver/samples/sample.gsd 2004-04-21 10:55:10 UTC (rev
5752)
+++ trunk/gnue-appserver/samples/sample.gsd 2004-04-21 14:23:50 UTC (rev
5753)
@@ -304,6 +304,22 @@
</value>
<value field="gnue_comment">Simple procedure to test
Appserver</value>
</row>
+ <row>
+ <value field="gnue_id">0000000000000000000000000000101G</value>
+ <value field="gnue_module">00000000000000000000000000001000</value>
+ <value field="gnue_class">00000000000000000000000000001010</value>
+ <value field="gnue_name">getnextmeeting</value>
+ <value field="gnue_language">python</value>
+ <value field="gnue_code">
+import mx.DateTime
+last = self.address_lastmeeting
+tm = self.address_meettime
+next = last + mx.DateTime.RelativeDateTime (days=+21, hour = tm.hour, minute =
tm.minute, second = tm.second)
+return next
+ </value>
+ <value field="gnue_comment">Calculate the next meeting date</value>
+ <value field="gnue_type">datetime</value>
+ </row>
</rows>
</tabledata>
<tabledata name="sample_accounts" tablename="gnue_useraccess">
Modified: trunk/gnue-appserver/src/classrep/Class.py
===================================================================
--- trunk/gnue-appserver/src/classrep/Class.py 2004-04-21 10:55:10 UTC (rev
5752)
+++ trunk/gnue-appserver/src/classrep/Class.py 2004-04-21 14:23:50 UTC (rev
5753)
@@ -238,6 +238,9 @@
gDebug (2, "%s.%s: %s: %s" % (self.fullName, p.fullName,
sys.exc_info () [0], sys.exc_info () [1]))
+ self.properties.loadCalculated (self.procedures)
+
+
# ---------------------------------------------------------------------------
# Replace references
# ---------------------------------------------------------------------------
Modified: trunk/gnue-appserver/src/classrep/Property.py
===================================================================
--- trunk/gnue-appserver/src/classrep/Property.py 2004-04-21 10:55:10 UTC
(rev 5752)
+++ trunk/gnue-appserver/src/classrep/Property.py 2004-04-21 14:23:50 UTC
(rev 5753)
@@ -118,31 +118,42 @@
return PropertyValidationError (self.__class.fullName, item.fullName,
verr.message)
+ # ---------------------------------------------------------------------------
+ # update property dictionary with calculated properties from procedure dict.
+ # ---------------------------------------------------------------------------
+
+ def loadCalculated (self, procDict):
+ """
+ This function merges all 'calculated fields' from the given procedure
+ dictionary into the property dictionary
+ """
+
+ for proc in procDict.values ():
+ if proc.isCalculated:
+ newProp = CalculatedProperty (proc)
+ self._items [newProp.fullName] = newProp
+
+
# =============================================================================
-# A Business Object Property
+# Base class for properties
# =============================================================================
-class Property (BaseObject):
+class BaseProperty:
+
_BASE_TYPES = ['boolean', 'date', 'datetime', 'number', 'string', 'time']
_ID_TYPE = "string"
_ID_LENGTH = 32
_ID_SCALE = 0
# ---------------------------------------------------------------------------
- # Construct a new property from module, class and business object
+ # Create the proper type information
# ---------------------------------------------------------------------------
- def __init__ (self, session, module, object, pDefs = None):
- BaseObject.__init__ (self, session, 'gnue_property', object, pDefs)
- self.module = module
- self.fullName = createName (self.module.gnue_name, self.gnue_name)
- self.column = self.fullName
-
- self.isValidated = False
- self.isReference = False
- self.referencedClass = None
-
- # build appserver specific type information
+ def _updateTypeInfo (self):
+ """
+ This function updates the properties 'fullType', 'dbType', 'dbLength' and
+ 'dbScale' based on 'gnue_type', 'gnue_length' and 'gnue_scale'
+ """
if self.gnue_type in ["string", "number"]:
if self.gnue_type == "number" and self.gnue_length and self.gnue_scale:
self.fullType = "%s(%d.%d)" % (self.gnue_type, self.gnue_length,
@@ -177,7 +188,32 @@
self.dbFullType = self.dbType
+# =============================================================================
+# A Business Object Property
+# =============================================================================
+class Property (BaseProperty, BaseObject):
+
# ---------------------------------------------------------------------------
+ # Construct a new property from module, class and business object
+ # ---------------------------------------------------------------------------
+ def __init__ (self, session, module, object, pDefs = None):
+ BaseObject.__init__ (self, session, 'gnue_property', object, pDefs)
+
+ self.module = module
+ self.fullName = createName (self.module.gnue_name, self.gnue_name)
+ self.column = self.fullName
+
+ self.isValidated = False
+ self.isReference = False
+ self.referencedClass = None
+ self.isCalculated = False
+ self.procedure = None
+
+ # build appserver specific type information
+ self._updateTypeInfo ()
+
+
+ # ---------------------------------------------------------------------------
# Validate a given property definition
# ---------------------------------------------------------------------------
def validate (self):
@@ -194,3 +230,39 @@
self.isValidated = True
+# =============================================================================
+# Class for calculated properties
+# =============================================================================
+
+class CalculatedProperty (BaseProperty):
+
+ # ---------------------------------------------------------------------------
+ # Constructor
+ # ---------------------------------------------------------------------------
+
+ def __init__ (self, aProcedure):
+ self.classname = '<calculated>'
+ self._session = aProcedure._session
+
+ self.module = aProcedure.module
+ self.fullName = aProcedure.calcFullName
+ self.column = None
+
+ self.isValidated = True
+ self.isReference = False
+ self.referencedClass = None
+ self.isCalculated = True
+ self.procedure = aProcedure
+
+ self.gnue_type = aProcedure.gnue_type
+ self.gnue_length = aProcedure.gnue_length
+ self.gnue_scale = aProcedure.gnue_scale
+
+ self._updateTypeInfo ()
+
+
+ # ---------------------------------------------------------------------------
+ # Validate a calculated property
+ # ---------------------------------------------------------------------------
+ def validate (self):
+ pass
Modified: trunk/gnue-appserver/src/data.py
===================================================================
--- trunk/gnue-appserver/src/data.py 2004-04-21 10:55:10 UTC (rev 5752)
+++ trunk/gnue-appserver/src/data.py 2004-04-21 14:23:50 UTC (rev 5753)
@@ -473,7 +473,8 @@
checktype (table, UnicodeType)
checktype (row, UnicodeType)
checktype (fields, ListType)
- for fields_element in fields: checktype (fields_element, UnicodeType)
+ for fields_element in fields:
+ checktype (fields_element, UnicodeType)
uncachedFields = []
for field in fields:
Modified: trunk/gnue-appserver/src/geasInstance.py
===================================================================
--- trunk/gnue-appserver/src/geasInstance.py 2004-04-21 10:55:10 UTC (rev
5752)
+++ trunk/gnue-appserver/src/geasInstance.py 2004-04-21 14:23:50 UTC (rev
5753)
@@ -27,6 +27,7 @@
import mx.DateTime.ISO
from gnue.appserver.language import Object, Session
from gnue.common.logic.language import getLanguageAdapter
+from gnue.appserver.classrep import Namespace
# =============================================================================
# Exceptions
@@ -63,6 +64,11 @@
"resulttype": type (result).__name__}
gException.__init__ (self, msg)
+class PropertyAccessError (gException):
+ def __init__ (self, classname, propertyname):
+ msg = u_("Calculated field '%(property)s' is a read-only field") \
+ % {"property": "%s.%s" % (classname, propertyname)}
+ gException.__init__ (self, msg)
# =============================================================================
# Instance class
@@ -196,9 +202,11 @@
record = self.__connection.findRecord (classdef.table, key, [])
propertydef = classdef.properties [elements [-1]]
+ if propertydef.isCalculated:
+ value = self.call (propertydef.procedure, None)
+ else:
+ value = record.getField (propertydef.column)
- value = record.getField (propertydef.column)
-
return self.__convert (value, propertydef, DbValueError)
# ---------------------------------------------------------------------------
@@ -206,7 +214,6 @@
# ---------------------------------------------------------------------------
def get (self, propertylist):
-
return [self.__getValue (aProperty) for aProperty in propertylist]
# ---------------------------------------------------------------------------
@@ -216,6 +223,8 @@
def __putValue (self, propertyname, value):
propertydef = self.__classdef.properties [propertyname]
+ if propertydef.isCalculated:
+ raise PropertyAccessError, (self.__classdef.fullName, propertyname)
__value = self.__convert (value, propertydef, PropertyValueError)
@@ -234,7 +243,7 @@
# Call a procedure
# ---------------------------------------------------------------------------
- def call (self, procedurename, params):
+ def call (self, proceduredef, params):
# TODO: This should run in a separate process so that a segfaulting
# procedure doesn't kill appserver.
@@ -247,9 +256,6 @@
obj = Object.Object (sess, self.__classdef.fullName,
self.__getValue (u'gnue_id'))
- # fetch the procedure definition
- proceduredef = self.__classdef.procedures [procedurename]
-
# check the parameters
if params is not None:
for parameter in params.keys ():
@@ -264,7 +270,7 @@
cx = engine.createNewContext ()
# describe the context
- cx.shortname = '%s.%s' % (self.__classdef.fullName, procedurename)
+ cx.shortname = '%s.%s' % (self.__classdef.fullName,
proceduredef.fullName)
cx.description = proceduredef.gnue_comment
# the object itself
@@ -304,8 +310,9 @@
is raised.
"""
for prop in self.__classdef.properties.values ():
- if prop.gnue_nullable is not None and not prop.gnue_nullable:
- value = self.__record.getField (prop.column)
- if value is None:
- raise PropertyValueError (prop.fullName, None)
+ if not prop.isCalculated:
+ if prop.gnue_nullable is not None and not prop.gnue_nullable:
+ value = self.__record.getField (prop.column)
+ if value is None:
+ raise PropertyValueError (prop.fullName, None)
Modified: trunk/gnue-appserver/src/geasSession.py
===================================================================
--- trunk/gnue-appserver/src/geasSession.py 2004-04-21 10:55:10 UTC (rev
5752)
+++ trunk/gnue-appserver/src/geasSession.py 2004-04-21 14:23:50 UTC (rev
5753)
@@ -71,11 +71,16 @@
return self.sm.classes [classname]
+ def __getProcdef (self, classdef, procedurename):
+ # add access control to procedures here
+ return classdef.procedures [procedurename]
+
# ---------------------------------------------------------------------------
# Get a field name from a property name, resolving references
# ---------------------------------------------------------------------------
- def __getFieldname (self, classdef, propertyname, contentdict, add):
+ def __getFieldname (self, classdef, propertyname, contentdict, add,
+ skipCalculated = True):
elements = string.split (propertyname, '.')
@@ -102,6 +107,8 @@
# the real (final) propertydef
p = c.properties [elements [-1]]
+ if skipCalculated and p.isCalculated:
+ return
# add new field to fieldlist
if add:
@@ -243,9 +250,14 @@
table = classdef.table
# Only query the main table here. geasInstance.get will do the rest.
- fieldlist = [classdef.properties [string.split (p, '.') [0]].column
- for p in propertylist]
+ fieldlist = []
+ for p in propertylist:
+ pdef = classdef.properties [string.split (p, '.') [0]]
+ if not pdef.isCalculated and not pdef.column in fieldlist:
+ fieldlist.append (pdef.column)
+
record = self.__connection.findRecord (table, object_id, fieldlist)
+
return geasInstance.geasInstance (self, self.__connection, record,
classdef)
@@ -322,10 +334,11 @@
def call (self, classname, obj_id_list, procedurename, parameters):
classdef = self.__getClassdef (classname)
+ procdef = self.__getProcdef (classdef, procedurename)
result = []
for object_id in obj_id_list:
instance = self.__findInstance (classdef, object_id, [])
- result.append (instance.call (procedurename, parameters))
+ result.append (instance.call (procdef, parameters))
return result
Modified: trunk/gnue-appserver/src/language/Object.py
===================================================================
--- trunk/gnue-appserver/src/language/Object.py 2004-04-21 10:55:10 UTC (rev
5752)
+++ trunk/gnue-appserver/src/language/Object.py 2004-04-21 14:23:50 UTC (rev
5753)
@@ -79,14 +79,9 @@
sm = self.__session.getSessionManager ()
sid = self.__session.getSessionId ()
- try:
- res = sm.load (sid, self.__class, [self.objectId, ''], [name])
- (value, datatype) = (res [0][0], res [1][0])
+ res = sm.load (sid, self.__class, [self.objectId, ''], [name])
+ (value, datatype) = (res [0][0], res [1][0])
- except:
- # TODO: use a more specific exception
- return None
-
# Convert reference fields to object references
if '_' in datatype:
return Object (self.__session, datatype, value)
Modified:
trunk/gnue-common/src/datasources/drivers/appserver/appserver/RecordSet.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/appserver/appserver/RecordSet.py
2004-04-21 10:55:10 UTC (rev 5752)
+++ trunk/gnue-common/src/datasources/drivers/appserver/appserver/RecordSet.py
2004-04-21 14:23:50 UTC (rev 5753)
@@ -64,7 +64,9 @@
[None],
fields.keys (),
[fields.values ()]) [0]
+ self._updateRecord ()
+
# ---------------------------------------------------------------------------
# Update
# ---------------------------------------------------------------------------
@@ -76,8 +78,22 @@
[self._fields ['gnue_id']],
fields.keys (),
[fields.values ()])
+ self._updateRecord ()
# ---------------------------------------------------------------------------
+ # Update all fields of a record after update/inserts
+ # ---------------------------------------------------------------------------
+
+ def _updateRecord (self):
+ propertylist = self._fields.keys ()
+ res = self.__sm.load (self.__session_id, self.__classname,
+ [self._fields ['gnue_id']], propertylist)
+
+ for ix in range (0, len (propertylist)):
+ self._fields [propertylist [ix]] = res [0][ix]
+
+
+ # ---------------------------------------------------------------------------
# Call a server-side function
# ---------------------------------------------------------------------------
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- r5753 - in trunk: gnue-appserver/samples gnue-appserver/src gnue-appserver/src/classrep gnue-appserver/src/language gnue-common/src/datasources/drivers/appserver/appserver,
johannes <=