[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
r6454 - in trunk: gnue-appserver/grpc gnue-appserver/share gnue-appserve
From: |
johannes |
Subject: |
r6454 - in trunk: gnue-appserver/grpc gnue-appserver/share gnue-appserver/src gnue-appserver/src/gcd gnue-common/src/datasources/drivers/appserver/appserver |
Date: |
Tue, 5 Oct 2004 03:14:06 -0500 (CDT) |
Author: johannes
Date: 2004-10-05 03:14:04 -0500 (Tue, 05 Oct 2004)
New Revision: 6454
Added:
trunk/gnue-appserver/src/geasFilter.py
Modified:
trunk/gnue-appserver/grpc/appserver.grpc
trunk/gnue-appserver/share/gnue.gsd
trunk/gnue-appserver/src/gcd/GCParser.py
trunk/gnue-appserver/src/gcd/readgcd.py
trunk/gnue-appserver/src/geasInstance.py
trunk/gnue-appserver/src/geasRpcServer.py
trunk/gnue-appserver/src/geasSession.py
trunk/gnue-appserver/src/geasSessionManager.py
trunk/gnue-common/src/datasources/drivers/appserver/appserver/Connection.py
Log:
*) Added support for arbitrary filters to appserver
*) Added getFilters () RPC call to appserver
*) gnue-readgcd now supports definition of indices
Modified: trunk/gnue-appserver/grpc/appserver.grpc
===================================================================
--- trunk/gnue-appserver/grpc/appserver.grpc 2004-10-04 17:03:32 UTC (rev
6453)
+++ trunk/gnue-appserver/grpc/appserver.grpc 2004-10-05 08:14:04 UTC (rev
6454)
@@ -56,5 +56,8 @@
<argument name="procedurename" type="string"/>
<argument name="parameters" type="stringlist"/>
</method>
+ <method name="getFilters" return="struct">
+ <argument name="language" type="string"/>
+ </method>
</service>
</gnurpc>
Modified: trunk/gnue-appserver/share/gnue.gsd
===================================================================
--- trunk/gnue-appserver/share/gnue.gsd 2004-10-04 17:03:32 UTC (rev 6453)
+++ trunk/gnue-appserver/share/gnue.gsd 2004-10-05 08:14:04 UTC (rev 6454)
@@ -65,8 +65,8 @@
description="Module that defined this class" />
<field name="gnue_name" type="string" length="35" nullable="N"
description="Classname without modulename" />
- <field name="gnue_filter" type="string" length="35"
- description="Master-Class of the class" />
+ <field name="gnue_filter" type="string" length="32"
+ description="Filter-Class of the class" />
</fields>
<indexes/>
<constraints>
@@ -74,6 +74,10 @@
<constraintfield name="gnue_module"/>
<constraintref name="gnue_id" table="gnue_module"/>
</constraint>
+ <constraint name="fk_gnue_class_gnue_filter" type="foreignkey">
+ <constraintfield name="gnue_filter"/>
+ <constraintref name="gnue_id" table="gnue_class"/>
+ </constraint>
</constraints>
<primarykey name="pk_gnue_class">
<pkfield name="gnue_id"/>
@@ -264,49 +268,6 @@
</primarykey>
</table>
- <!-- ============================================================ -->
- <!-- Company -->
- <!-- ============================================================ -->
- <table name="gnue_company">
- <fields>
- <field name="gnue_id" type="string" length="32" nullable="N"
- description="Object ID"/>
- <field name="gnue_code" type="string" length="8" nullable="N"
- description="Code of the company"/>
- <field name="gnue_name" type="string" length="35" nullable="N"
- description="Name of the company"/>
- </fields>
- <indexes/>
- <constraints/>
- <primarykey name="pk_gnue_company">
- <pkfield name="gnue_id"/>
- </primarykey>
- </table>
-
- <!-- ============================================================ -->
- <!-- Year -->
- <!-- ============================================================ -->
- <table name="gnue_year">
- <fields>
- <field name="gnue_id" type="string" length="32" nullable="N"
- description="Object ID"/>
- <field name="gnue_company" type="string" length="32" nullable="N"
- description="Company this year is assigned to"/>
- <field name="gnue_code" type="string" length="8" nullable="N"
- description="Code of the year"/>
- </fields>
- <indexes/>
- <constraints>
- <constraint name="fk_gnue_year_gnue_company" type="foreignkey">
- <constraintfield name="gnue_company"/>
- <constraintref name="gnue_id" table="gnue_company"/>
- </constraint>
- </constraints>
- <primarykey name="pk_gnue_year">
- <pkfield name="gnue_id"/>
- </primarykey>
- </table>
-
</tables>
<data>
@@ -383,19 +344,6 @@
<value field="gnue_module">00000000000000000000000000000000</value>
<value field="gnue_name">message</value>
</row>
- <row>
- <value field="gnue_comment">GNU Enterprise Company</value>
- <value field="gnue_id">00000000000000000000000000000090</value>
- <value field="gnue_module">00000000000000000000000000000000</value>
- <value field="gnue_name">company</value>
- </row>
- <row>
- <value field="gnue_comment">GNU Enterprise Year</value>
- <value field="gnue_id">000000000000000000000000000000A0</value>
- <value field="gnue_module">00000000000000000000000000000000</value>
- <value field="gnue_name">year</value>
- <value field="gnue_filter">gnue_company</value>
- </row>
</rows>
</tabledata>
@@ -495,11 +443,10 @@
<value field="gnue_module">00000000000000000000000000000000</value>
<value field="gnue_class">00000000000000000000000000000020</value>
<value field="gnue_id">00000000000000000000000000000025</value>
- <value field="gnue_comment">Master-Class of the class</value>
- <value field="gnue_length">35</value>
+ <value field="gnue_comment">Filter-Class of the class</value>
<value field="gnue_name">filter</value>
<value field="gnue_nullable">TRUE</value>
- <value field="gnue_type">string</value>
+ <value field="gnue_type">gnue_class</value>
</row>
<!-- ============================================================ -->
@@ -915,70 +862,6 @@
<value field="gnue_nullable">TRUE</value>
</row>
- <!-- ============================================================ -->
- <!-- Properties of gnue_company -->
- <!-- ============================================================ -->
- <row>
- <value field="gnue_module">00000000000000000000000000000000</value>
- <value field="gnue_class">00000000000000000000000000000090</value>
- <value field="gnue_id">00000000000000000000000000000091</value>
- <value field="gnue_comment">Object ID</value>
- <value field="gnue_name">id</value>
- <value field="gnue_nullable">FALSE</value>
- <value field="gnue_type">id</value>
- </row>
- <row>
- <value field="gnue_module">00000000000000000000000000000000</value>
- <value field="gnue_class">00000000000000000000000000000090</value>
- <value field="gnue_id">00000000000000000000000000000092</value>
- <value field="gnue_comment">Code of the company</value>
- <value field="gnue_name">code</value>
- <value field="gnue_nullable">FALSE</value>
- <value field="gnue_type">string</value>
- <value field="gnue_length">8</value>
- </row>
- <row>
- <value field="gnue_module">00000000000000000000000000000000</value>
- <value field="gnue_class">00000000000000000000000000000090</value>
- <value field="gnue_id">00000000000000000000000000000093</value>
- <value field="gnue_comment">Name of the company</value>
- <value field="gnue_name">name</value>
- <value field="gnue_nullable">FALSE</value>
- <value field="gnue_type">string</value>
- <value field="gnue_length">35</value>
- </row>
-
- <!-- ============================================================ -->
- <!-- Properties of gnue_year -->
- <!-- ============================================================ -->
- <row>
- <value field="gnue_module">00000000000000000000000000000000</value>
- <value field="gnue_class">000000000000000000000000000000A0</value>
- <value field="gnue_id">000000000000000000000000000000A1</value>
- <value field="gnue_comment">Object ID</value>
- <value field="gnue_name">id</value>
- <value field="gnue_nullable">FALSE</value>
- <value field="gnue_type">id</value>
- </row>
- <row>
- <value field="gnue_module">00000000000000000000000000000000</value>
- <value field="gnue_class">000000000000000000000000000000A0</value>
- <value field="gnue_id">000000000000000000000000000000A2</value>
- <value field="gnue_comment">Code of the year</value>
- <value field="gnue_name">code</value>
- <value field="gnue_nullable">FALSE</value>
- <value field="gnue_type">string</value>
- <value field="gnue_length">8</value>
- </row>
- <row>
- <value field="gnue_module">00000000000000000000000000000000</value>
- <value field="gnue_class">000000000000000000000000000000A0</value>
- <value field="gnue_id">000000000000000000000000000000A3</value>
- <value field="gnue_comment">Company this year is assigned to</value>
- <value field="gnue_name">company</value>
- <value field="gnue_nullable">FALSE</value>
- <value field="gnue_type">gnue_company</value>
- </row>
</rows>
</tabledata>
Modified: trunk/gnue-appserver/src/gcd/GCParser.py
===================================================================
--- trunk/gnue-appserver/src/gcd/GCParser.py 2004-10-04 17:03:32 UTC (rev
6453)
+++ trunk/gnue-appserver/src/gcd/GCParser.py 2004-10-05 08:14:04 UTC (rev
6454)
@@ -190,6 +190,30 @@
},
'ParentTags': ('procedure',)
},
+
+ 'index': {
+ 'BaseClass': GCIndex,
+ 'Attributes': {
+ 'name': {
+ 'Required': True,
+ 'Unique' : True,
+ 'Typecase': GTypecast.name},
+ 'unique': {
+ 'Typecast': GTypecast.boolean,
+ 'Default': True},
+ },
+ 'ParentTags': ('class',),
+ },
+ 'indexfield': {
+ 'BaseClass': GCIndexField,
+ 'Attributes': {
+ 'name': {
+ 'Required': True,
+ 'Unique': True,
+ 'Typecase': GTypecast.name},
+ },
+ 'Parenttags': ('index',)
+ },
}
return GParser.buildImportableTags ('module', xmlElements)
@@ -463,3 +487,29 @@
class GCParameter (GCTypeDefinition):
def __init__ (self, parent):
GCTypeDefinition.__init__ (self, parent, objType = 'GCParameter')
+
+
+# =============================================================================
+# The Index object
+# =============================================================================
+
+class GCIndex (GCObject):
+ def __init__ (self, parent):
+ GCObject.__init__ (self, parent, type = 'GCIndex')
+ self.fields = []
+ self.fullName = None
+ self.module = None
+ self._inits.extend ([None, self._complete])
+
+ def _complete (self):
+ self.module = self.findParentOfType ('GCModule').name
+ self.fullName = "ix_%s" % Namespace.createName (self.module, self.name)
+ self.fields = self.findChildrenOfType ('GCIndexField')
+
+# =============================================================================
+# The index field object
+# =============================================================================
+
+class GCIndexField (GCObject):
+ def __init__ (self, parent):
+ GCObject.__init__ (self, parent, type = 'GCIndexField')
Modified: trunk/gnue-appserver/src/gcd/readgcd.py
===================================================================
--- trunk/gnue-appserver/src/gcd/readgcd.py 2004-10-04 17:03:32 UTC (rev
6453)
+++ trunk/gnue-appserver/src/gcd/readgcd.py 2004-10-05 08:14:04 UTC (rev
6454)
@@ -32,6 +32,7 @@
from gnue.appserver import VERSION
from gnue.appserver.gcd import GCParser
+from gnue.appserver.classrep import Namespace
# =============================================================================
@@ -303,7 +304,14 @@
sObject.walk (self.__iterateProcedure)
+ elif sObject._type == 'GCIndex':
+ if not defs.has_key ('indices'):
+ defs ['indices'] = []
+ defs ['indices'].append ({'name' : sObject.fullName,
+ 'unique': sObject.unique,
+ 'fields': [f.name for f in sObject.fields]})
+
# ---------------------------------------------------------------------------
# Iterate over all child elements of a procedure
# ---------------------------------------------------------------------------
@@ -400,22 +408,27 @@
# ---------------------------------------------------------------------------
+ # Create a new datasource for a given class
+ # ---------------------------------------------------------------------------
+
+ def __openSource (self, classname, fieldList):
+ return GDataSource.DataSourceWrapper (connections = self.connections,
+ attributes = {'name': "dts_%s" % classname,
+ 'database': self.OPTIONS ['connection'],
+ 'table': classname},
+ fields = fieldList, unicodeMode = True)
+
+
+ # ---------------------------------------------------------------------------
# Update/add modules to the class repository
# ---------------------------------------------------------------------------
def _updateModules (self):
"""
"""
- attributes = {'name' : "dts_gnueModule",
- 'database': self.OPTIONS ['connection'],
- 'table' : 'gnue_module'}
- fieldList = ['gnue_id', 'gnue_name', 'gnue_comment']
- self._dtsModules = GDataSource.DataSourceWrapper (
- connections = self.connections,
- attributes = attributes,
- fields = fieldList,
- unicodeMode = True)
+ self._dtsModules = self.__openSource ('gnue_module', ['gnue_id',
+ 'gnue_name', 'gnue_comment'])
stat = [0, 0, 0] # inserted, updated, unchanged
@@ -452,26 +465,20 @@
def _updateClasses (self):
"""
"""
- attributes = {'name' : "dts_gnueClass",
- 'database': self.OPTIONS ['connection'],
- 'table' : 'gnue_class'}
- fieldList = ['gnue_id', 'gnue_name', 'gnue_module', 'gnue_comment',
- 'gnue_filter']
- datasource = GDataSource.DataSourceWrapper (
- connections = self.connections,
- attributes = attributes,
- fields = fieldList,
- unicodeMode = True)
+ self._dtsClass = self.__openSource ('gnue_class', ['gnue_id', 'gnue_name',
+ 'gnue_module', 'gnue_comment', 'gnue_filter'])
stat = [0, 0, 0] # inserted, updated, unchanged
- for klass in self.classes.values ():
+ filterStack = []
+
+ for (fullName, klass) in self.classes.items ():
moduleId = self.__findModule (klass ['gnue_module'])
cond = GConditions.buildConditionFromDict ( \
{'gnue_name': klass ['gnue_name'],
'gnue_module': moduleId})
- resultSet = datasource.createResultSet (cond)
+ resultSet = self._dtsClass.createResultSet (cond)
if resultSet.firstRecord () is None:
resultSet.insertRecord ()
@@ -484,12 +491,36 @@
# replace the module's name by it's gnue_id
klass ['gnue_module'] = moduleId
+ if klass.has_key ('gnue_filter'):
+ filterId = self.__findClass (klass ['gnue_filter'])
+
+ # The filter class is defined but has no gnue_id yet. So we defer
+ # updating the filter-reference
+ if filterId is None:
+ filterStack.append ((klass ['gnue_id'], klass ['gnue_filter'],
+ fullName))
+ del klass ['gnue_filter']
+ else:
+ klass ['gnue_filter'] = filterId
+
if not self.doUpdate (resultSet, klass):
modifier += 1
stat [modifier] += 1
+ doCommit = (stat [0] + stat [1]) > 0
- if stat [0] + stat [1]:
+ for (gnue_id, filterName, fullName) in filterStack:
+ cond = GConditions.buildConditionFromDict ({'gnue_id': gnue_id})
+ resultSet = self._dtsClass.createResultSet (cond)
+ if resultSet.firstRecord () is None:
+ raise ClassNotFoundError, (fullName)
+
+ filterId = self.__findClass (filterName)
+
+ if self.doUpdate (resultSet, {'gnue_filter': filterId}):
+ doCommit = True
+
+ if doCommit:
self.connections.commitAll ()
print o (u_(" Classes : %(ins)3d inserted, %(upd)3d updated, %(kept)3d "
@@ -504,18 +535,10 @@
def _updateProperties (self):
"""
"""
- attributes = {'name' : "dts_gnueProperty",
- 'database': self.OPTIONS ['connection'],
- 'table' : 'gnue_property'}
- fieldList = ['gnue_id', 'gnue_module', 'gnue_class', 'gnue_name',
- 'gnue_type', 'gnue_length', 'gnue_scale', 'gnue_nullable',
- 'gnue_comment']
- datasource = GDataSource.DataSourceWrapper (
- connections = self.connections,
- attributes = attributes,
- fields = fieldList,
- unicodeMode = True)
+ datasource = self.__openSource ('gnue_property', ['gnue_id', 'gnue_module',
+ 'gnue_class', 'gnue_name', 'gnue_type', 'gnue_length', 'gnue_scale',
+ 'gnue_nullable', 'gnue_comment'])
stat = [0, 0, 0] # inserted, updated, unchanged
@@ -559,18 +582,11 @@
# ---------------------------------------------------------------------------
def _updateProcedures (self):
- attributes = {'name' : "dts_gnueProcedure",
- 'database': self.OPTIONS ['connection'],
- 'table' : 'gnue_procedure'}
- fieldList = ['gnue_id', 'gnue_module', 'gnue_class', 'gnue_name',
- 'gnue_type', 'gnue_length', 'gnue_scale', 'gnue_nullable',
- 'gnue_comment', 'gnue_code', 'gnue_language']
- self._dtsProcedure = GDataSource.DataSourceWrapper (
- connections = self.connections,
- attributes = attributes,
- fields = fieldList,
- unicodeMode = True)
+ self._dtsProcedure = self.__openSource ('gnue_procedure', ['gnue_id',
+ 'gnue_module', 'gnue_class', 'gnue_name', 'gnue_type', 'gnue_length',
+ 'gnue_scale', 'gnue_nullable', 'gnue_comment', 'gnue_code',
+ 'gnue_language'])
stat = [0, 0, 0] # inserted, updated, unchanged
@@ -612,17 +628,10 @@
# ---------------------------------------------------------------------------
def _updateParameter (self):
- attributes = {'name' : "dts_gnueParameter",
- 'database': self.OPTIONS ['connection'],
- 'table' : 'gnue_parameter'}
- fieldList = ['gnue_id', 'gnue_procedure', 'gnue_name', 'gnue_type',
- 'gnue_scale', 'gnue_length', 'gnue_comment']
- self._dtsParameter = GDataSource.DataSourceWrapper (
- connections = self.connections,
- attributes = attributes,
- fields = fieldList,
- unicodeMode = True)
+ self._dtsParameter = self.__openSource ('gnue_parameter', ['gnue_id',
+ 'gnue_procedure', 'gnue_name', 'gnue_type', 'gnue_scale',
+ 'gnue_length', 'gnue_comment'])
stat = [0, 0, 0] # inserted, updated, unchanged
@@ -707,6 +716,23 @@
# ---------------------------------------------------------------------------
+ # Find the gnue-id of a given class
+ # ---------------------------------------------------------------------------
+
+ def __findClass (self, classname):
+ if self.classes.has_key (classname):
+ return self.classes [classname]['gnue_id']
+ else:
+ (module, name) = Namespace.splitName (classname)
+ mc = GConditions.buildConditionFromDict ( \
+ {'gnue_module': self.__findModule (module), 'gnue_name': name})
+ rs = self._dtsClass.createResultSet (mc)
+ if rs.firstRecord () is None:
+ raise ClassNotFoundError, (classname)
+
+ return rs.current.getField ('gnue_id')
+
+ # ---------------------------------------------------------------------------
# Generate a new object id
# ---------------------------------------------------------------------------
Added: trunk/gnue-appserver/src/geasFilter.py
===================================================================
--- trunk/gnue-appserver/src/geasFilter.py 2004-10-04 17:03:32 UTC (rev
6453)
+++ trunk/gnue-appserver/src/geasFilter.py 2004-10-05 08:14:04 UTC (rev
6454)
@@ -0,0 +1,362 @@
+# GNU Enterprise Application Server - Filter Support
+#
+# Copyright 2001-2004 Free Software Foundation
+#
+# This file is part of GNU Enterprise
+#
+# GNU Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2, or (at your option) any later version.
+#
+# GNU Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied
+# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+# PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with program; see the file COPYING. If not,
+# write to the Free Software Foundation, Inc., 59 Temple Place
+# - Suite 330, Boston, MA 02111-1307, USA.
+#
+# $Id$
+
+from language import Session
+from classrep import Namespace
+from gnue.common.apps import errors
+
+
+# =============================================================================
+# Exceptions
+# =============================================================================
+
+class CircularFilterError (errors.ApplicationError):
+ def __init__ (self):
+ msg = u_("The filters have circular references")
+ errors.ApplicationError.__init__ (self, msg)
+
+
+# =============================================================================
+# This class encapsulates handling of filters
+# =============================================================================
+
+class geasFilter:
+
+ # ---------------------------------------------------------------------------
+ # Constructor
+ # ---------------------------------------------------------------------------
+
+ def __init__ (self, sm):
+ self.__sm = sm
+ self.__session = Session.InternalSession (sm)
+ self.__filters = self.__loadFilters ()
+ self.__labels = self.__fetchLabels ()
+
+
+ # ---------------------------------------------------------------------------
+ # Get a structure describing the defined filters, their labels and values
+ # ---------------------------------------------------------------------------
+
+ def getFilter (self, language):
+ """
+ This function creates a structure holding all defined filters, their labels
+ in a requested language and all their possible values. The result is a
+ sequence of tuples, where a tuple is constructed as follows:
+
+ (filter-id, labels, master, data)
+
+ filter-id: the gnue-id of the filter class
+ labels: a sequence of tuples describing the labels (label, search, field)
+ master: gnue_id of the master-filter or None if no such master is defined
+ data: dictionary describing the allowed values of the filter's fields
+
+ @return: sequence of tuples as described above.
+ """
+
+ result = []
+
+ for (fId, filterDef) in self.__labels:
+ # Create an ordered sequence of all search/info-properties as stated in
+ # the GNUe Language Definition of the filter class
+ fields = []
+
+ for (propertyId, propertyDef) in filterDef.items ():
+ field = self.__getLabel (self.__getLanguages (language), propertyDef)
+ fields.append ((field ['order'], field ['label'], field))
+
+ # order sequence by search-value or info-value
+ fields.sort ()
+
+ master = self.__sm.classes.find (fId).gnue_filter
+ if master is not None:
+ master = master.gnue_id
+
+ labels = [(f [1], f [2]['search'], f [2]['name']) for f in fields]
+ names = [f [2]['name'] for f in fields]
+
+ data = self.__getData (fId, master, names)
+ result.append ((fId, labels, master, data))
+
+ return result
+
+
+
+ # ---------------------------------------------------------------------------
+ # Load a sorted list of all filters defined in the class repository
+ # ---------------------------------------------------------------------------
+
+ def __loadFilters (self):
+ """
+ This function creates a sequence with all filter-Ids defined in the class
+ repository. The sequence is given in such an order which respects internal
+ filter dependancies.
+
+ @return: sequence with gnue_id's of all filter classes found in the class
+ repository.
+ """
+
+ self.__fDict = {}
+
+ # First get all filters defined in class repository
+ for klass in self.__sm.classes.values ():
+ if klass.gnue_filter is not None:
+ self.__addFilter (klass.gnue_filter)
+
+ result = []
+ add = self.__getIndependantFilters ()
+
+ while len (add):
+ result.extend (add)
+ add = self.__getIndependantFilters ()
+
+ return result
+
+
+ # ---------------------------------------------------------------------------
+ # Add a filter class to the filter dictionary
+ # ---------------------------------------------------------------------------
+
+ def __addFilter (self, filterClass):
+ """
+ This function adds a filter to the filter dicionary. If the filter has
+ another master itself this function starts a recursion with that master.
+
+ @param filterClass: Class instance of the filter class to be added
+ """
+
+ filterId = filterClass.gnue_id
+ if not self.__fDict.has_key (filterId):
+ self.__fDict [filterId] = []
+
+ if filterClass.gnue_filter is not None:
+ refId = filterClass.gnue_filter.gnue_id
+ if not refId in self.__fDict [filterId]:
+ self.__fDict [filterId].append (refId)
+
+ self.__addFilter (filterClass.gnue_filter)
+
+
+ # ---------------------------------------------------------------------------
+ # Get all items from the filter dictionary which have no dependancies
+ # ---------------------------------------------------------------------------
+
+ def __getIndependantFilters (self):
+ """
+ This function returns a sequence of all filter-Ids without any dependancies
+ to other filters. If no such filter is found but there are still filters in
+ the dictionary a CircularFilterError will be raised.
+
+ @return: sequence holding the gnue_id's of all filters without any
+ reference to another filter.
+ """
+
+ result = []
+
+ for (filterId, references) in self.__fDict.items ():
+
+ # if a filter has no other references, we can add it to the result and
+ # remove all references in other filters to this filter.
+ if not len (references):
+ result.append (filterId)
+
+ for others in self.__fDict.values ():
+ if filterId in others:
+ others.remove (filterId)
+
+ del self.__fDict [filterId]
+
+ # If no filter was independant, but there are still filters in the
+ # dictionary, there must be a circular reference
+ if not len (result) and len (self.__fDict.keys ()):
+ raise CircularFilterError
+
+ return result
+
+
+ # ---------------------------------------------------------------------------
+ # Create a sequence with all labels per filter (in all languages)
+ # ---------------------------------------------------------------------------
+
+ def __fetchLabels (self):
+ """
+ This function creates a sequence of all filters and all their labels in all
+ languages defined in the class repository. Each element of the sequence is
+ a tuple with the gnue_id of the filter class and a dictionary describing
+ the filter labels. This dicionary is constructed as follows:
+ {property-gnue_id: {language: {'order':?, 'name':?, 'label':?,
'search':?}}}
+
+ @return: sequence of tuples describing the filters and their labels
+ """
+
+ result = []
+
+ for filterId in self.__filters:
+ cond = ['and', ['or', ['notnull', ['field', 'gnue_search']],
+ ['notnull', ['field', 'gnue_info']]],
+ ['eq', ['field', 'gnue_property.gnue_class'],
+ ['const', filterId]]]
+
+ labels = self.__session.find ('gnue_label', cond, [], ['gnue_language',
+ 'gnue_label', 'gnue_search', 'gnue_info', 'gnue_id', 'gnue_property',
+ 'gnue_property.gnue_class'])
+
+ entry = {}
+
+ for label in labels:
+ prop = label.gnue_property
+ klass = self.__sm.classes.find (prop.gnue_class.gnue_id)
+
+ fullName = None
+ for p in klass.properties.values ():
+ if p.gnue_id == prop.gnue_id:
+ fullName = p.fullName
+ break
+
+ if not entry.has_key (prop.gnue_id):
+ entry [prop.gnue_id] = {}
+
+ entry [prop.gnue_id][label.gnue_language] = \
+ {'order' : label.gnue_search or label.gnue_info,
+ 'label' : label.gnue_label,
+ 'name' : fullName,
+ 'search': label.gnue_search is not None}
+
+ if not len (labels):
+ filterClass = self.__sm.classes.find (filterId)
+ prop = filterClass.properties ['gnue_id']
+ entry [prop.gnue_id] = {'C': {'order' : 0,
+ 'label' : filterClass.fullName,
+ 'name' : 'gnue_id',
+ 'search': True}}
+
+ result.append ((filterId, entry))
+
+ return result
+
+
+ # ---------------------------------------------------------------------------
+ # Create a sequence of languages in descending order
+ # ---------------------------------------------------------------------------
+
+ def __getLanguages (self, language):
+ """
+ This function creates a sequence of languages to be used for fetching
+ labels out of a given language. Where the starts with the most specific
+ language. The result contains at least the language 'C'.
+
+ @param language: Language to create a sequence out of, i.e. 'de_AT'
+ @return: sequence of languages to try, i.e. ['de_AT', 'de', 'C']
+ """
+
+ result = []
+
+ if '_' in language:
+ result = [language.split ('_') [0]]
+
+ if not language in result:
+ result.insert (0, language)
+
+ if not 'C' in result:
+ result.append ('C')
+
+ return result
+
+
+
+ # ---------------------------------------------------------------------------
+ # Get the first usable label for a given language
+ # ---------------------------------------------------------------------------
+
+ def __getLabel (self, languages, items):
+ """
+ This function returns a label from the given dictionary according to the
+ order given in the languages-sequence.
+
+ @param languages: sequence with languages to fetch a label for
+ @param items: dictionary with labels, where the language is the key
+ @return: dictionary describing the label
+ """
+
+ for lang in languages:
+ if items.get (lang) is not None:
+ return items.get (lang)
+
+ # if no item was found for the requested languages try an english one. If
+ # no such item is defined we use the first element defined
+ return items.get ('en', items.values () [0])
+
+
+ # ---------------------------------------------------------------------------
+ # Get a dictionary with all valid data for a given filter
+ # ---------------------------------------------------------------------------
+
+ def __getData (self, filterId, master, fields):
+ """
+ This function creates a dictionary with all allowed values for a given
+ filter. If the filter has a master assigned, the dictionary's keys will be
+ all the master's values (gnue_id), where the values of the dictionary are
+ all fields of the filter plus a gnue_id.
+
+ @param filterId: gnue_id of the filter class
+ @param master: gnue_id of the master-filter or None
+ @param fields: sequence with all fieldnames to be fetched
+
+ @return: dictionary with the possible filter values. This dictionary has
+ one key per entry in the master-filter and a sequence with all fields
+ as data values. Each entry in this sequence is a dictionary with
+ the filter's field-names and -values.
+ """
+
+ result = {}
+ classname = self.__sm.classes.find (filterId).fullName
+
+ # if we have a master-filter add the master-field to the query as well as a
+ # 'select-all' condition to prevent geasSession.request () of inserting a
+ # filter-value
+ if master is not None:
+ mClass = self.__sm.classes.find (master)
+ masterField = "%s.gnue_id" % mClass.fullName
+ condition = ['like', ['field', mClass.fullName], ['const', '%']]
+ fields.append (masterField)
+
+ else:
+ masterField = None
+ condition = []
+
+ data = self.__session.find (classname, condition, [], fields)
+
+ for row in data:
+ # use the master-id as dictionary key or None if no master available
+ key = master is not None and row [mClass.fullName].gnue_id or None
+
+ if not result.has_key (key):
+ result [key] = []
+
+ add = {'gnue_id': row.gnue_id}
+ for field in fields:
+ if field != masterField:
+ add [field] = row [field]
+
+ result [key].append (add)
+
+ return result
Property changes on: trunk/gnue-appserver/src/geasFilter.py
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: trunk/gnue-appserver/src/geasInstance.py
===================================================================
--- trunk/gnue-appserver/src/geasInstance.py 2004-10-04 17:03:32 UTC (rev
6453)
+++ trunk/gnue-appserver/src/geasInstance.py 2004-10-05 08:14:04 UTC (rev
6454)
@@ -387,8 +387,8 @@
(datefield, userfield) = [('gnue_modifydate', 'gnue_modifyuser'),
('gnue_createdate', 'gnue_createuser')][creation]
if self.has_key (datefield):
- self.__putValue (datefield, mx.DateTime.now ())
+ self.__putValue (datefield, mx.DateTime.now (), False)
if self.has_key (userfield) and self.__session.user is not None:
- self.__putValue (userfield, self.__session.user)
+ self.__putValue (userfield, self.__session.user, False)
Modified: trunk/gnue-appserver/src/geasRpcServer.py
===================================================================
--- trunk/gnue-appserver/src/geasRpcServer.py 2004-10-04 17:03:32 UTC (rev
6453)
+++ trunk/gnue-appserver/src/geasRpcServer.py 2004-10-05 08:14:04 UTC (rev
6454)
@@ -237,13 +237,19 @@
print _("Step 4: Retrieving first instance ...")
rset = sm.fetch (session,list,0,1)
- print o(u_("""
+ if len (rset):
+ print o(u_("""
These are the values of the first instance:
Name : %(name)s
Street: %(street)s
City : %(city)s
""") % { "name": rset[0][1], "street": rset[0][2], "city": rset[0][3] })
+
+ print o(u_("Step 5: Retrieving defined filters ..."))
+ res = sm.getFilters (i18n.language)
+ print "Filters:", res
+
print _('Selftest passed!')
# =============================================================================
Modified: trunk/gnue-appserver/src/geasSession.py
===================================================================
--- trunk/gnue-appserver/src/geasSession.py 2004-10-04 17:03:32 UTC (rev
6453)
+++ trunk/gnue-appserver/src/geasSession.py 2004-10-05 08:14:04 UTC (rev
6454)
@@ -227,32 +227,6 @@
# ---------------------------------------------------------------------------
- # Get the value for the given filter
- # ---------------------------------------------------------------------------
-
- def __getFilter (self, filterName):
- if not self.filters.has_key (filterName):
- filterValue = self.parameters.get (filterName, None)
- if filterValue is None:
- raise NoFilterParamError, (filterName)
-
- cond = ['eq', ['field', 'gnue_code'], ['const', filterValue]]
- fList = self.request (filterName, cond, [], ['gnue_id'])
- idList = self.fetch (fList, 0, 5)
-
- if not len (idList):
- raise InvalidFilterValueError, (filterName, filterValue)
-
- elif len (idList) > 1:
- raise MultipleFilterValueError, (filterName, filterValue)
-
- self.filters [filterName] = idList [0][0]
-
- return self.filters [filterName]
-
-
-
- # ---------------------------------------------------------------------------
# Log into the application server
# ---------------------------------------------------------------------------
@@ -429,9 +403,11 @@
table = classdef.table
record = self.__connection.insertRecord (table)
+
if classdef.gnue_filter is not None:
- fName = classdef.gnue_filter
- record.putField (fName, self.__getFilter (fName))
+ fId = classdef.gnue_filter.gnue_id
+ fName = self.sm.classes.find (fId).fullName
+ record.putField (fName, self.__filterValue (fId))
instance = geasInstance.geasInstance (self, self.__connection, record,
classdef)
@@ -594,14 +570,8 @@
by the datasource, and another one which has to be processed by appserver.
"""
- if classdef.gnue_filter is not None:
- filterCond = GConditions.buildConditionFromDict ( \
- {classdef.gnue_filter: self.__getFilter (classdef.gnue_filter)})
- else:
- filterCond = None
-
if condition is None:
- return (filterCond, None)
+ return (self.__filterCondition (classdef), None)
if isinstance (condition, ListType):
cTree = GConditions.buildTreeFromList (condition)
@@ -612,21 +582,24 @@
else:
raise ConditionDataTypeError, condition
- # If filterCond is already mentioned in the condition tree, keep that one
- if filterCond is not None:
+ if classdef.gnue_filter is not None:
+ useFilter = True
+ filterName = self.sm.classes.find (classdef.gnue_filter.gnue_id).fullName
cList = cTree.findChildrenOfType ('GCCField', allowAllChildren = True)
if len (cList):
for item in cList:
- if classdef.gnue_filter in item.name.split ('.'):
- filterCond = None
+ if filterName in item.name.split ('.'):
+ useFilter = False
break
+ else:
+ useFilter = False
dbTrees = []
asTrees = []
forest = []
- if filterCond is not None:
- self.__splitIntoAnd (filterCond, forest)
+ if useFilter:
+ self.__splitIntoAnd (self.__filterCondition (classdef), forest)
if len (cTree._children):
# NOTE: the first element of a condition tree is a GCondition object
@@ -663,6 +636,50 @@
# ---------------------------------------------------------------------------
+ # Create a condition tree for the current classdef representing it's filter
+ # ---------------------------------------------------------------------------
+
+ def __filterCondition (self, classdef):
+
+ if classdef.gnue_filter is not None:
+ filterId = classdef.gnue_filter.gnue_id
+ filterName = self.sm.classes.find (filterId).fullName
+ filterCond = GConditions.buildConditionFromDict ( \
+ {filterName: self.__filterValue (filterId)})
+ else:
+ filterCond = None
+
+ return filterCond
+
+
+ # ---------------------------------------------------------------------------
+ # Get the value for the given filter
+ # ---------------------------------------------------------------------------
+
+ def __filterValue (self, filterId):
+
+ filterName = self.sm.classes.find (filterId).fullName
+ if not self.filters.has_key (filterId):
+ filterValue = self.parameters.get (filterId, None)
+ if filterValue is None:
+ raise NoFilterParamError, (filterName)
+
+ cond = ['eq', ['field', 'gnue_id'], ['const', filterValue]]
+ fList = self.request (filterName, cond, [], ['gnue_id'])
+ idList = self.fetch (fList, 0, 5)
+
+ if not len (idList):
+ raise InvalidFilterValueError, (filterName, filterValue)
+
+ elif len (idList) > 1:
+ raise MultipleFilterValueError, (filterName, filterValue)
+
+ self.filters [filterId] = idList [0][0]
+
+ return self.filters [filterId]
+
+
+ # ---------------------------------------------------------------------------
# Split a condition tree into separate parts
# ---------------------------------------------------------------------------
Modified: trunk/gnue-appserver/src/geasSessionManager.py
===================================================================
--- trunk/gnue-appserver/src/geasSessionManager.py 2004-10-04 17:03:32 UTC
(rev 6453)
+++ trunk/gnue-appserver/src/geasSessionManager.py 2004-10-05 08:14:04 UTC
(rev 6454)
@@ -26,6 +26,7 @@
import geasSession
import geasAuthentication
import classrep
+import geasFilter
from gnue import appserver
from gnue.common.datasources import GConnections
@@ -56,6 +57,7 @@
self._sessions = {}
self._buildInternalSession ()
classrep.init (self)
+ self._filter = geasFilter.geasFilter (self)
cfg = gConfigDict (section = 'appserver')
dbauth = cfg.get ('authentication', 'False')
@@ -209,3 +211,11 @@
s = self._getSession (session_id)
return s.call (classname, obj_id_list, procedurename, parameters)
+
+
+ # ---------------------------------------------------------------------------
+ # Get a structure describing all available filters
+ # ---------------------------------------------------------------------------
+
+ def getFilters (self, language):
+ return self._filter.getFilter (language)
Modified:
trunk/gnue-common/src/datasources/drivers/appserver/appserver/Connection.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/appserver/appserver/Connection.py
2004-10-04 17:03:32 UTC (rev 6453)
+++ trunk/gnue-common/src/datasources/drivers/appserver/appserver/Connection.py
2004-10-05 08:14:04 UTC (rev 6454)
@@ -51,6 +51,17 @@
}
# ---------------------------------------------------------------------------
+ # Constructor
+ # ---------------------------------------------------------------------------
+
+ def __init__ (self, connections, name, parameters):
+ Base.Connection.__init__ (self, connections, name, parameters)
+ self._filters = None
+ self._server = None
+ self._sm = None
+
+
+ # ---------------------------------------------------------------------------
# Define the needed information to log in
# ---------------------------------------------------------------------------
@@ -63,11 +74,18 @@
result.extend ([['_username', _('User Name'), 0],
['_password', _('Password'), 1]])
- result.extend ([['gnue_company', _('Company'), 0],
- ['gnue_year', _('Fiscal Year'), 0]])
+ self.__getSessionManager ()
+ self._filters = self._sm.getFilters (self.parameters.get ('_language',
'C'))
+ for item in self._filters:
+ filterId = item [0]
+ for (label, search, field) in item [1]:
+ result.append ([filterId, label, False])
+ break
+
return result
+
# ---------------------------------------------------------------------------
# Open a connection
# ---------------------------------------------------------------------------
@@ -77,17 +95,10 @@
user = connectData.get ('_username', None)
passwd = connectData.get ('_password', None)
- params = {'host' : connectData ['host'],
- 'port' : connectData ['port'],
- 'transport': connectData ['transport']}
+ self.__getSessionManager ()
- self._server = client.attach (connectData ['rpctype'], params)
+ self.__updateFilters (connectData)
- if connectData.has_key ('timeout'):
- self._server.setTimeout (float (connectData ['timeout']))
-
- self._sm = self._server.request ('Session')
-
try:
if connectData.has_key ('_username'):
del connectData ['_username']
@@ -139,3 +150,58 @@
# the Base driver
def cursor(self):
return None
+
+
+ # ---------------------------------------------------------------------------
+ # Create/return a connection to the appserver
+ # ---------------------------------------------------------------------------
+
+ def __getSessionManager (self):
+
+ if self._server is None:
+ params = {'host' : self.parameters.get ('host'),
+ 'port' : self.parameters.get ('port'),
+ 'transport': self.parameters.get ('transport')}
+ rpcType = self.parameters.get ('rpctype')
+ self._server = client.attach (rpcType, params)
+
+ if self.parameters.has_key ('timeout'):
+ self._server.setTimeout (float (self.parameters ['timeout']))
+
+ if self._sm is None:
+ self._sm = self._server.request ('Session')
+
+ return self._sm
+
+
+ # ---------------------------------------------------------------------------
+ # Update the given filter values
+ # ---------------------------------------------------------------------------
+
+ def __updateFilters (self, connectData):
+
+ for item in self._filters:
+ filterId = item [0]
+
+ if connectData.has_key (filterId):
+ value = connectData [filterId]
+ (label, search, field) = item [1][0]
+
+ if item [2] is None:
+ masterkey = ''
+ else:
+ masterkey = connectData [item [2]]
+
+ found = False
+ vDict = item [3][masterkey]
+ for record in vDict:
+ if record [field] == value:
+ connectData [filterId] = record ['gnue_id']
+ found = True
+ break
+
+ if not found:
+ raise Exceptions.LoginError, \
+ u_("'%(value)s' is not a valid filter-value for '%(filter)s'") \
+ % {'value': value,
+ 'filter': label}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- r6454 - in trunk: gnue-appserver/grpc gnue-appserver/share gnue-appserver/src gnue-appserver/src/gcd gnue-common/src/datasources/drivers/appserver/appserver,
johannes <=