[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnue] r7915 - in trunk/gnue-appserver/src: . gcd gld
From: |
johannes |
Subject: |
[gnue] r7915 - in trunk/gnue-appserver/src: . gcd gld |
Date: |
Wed, 28 Sep 2005 12:35:22 -0500 (CDT) |
Author: johannes
Date: 2005-09-19 04:43:52 -0500 (Mon, 19 Sep 2005)
New Revision: 7915
Removed:
trunk/gnue-appserver/src/geasFilter.py
Modified:
trunk/gnue-appserver/src/data.py
trunk/gnue-appserver/src/gcd/readgcd.py
trunk/gnue-appserver/src/geasSessionManager.py
trunk/gnue-appserver/src/gld/readgld.py
trunk/gnue-appserver/src/repository.py
Log:
Improved class repository, removed usage of the internal session
Modified: trunk/gnue-appserver/src/data.py
===================================================================
--- trunk/gnue-appserver/src/data.py 2005-09-19 08:06:13 UTC (rev 7914)
+++ trunk/gnue-appserver/src/data.py 2005-09-19 09:43:52 UTC (rev 7915)
@@ -747,10 +747,7 @@
self.__uuidType = gConfig ('uuidtype').lower ()
- # Keep a weak reference to the backend connection and make sure we're
- # logged in
- self.__backend = weakref.ref (connections.getConnection (database))
- connections.loginToConnection (self.__backend ())
+ self.__backend = connections.getConnection (database, True)
# ---------------------------------------------------------------------------
@@ -895,7 +892,7 @@
# otherwise requery the current record for all uncached fields
else:
- new = self.__backend ().requery (table, {u'gnue_id': row},
uncachedFields)
+ new = self.__backend.requery (table, {u'gnue_id': row}, uncachedFields)
r = record (self.__cache, self.__connections, self.__database, table,
row)
r._fill (None, uncachedFields, new)
@@ -934,7 +931,7 @@
tables = self.__cache.dirtyTables ()
- backend = self.__backend ()
+ backend = self.__backend
# first perform all inserts
if self.__cache.inserted:
@@ -961,7 +958,7 @@
# Commit the whole transaction
- self.__connections.commitAll ()
+ self.__backend.commit ()
# The transaction has ended. Changes from other transactions could become
# valid in this moment, so we have to clear the cache.
@@ -1172,7 +1169,7 @@
# written anything yet, we have to tell the database that a new transaction
# starts now, so that commits from other sessions become valid now for us
# too.
- self.__connections.rollbackAll ()
+ self.__backend.rollback ()
# The transaction has ended. Changes from other transactions could become
# valid in this moment, so we have to clear the whole cache.
@@ -1188,7 +1185,7 @@
Close the connection to the database backend.
"""
- self.__connections.closeAll ()
+ self.__backend.close ()
# ---------------------------------------------------------------------------
@@ -1850,11 +1847,9 @@
# If we have no backend reference until now, create a weak reference to the
# connection instance and make sure we're logged in.
if self.__backend is None:
- cons = self.__connections
- self.__backend = weakref.ref (cons.getConnection (self.__database))
- cons.loginToConnection (self.__backend ())
+ self.__backend = self.__connections.getConnection (self.__database, True)
- new = self.__backend ().requery (self.__table, {u'gnue_id': self.__row},
+ new = self.__backend.requery (self.__table, {u'gnue_id': self.__row},
[field])
if new:
value = new.get (field)
Modified: trunk/gnue-appserver/src/gcd/readgcd.py
===================================================================
--- trunk/gnue-appserver/src/gcd/readgcd.py 2005-09-19 08:06:13 UTC (rev
7914)
+++ trunk/gnue-appserver/src/gcd/readgcd.py 2005-09-19 09:43:52 UTC (rev
7915)
@@ -313,10 +313,16 @@
self.__integrityCheck ()
- self.executeAndGenerateCode ()
- self.updateRepository ()
+ self.__backend = self._connections.getConnection (self._database, True)
+ try:
+ self.executeAndGenerateCode ()
+ self.updateRepository ()
+ finally:
+ self.__backend.close ()
+
+
# ---------------------------------------------------------------------------
# Execute and generate the code
# ---------------------------------------------------------------------------
@@ -329,11 +335,8 @@
given output file (if requested by options).
"""
- connection = self._connections.getConnection (self._database)
- self._connections.loginToConnection (connection)
-
print _("Updating schema ...")
- code = connection.writeSchema (self.schema, self._fileonly)
+ code = self.__backend.writeSchema (self.schema, self._fileonly)
if self._dump is not None:
dest = open (self._dump, 'w')
@@ -362,7 +365,7 @@
commit |= self.__updateParameter ()
if commit:
- self._connections.commitAll ()
+ self.__backend.commit ()
# ---------------------------------------------------------------------------
Deleted: trunk/gnue-appserver/src/geasFilter.py
===================================================================
--- trunk/gnue-appserver/src/geasFilter.py 2005-09-19 08:06:13 UTC (rev
7914)
+++ trunk/gnue-appserver/src/geasFilter.py 2005-09-19 09:43:52 UTC (rev
7915)
@@ -1,399 +0,0 @@
-# GNU Enterprise Application Server - Filter Support
-#
-# Copyright 2001-2005 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 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 ()
- self.__cLabels = self.__fetchClassLabels ()
-
-
- # ---------------------------------------------------------------------------
- # 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-class, labels, master, data)
-
- filter-class: tuple with the name of the filter class and it's label
- labels: a sequence of tuples describing the labels (label, search, field)
- master: name 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 = []
- repository = self.__sm.repository
-
- 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 ()
-
- classdef = repository.classes [fId]
- master = classdef.gnue_filter and classdef.gnue_filter or None
- if master is not None:
- master = repository.classes [master.gnue_id].fullName
-
- labels = [(f [1], f [2]['search'], f [2]['name']) for f in fields]
- names = [f [2]['name'] for f in fields]
-
- if self.__cLabels.has_key (fId):
- classLabel = self.__getLabel (self.__getLanguages (language),
- self.__cLabels [fId])
- else:
- classLabel = labels [0][0]
-
- data = self.__getData (fId, master, names)
- result.append (((classdef.fullName, classLabel), 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 filterClass in self.__sm.repository.filters.values ():
- self.__addFilter (filterClass)
-
- 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:
- 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.repository.classes [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.repository.classes [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
-
-
- # ---------------------------------------------------------------------------
- # Get a dictionary with all class labels of the filter classes
- # ---------------------------------------------------------------------------
-
- def __fetchClassLabels (self):
- """
- This function creates a dictionary of class-labels for all filters
- currently in use. This dictionary has the filter-id's as keys and another
- dictionary - with language = label - as values.
-
- @return: dictionary {filter-id: {language: label, language: label} ..}
- """
-
- result = {}
-
- for filterId in self.__filters:
- filterClass = self.__sm.repository.classes [filterId]
- prop = filterClass.properties ['gnue_id']
- cond = {'gnue_property': prop.gnue_id}
-
- labels = self.__session.find ('gnue_label', cond, [],
- ['gnue_language', 'gnue_label'])
- if labels:
- result [filterId] = {}
-
- for item in labels:
- result [filterId] [item.gnue_language] = item.gnue_label
-
- 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: name 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.repository.classes [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:
- masterField = "%s.gnue_id" % master
- condition = ['like', ['field', master], ['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 [master].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
Modified: trunk/gnue-appserver/src/geasSessionManager.py
===================================================================
--- trunk/gnue-appserver/src/geasSessionManager.py 2005-09-19 08:06:13 UTC
(rev 7914)
+++ trunk/gnue-appserver/src/geasSessionManager.py 2005-09-19 09:43:52 UTC
(rev 7915)
@@ -23,7 +23,6 @@
import geasSession
import geasAuthentication
-import geasFilter
import os.path
import fnmatch
import time
@@ -61,7 +60,7 @@
self._modulepath = modulepath or \
os.path.join (paths.data, "share", "gnue", "appserver")
- self.repository = repository.Repository (self._internalSession)
+ self.repository = repository.Repository (connections)
self.updateRepository (scanModules, haltOnError = True)
cfg = gConfigDict (section = 'appserver')
@@ -82,6 +81,7 @@
# ---------------------------------------------------------------------------
def _buildInternalSession (self):
+
self._internalSession = geasSession.geasSession (self._connections,
geasAuthentication.geasAuthAgent(), self, {})
self._internalSession.login (None, None) # fake login
@@ -97,6 +97,7 @@
# ---------------------------------------------------------------------------
def _getSession (self, sess_id):
+
if self._sessions.has_key (sess_id):
return self._sessions [sess_id]
else:
@@ -165,12 +166,8 @@
print o(u_("Reloading class repository ..."))
- self._internalSession.rollback ()
-
self.repository.load ()
- self._filter = geasFilter.geasFilter (self)
-
print o(u_("Class repository loaded"))
@@ -402,6 +399,6 @@
assert gEnter (4)
- result = self._filter.getFilter (language)
+ return self.repository.getFilterDefinition (language)
return gLeave (4, result)
Modified: trunk/gnue-appserver/src/gld/readgld.py
===================================================================
--- trunk/gnue-appserver/src/gld/readgld.py 2005-09-19 08:06:13 UTC (rev
7914)
+++ trunk/gnue-appserver/src/gld/readgld.py 2005-09-19 09:43:52 UTC (rev
7915)
@@ -271,11 +271,17 @@
self.__replaceReferences ()
# and finally update the repository
- self.__updateLabels ()
- self.__updateMessages ()
+ self.__backend = self._connections.getConnection (self._database, True)
+ try:
+ self.__updateLabels ()
+ self.__updateMessages ()
+ finally:
+ self.__backend.close ()
+
+
# ---------------------------------------------------------------------------
# Iterate over all top level elements
# ---------------------------------------------------------------------------
@@ -631,7 +637,7 @@
stat = self.__processResultSet (rSet, self.labels, cond)
if stat [0] + stat [1]:
- self._connections.commitAll ()
+ self.__backend.commit ()
msg = u_(" Labels : %(ins)3d inserted, %(upd)3d updated, %(kept)3d "
"unchanged.") \
@@ -664,7 +670,7 @@
stat = self.__processResultSet (rSet, self.messages, cond)
if stat [0] + stat [1]:
- self._connections.commitAll ()
+ self.__backend.commit ()
msg = u_(" Messages: %(ins)3d inserted, %(upd)3d updated, %(kept)3d "
"unchanged.") \
Modified: trunk/gnue-appserver/src/repository.py
===================================================================
--- trunk/gnue-appserver/src/repository.py 2005-09-19 08:06:13 UTC (rev
7914)
+++ trunk/gnue-appserver/src/repository.py 2005-09-19 09:43:52 UTC (rev
7915)
@@ -64,6 +64,24 @@
% {"procedure": procedure, "parameter": parameter}
errors.ApplicationError.__init__ (self, msg)
+class LabelNotFoundError (errors.ApplicationError):
+ def __init__ (self, name, prname):
+ msg = u_("Property '%(prname)s' has no label '%(name)s'") \
+ % {"prname": prname, "name": name}
+ errors.ApplicationError.__init__ (self, msg)
+
+class ProcLabelNotFoundError (errors.ApplicationError):
+ def __init__ (self, name, prname):
+ msg = u_("Procedure '%(prname)s' has no label '%(name)s'") \
+ % {"prname": prname, "name": name}
+ errors.ApplicationError.__init__ (self, msg)
+
+class ClassLabelNotFoundError (errors.ApplicationError):
+ def __init__ (self, language, classname):
+ msg = u_("Class '%(class)s' has no label for language '%(language)s'") \
+ % {'class': classname, 'language': language}
+ errors.ApplicationError.__init__ (self, msg)
+
class MissingFilterClassError (errors.ApplicationError):
def __init__ (self, classname, filterid):
msg = u_("Filter '%(filter)s' defined in class '%(classname)s' not found "
@@ -94,6 +112,12 @@
msg = u_("'%s' is not a valid, fully qualified identifier") % name
errors.ApplicationError.__init__ (self, name)
+class CircularFilterError (errors.ApplicationError):
+ def __init__ (self):
+ msg = u_("The filters have circular references")
+ errors.ApplicationError.__init__ (self, msg)
+
+
# =============================================================================
# This class implements the class repository
# =============================================================================
@@ -116,18 +140,18 @@
# Create a new repository instance
# ---------------------------------------------------------------------------
- def __init__ (self, session):
+ def __init__ (self, connections):
"""
- @param session: geasSession instance to use for data retrieval
+ @param connection: L{gnue.common.datasources.GConnections} instance
"""
- self._session = session
- self._langSession = Session.InternalSession (session.sm)
- self._connection = data.connection (session.connections, session.database)
+ self._connections = connections
+ self._database = gConfig ('connection')
self.modules = None
self.classes = None
self.filters = None
+ self.filterOrder = None
# ---------------------------------------------------------------------------
@@ -153,13 +177,13 @@
# Wrap all modules
for (key, value) in self.__rawModules.items ():
- module = Module (self._langSession, value)
+ module = Module (value)
modules [key] = module
modules [module.fullName] = module
# Wrap all classes and install them into the apropriate module
for (key, value) in self.__rawClasses.items ():
- aClass = Class (self._langSession, value, self.__rawModules)
+ aClass = Class (value, self.__rawModules)
module = aClass.gnue_module
modules [module]._installClass (aClass)
@@ -180,20 +204,29 @@
# Wrap all properties and install them into the apropriate class
for (key, value) in self.__rawProperties.items ():
- aProperty = Property (self._langSession, value, self.__rawModules)
+ aProperty = Property (value, self.__rawModules)
classes [aProperty.gnue_class]._installProperty (aProperty)
properties [key] = aProperty
# Wrap all procedures and link them into a lookup dictionary first
for (key, value) in self.__rawProcedures.items ():
- aProcedure = Procedure (self._langSession, value, self.__rawModules)
+ aProcedure = Procedure (value, self.__rawModules)
procedures [key] = aProcedure
# Now create all parameters and install them to their procedures.
for (key, value) in self.__rawParameters.items ():
- aParameter = Parameter (self._langSession, value)
+ aParameter = Parameter (value)
procedures [aParameter.gnue_procedure]._installParameter (aParameter)
+ # Create the labels and install them into their properties or procedures
+ for (key, value) in self.__rawLabels.items ():
+ aLabel = Label (value)
+
+ if aLabel.gnue_property:
+ properties [aLabel.gnue_property]._installLabel (aLabel)
+ else:
+ procedures [aLabel.gnue_procedure]._installLabel (aLabel)
+
# After having all parameters installed to their procedures, we can then
# run their second level initialization. Here it'll be determined wether
# a procedure is a calculated field or not. Finally the procedures will
@@ -210,7 +243,6 @@
# calculated properties.
map (verifyProcedure, procedures.values ())
-
# To finish the build process, all references (unicode-strings) are
# replaced by the corresponding wrapper instance. This way a
# 'someClass.gnue_module.fullName' will work.
@@ -236,7 +268,9 @@
if oldmodules is not None:
self.release (oldmodules, oldclasses, oldfilters)
+ self.filterOrder = self.__orderFilters ()
+
# ---------------------------------------------------------------------------
# Release resources of the repository
# ---------------------------------------------------------------------------
@@ -264,6 +298,27 @@
# ---------------------------------------------------------------------------
+ #
+ # ---------------------------------------------------------------------------
+
+ def getFilterDefinition (self, language):
+ """
+ """
+
+ result = []
+ dcon = data.connection (self._connections, self._database)
+
+ try:
+ for fk in self.filterOrder:
+ result.append (self.filters [fk]._getFilterDefinition (language, dcon))
+
+ finally:
+ dcon.close ()
+
+ return result
+
+
+ # ---------------------------------------------------------------------------
# Load the raw data from all repository tables
# ---------------------------------------------------------------------------
@@ -272,22 +327,33 @@
This function reads all repository tables into dictionaries.
"""
- self.__rawModules = self.__loadTable (u'gnue_module', [u'gnue_name'])
- self.__rawClasses = self.__loadTable (u'gnue_class', \
+ self._connection = data.connection (self._connections, self._database)
+
+ try:
+ self.__rawModules = self.__loadTable (u'gnue_module', [u'gnue_name'])
+ self.__rawClasses = self.__loadTable (u'gnue_class', \
[u'gnue_module', u'gnue_name', u'gnue_filter'])
- self.__rawProperties = self.__loadTable (u'gnue_property', \
+ self.__rawProperties = self.__loadTable (u'gnue_property', \
[u'gnue_module', u'gnue_class', u'gnue_name', u'gnue_length',
- u'gnue_scale', u'gnue_nullable', u'gnue_type'])
- self.__rawProcedures = self.__loadTable (u'gnue_procedure', \
+ u'gnue_scale', u'gnue_nullable', u'gnue_type',
+ u'gnue_comment'])
+ self.__rawProcedures = self.__loadTable (u'gnue_procedure', \
[u'gnue_module', u'gnue_class', u'gnue_name', u'gnue_language',
u'gnue_length', u'gnue_nullable', u'gnue_scale', u'gnue_type',
- u'gnue_comment'])
+ u'gnue_comment', u'gnue_code'])
- self.__rawParameters = self.__loadTable (u'gnue_parameter', \
+ self.__rawParameters = self.__loadTable (u'gnue_parameter', \
[u'gnue_procedure', u'gnue_name', u'gnue_type', u'gnue_length',
- u'gnue_scale'])
+ u'gnue_scale', u'gnue_comment'])
+ self.__rawLabels = self.__loadTable (u'gnue_label', \
+ [u'gnue_property', u'gnue_procedure', u'gnue_language', u'gnue_page',
+ u'gnue_label', u'gnue_position', u'gnue_search', u'gnue_info'])
+ finally:
+ self._connection.close ()
+
+
# ---------------------------------------------------------------------------
# Load fields from a given table
# ---------------------------------------------------------------------------
@@ -323,30 +389,68 @@
return result
+ # ---------------------------------------------------------------------------
+ # Create an ordered list of filters
+ # ---------------------------------------------------------------------------
+
+ def __orderFilters (self):
+
+ # Build a dependency tree of all filters
+ result = []
+ filters = {}
+
+ for item in self.filters.values ():
+ rec = filters.setdefault (item.gnue_id, [])
+ if item.gnue_filter:
+ rec.append (item.gnue_filter.gnue_id)
+
+ # and transform that tree into a list starting with independent filters
+ while filters:
+ addition = []
+
+ for (fid, deps) in filters.items ():
+ # if a filter has no other dependencies, add it to the result and
+ # remove all other references to it
+ if not len (deps):
+ addition.append (fid)
+
+ for ref in filters.values ():
+ if fid in ref:
+ ref.remove (fid)
+
+ del filters [fid]
+
+ # Finally, if nothing was added to the result, but there are still
+ # filters left in the tree we have a circular reference problem
+ if not len (addition) and len (filters):
+ raise CircularFilterError
+
+ result.extend (addition)
+
+ return result
+
+
+
# =============================================================================
# Base class implementing a repository element
# =============================================================================
class BaseItem:
+ """
+ Base class for repository items. The optionally given dictionary will be
+ transferred into the instances __dict__ attribute.
+ """
# ---------------------------------------------------------------------------
# Create a new instance of a repository item
# ---------------------------------------------------------------------------
- def __init__ (self, session, classname, predefined = None):
+ def __init__ (self, classname, predefined = None):
"""
- This function creates a new instance of a repository item. If a predefined
- dictionary is given, all it's elements are copied into the instances'
- __dict__. Access to other attributes will be delegated to the corresponding
- language interface Object.
-
- @param session: language interface session
@param classname: name of the class wrapped by this item
@param predefined: dictionary with predefined values
"""
- self._session = session
- self.__object = None
self.classname = classname
if predefined is not None:
@@ -354,60 +458,93 @@
# ---------------------------------------------------------------------------
- # Access to a non-prefdefined attribute
+ # Dictionary emulation for wrapper instances
# ---------------------------------------------------------------------------
- def __getattr__ (self, attr):
+ def __getitem__ (self, attr):
"""
- This function delegates property access to the bound language interface
- object and caches the result for following access.
+ Emulate a dictionary access to the wrapper instance.
- @param attr: name of the attribute to retrieve
- @return: value of the attribute
+ @param attr: attribute to return
+ @return: value of the attribute 'attr'
"""
- if self.__object is None:
- self.__object = self._session._get (self.classname, self.gnue_id)
+ return getattr (self, attr)
- # Fetch the result of a given attribute and keep it cached for later reuse
- result = getattr (self.__object, attr)
- self.__dict__ [attr] = result
- return result
+ # ---------------------------------------------------------------------------
+ # Truth value testing
+ # ---------------------------------------------------------------------------
+ def __nonzero__ (self):
+ return True
+
+
+
+# =============================================================================
+# MixIn class for classes having gnue_labels
+# =============================================================================
+
+class LabelsMixIn:
+
# ---------------------------------------------------------------------------
- # Dictionary emulation for wrapper instances
+ # Add a label to the labels dictionary
# ---------------------------------------------------------------------------
- def __getitem__ (self, attr):
+ def _installLabel (self, aLabel):
"""
- This function emulates a dictionary access to the wrapper instance.
+ Add a label to the list of labels in the proper language.
- @param attr: attribute to return
- @return: value of the attribute 'attr'
+ @param aLabel: L{Label} to be added
"""
- return getattr (self, attr)
+ self.labels [aLabel.gnue_language] = aLabel
+ # ---------------------------------------------------------------------------
+ # Get all labels usable within filter grouped by their language
+ # ---------------------------------------------------------------------------
+
+ def getFilterLabels (self, language):
+
+ usable = {}
+
+ for (lang, label) in self.labels.items ():
+ if label.order:
+ usable [lang] = label
+
+ for lang in getLanguages (language):
+ if lang.lower () in usable:
+ return usable [lang.lower ()]
+
+ return None
+
+
+
# =============================================================================
# This class implements a wrapper for module items of the repository
# =============================================================================
class Module (BaseItem):
+ """
+ A module object in the repository.
+ @ivar classes: a caseless dictionary of all classes of the module. Each class
+ will be listed in this dictionary by it's gnue_id as well as it's full
name.
+ @ivar fullname: fully qualified name of the module
+ """
+
# ---------------------------------------------------------------------------
# Create a new module item of the repository
# ---------------------------------------------------------------------------
- def __init__ (self, session, predefined = None):
+ def __init__ (self, predefined = None):
"""
- @param session: language interface session
@param predefined: dictionary with predefined ('builtin') values
"""
- BaseItem.__init__ (self, session, u'gnue_module', predefined)
+ BaseItem.__init__ (self, u'gnue_module', predefined)
self.classes = CaselessDict (ClassNotFoundError)
self.fullName = self.gnue_name
@@ -419,8 +556,9 @@
def _installClass (self, aClass):
"""
- This function adds the given class to the modules' list of classes.
- @param aClass: Class instance to be added
+ Add a class element to the class dictionary.
+
+ @param aClass: L{Class} instance to be added
"""
self.classes [aClass.gnue_id] = aClass
@@ -433,15 +571,14 @@
def updateLinks (self, modules, classes, unlink = False):
"""
- This class updates links of a module item by updating the links of all it's
- classes.
+ Update links of a module item by updating the links of all it's classes.
@param modules: dictionary with all modules available
@param classes: dictionary with all classes available
@param unlink: if set to True, references will be cleared
"""
- for (key, item) in self.classes.items ():
+ for item in self.classes.values ():
item.updateLinks (modules, classes, unlink)
@@ -451,19 +588,41 @@
# =============================================================================
class Class (BaseItem):
+ """
+ A class object in the repository.
+ @ivar fullName: fully qualified name (including the module name)
+ @ivar table: name of the underlying table in the backend database
+ @ivar properties: caseless dictionary with all properties of the class. Every
+ property is accessible either by it's gnue_id or it's full name. This
+ dictionary also contains I{calculated properties}
+ @ivar procedures: caseless dictionary with all procedures of the class. Every
+ procedure is accessible either by it's gnue_id or it's full name
+ @ivar masters: caseless dictionary of all the master classes
+ (master-/detail-relation). This dictionary contains the full name of the
+ master classes as keys, and a sequence of those properties referencing that
+ master class.
+ @ivar OnInit: list of L{Procedure} objects containing OnInit triggers of the
+ class
+ @ivar OnChange: list of L{Procedure} objects containing OnChange triggers of
+ the class
+ @ivar OnValidate: list of L{Procedure} objects containing OnValidate triggers
+ of the class
+ @ivar OnDelete: list of L{Procedure} objects containing OnDelete triggers of
+ the class
+ """
+
# ---------------------------------------------------------------------------
# Create a new class item of the repository
# ---------------------------------------------------------------------------
- def __init__ (self, session, predefined, moduleLookup):
+ def __init__ (self, predefined, moduleLookup):
"""
- @param session: language interface session
@param predefined: dictionary with predefined ('builtin') values
@param moduleLookup: (raw) lookup-dictionary with all modules available
"""
- BaseItem.__init__ (self, session, u'gnue_class', predefined)
+ BaseItem.__init__ (self, u'gnue_class', predefined)
moduleName = moduleLookup [self.gnue_module] ['gnue_name']
self.fullName = createName (moduleName, self.gnue_name)
@@ -473,6 +632,9 @@
self.procedures = CaselessDict (ProcedureNotFoundError, self.fullName)
self.masters = CaselessDict (ClassNotFoundError)
+ self.labels = CaselessDict (ClassLabelNotFoundError, self.fullName)
+ self.labels ['C'] = self.fullName
+
self.OnInit = []
self.OnChange = []
self.OnValidate = []
@@ -485,7 +647,7 @@
def _installProperty (self, aProperty):
"""
- This function installs a given property to the property dictionary
+ Add a property to the property dictionary
@param aProperty: Property instance to be installed
"""
@@ -500,10 +662,9 @@
def _installProcedure (self, aProcedure):
"""
- This function adds a procedure to the procedure dictionary. If the
- procedure is a 'calculated property' it also adds it to the property
- dictionary. If a procedure is a trigger it will be added to the apropriate
- trigger sequence.
+ Add a procedure to the procedure dictionary. If the procedure is a
+ 'calculated property', also add it to the property dictionary. If a
+ procedure is a trigger, add it to the apropriate trigger sequence.
@param aProcedure: procedure to be installed
"""
@@ -551,7 +712,7 @@
Add a given class to the dictionary of master-classes.
@param aProperty: name of the property holding the pointer to master-class
- @param aMaster: class wrapper instance to be added
+ @param aMaster: L{Class} instance to be added
"""
self.masters.setdefault (aMaster.fullName, []).append (aProperty)
@@ -563,7 +724,7 @@
def updateLinks (self, modules, classes, unlink = False):
"""
- This class updates links of a class item by updating the links of all it's
+ Updates links of a L{Class} item by updating the links of all it's
properties and procedures.
@param modules: dictionary with all modules available
@@ -592,30 +753,133 @@
item.updateLinks (self, modules, unlink)
+ # ---------------------------------------------------------------------------
+ #
+ # ---------------------------------------------------------------------------
+ def getFilterLabels (self, language):
+ """
+ """
+
+ props = {}
+ for item in self.properties.values ():
+ if item.gnue_id in props:
+ continue
+
+ flabels = item.getFilterLabels (language)
+ if flabels:
+ props [item.gnue_id] = flabels
+
+ if not props:
+ labels = [Label ({u'gnue_id': None,
+ u'gnue_property': self.properties [u'gnue_id'],
+ u'gnue_procedure': None,
+ u'gnue_label': u'gnue_id',
+ u'gnue_language': u'C',
+ u'gnue_search': 0,
+ u'gnue_info': None,
+ u'gnue_page': None,
+ u'gnue_position': 0})]
+ else:
+ labels = props.values ()
+
+ order = [(l.order, l.gnue_label, l) for l in labels]
+ order.sort ()
+
+ return [label for (pos, text, label) in order]
+
+
+ def getClassLabel (self, language):
+
+ for lang in getLanguages (language):
+ result = self.labels.get (lang)
+ if result:
+ return result
+
+ return self.fullName
+
+
+ def _getFilterDefinition (self, language, dataCon):
+ """
+ """
+
+ labels = self.getFilterLabels (language)
+
+ master = None
+ fields = [l.gnue_property.fullName for l in labels]
+ if self.gnue_filter:
+ master = self.gnue_filter.fullName
+ fields.append (master)
+
+ data = {}
+ contents = {None: (self.table, None, None, fields)}
+ resultSet = dataCon.query (contents, None, [{'name': u'gnue_id'}])
+
+ try:
+ rec = resultSet.nextRecord ()
+ while rec is not None:
+ if master:
+ group = data.setdefault (rec.getField (master), [])
+ else:
+ group = data.setdefault (None, [])
+
+ row = {}
+ for field in fields:
+ if field != master:
+ row [field] = rec.getField (field)
+
+ group.append (row)
+
+ rec = resultSet.nextRecord ()
+
+ finally:
+ resultSet.close ()
+
+
+ return ((self.fullName, self.getClassLabel (language)), \
+ [(l.gnue_label, l.search, l.gnue_property.fullName) for l in labels],
+ master, data)
+
+
# =============================================================================
# This class wraps a property item of the repository
# =============================================================================
-class Property (BaseItem):
+class Property (LabelsMixIn, BaseItem):
+ """
+ A property object in the repository.
+
+ @ivar fullName: fully qualified name of the property
+ @ivar column: name of the column in the backend this property is bound to
+ @ivar isCalculated: if True, the property is a calculated field, based on a
+ L{Procedure}. In this case column is set to None
+ @ivar isReference: True, if the property is a reference to another L{Class}.
+ @ivar referencedClass: for a reference property this attribute contains the
+ L{Class} instance of the referenced class (= master class)
+ @ivar fullType: full datatype as used by gnue
+ @ivar dbFullType: full datatype as used at the backend
+ @ivar dbType: base datatype as used at the backend
+ @ivar dbLength: length used at the backend
+ @ivar dbScale: scale used at the backend
+ """
# ---------------------------------------------------------------------------
# Create a new property item
# ---------------------------------------------------------------------------
- def __init__ (self, session, predefined, moduleLookup):
+ def __init__ (self, predefined, moduleLookup):
"""
- @param session: language interface session
@param predefined: dictionary with predefined ('builtin') values
@param moduleLookup: (raw) lookup-dictionary with all modules available
"""
updateTypeInfo (predefined)
- BaseItem.__init__ (self, session, u'gnue_property', predefined)
+ BaseItem.__init__ (self, u'gnue_property', predefined)
moduleName = moduleLookup [self.gnue_module]['gnue_name']
self.fullName = createName (moduleName, self.gnue_name)
self.column = self.fullName
+ self.labels = CaselessDict (LabelNotFoundError, self.fullName)
self.isCalculated = False
self.isReference = False
@@ -628,11 +892,11 @@
def updateLinks (self, aClass, modules, unlink = False):
"""
- This function updates the links of a property item to it's module and
- class. If unlink is set the references are cleared.
+ Update the links of a property item to it's L{Module} and L{Class}. If
+ unlink is set the references are cleared.
- @param aClass: Class instance the property belongs to
- @param modules: Module dictionary with all modules available
+ @param aClass: L{Class} instance the property belongs to
+ @param modules: module dictionary with all modules available
@param unlink: this boolean Flag determines wether to establish links or to
break them
"""
@@ -647,15 +911,18 @@
if not isinstance (self.gnue_module, Module):
self.gnue_module = modules [self.gnue_module]
+ for item in self.labels.values ():
+ item.updateLinks (self, unlink)
+
# ---------------------------------------------------------------------------
# Finalize the definition of a property
# ---------------------------------------------------------------------------
def finalize (self, classes):
"""
- This function verifies the type of the property and set's the reference
- flags for rerference properties.
+ Verify the type of the property and set the reference flags for rerference
+ properties.
@param classes: dictionary with all classes available
"""
@@ -670,14 +937,35 @@
if r is not None:
classes [self.gnue_class].addMasterClass (self.fullName, r)
+ # a 'gnue_id' property defines the class labels (if any)
+ parent = classes [self.gnue_class]
+ if self.fullName == u'gnue_id':
+ for (lang, label) in self.labels.items ():
+ parent.labels [lang] = label.gnue_label
# =============================================================================
# This class wraps a calculated property (= special procedures)
# =============================================================================
-class CalculatedProperty (BaseItem):
+class CalculatedProperty (LabelsMixIn, BaseItem):
+ """
+ A calculated property object in the repository. A calculated property is a
+ special kind of a L{Procedure}.
+ @ivar fullName: fully qualified name of the property
+ @ivar column: allways None
+ @ivar isReference: allways False
+ @ivar referencedClass: allways None
+ @ivar isCalculated: allways True
+ @ivar procedure: the L{Procedure} instance defining the property
+ @ivar fullType: full datatype as used by gnue
+ @ivar dbFullType: full datatype as used at the backend
+ @ivar dbType: base datatype as used at the backend
+ @ivar dbLength: length used at the backend
+ @ivar dbScale: scale used at the backend
+ """
+
# ---------------------------------------------------------------------------
# Create a new calculated property
# ---------------------------------------------------------------------------
@@ -698,7 +986,7 @@
'gnue_nullable': aProcedure.gnue_nullable}
updateTypeInfo (predefined)
- BaseItem.__init__ (self, aProcedure._session, u'gnue_procedure',
predefined)
+ BaseItem.__init__ (self, u'gnue_procedure', predefined)
self.fullName = aProcedure.calcFullName
self.column = None
@@ -707,8 +995,14 @@
self.referencedClass = None
self.isCalculated = True
self.procedure = aProcedure
+ self.labels = CaselessDict (LabelNotFoundError, self.fullName)
+ # Make sure to have all labels of the procedure bound to the calculated
+ # field as well
+ for item in aProcedure.labels.values ():
+ self._installLabel (item)
+
# ---------------------------------------------------------------------------
# Update the links of a calculated property item
# ---------------------------------------------------------------------------
@@ -717,8 +1011,8 @@
"""
If in unlink mode this function clears the pointer to the bound procedure.
- @param aClass: Class instance the property belongs to
- @param modules: Module dictionary with all modules available
+ @param aClass: L{Class} instance the property belongs to
+ @param modules: module dictionary with all modules available
@param unlink: this boolean Flag determines wether to establish links or to
break them
"""
@@ -733,6 +1027,8 @@
if not isinstance (self.gnue_module, Module):
self.gnue_module = modules [self.gnue_module]
+ for item in self.labels.values ():
+ item.updateLinks (self, unlink)
@@ -740,20 +1036,29 @@
# This class wraps a procedure item of the repository
# =============================================================================
-class Procedure (BaseItem):
+class Procedure (LabelsMixIn, BaseItem):
+ """
+ A procedure object in the repository.
+ @ivar fullName: fully qualified name of the procedure
+ @ivar isCalculated: if True, this procedure matches all requirements of a
+ calculated property.
+ @ivar calcFullName: fully qualified name of the calculated property
+ @ivar calcName: name of the calculated property withouth any module name
+ @ivar parameters: caseless dictionary with all L{Parameter}s of the procedure
+ """
+
# ---------------------------------------------------------------------------
# Create a new procedure wrapper
# ---------------------------------------------------------------------------
- def __init__ (self, session, predefined, moduleLookup):
+ def __init__ (self, predefined, moduleLookup):
"""
- @param session: language interface session
@param predefined: dictionary with predefined ('builtin') values
@param moduleLookup: (raw) lookup-dictionary with all modules available
"""
- BaseItem.__init__ (self, session, u'gnue_procedure', predefined)
+ BaseItem.__init__ (self, u'gnue_procedure', predefined)
moduleName = moduleLookup [self.gnue_module]['gnue_name']
self.fullName = createName (moduleName, self.gnue_name)
@@ -763,6 +1068,7 @@
self.calcName = None
self.parameters = CaselessDict (ParameterNotFoundError)
+ self.labels = CaselessDict (ProcLabelNotFoundError, self.fullName)
# ---------------------------------------------------------------------------
@@ -771,8 +1077,7 @@
def secondaryInit (self, moduleLookup):
"""
- This function determines wether a procedure can be used as a calculated
- field or not. If so the flag 'isCalcualted' will be set.
+ Check wether a procedure matches all requirements of a calculated property
@param moduleLookup: lookup dictionary for modules
"""
@@ -792,8 +1097,7 @@
def _installParameter (self, aParameter):
"""
- This function installs the given parameter to the procedure's parameter
- dictionary.
+ Add a L{Parameter} to the procedure's parameter dictionary.
@param aParameter: the parameter to be installed.
"""
@@ -808,11 +1112,11 @@
def updateLinks (self, aClass, modules, unlink = False):
"""
- This function updates the links of a procedure item to it's module and
- class. If unlink is set the references are cleared.
+ Update the links of a procedure item to it's module and class. If unlink is
+ set the references are cleared.
- @param aClass: Class instance the procedure belongs to
- @param modules: Module dictionary with all modules available
+ @param aClass: L{Class} instance the procedure belongs to
+ @param modules: module dictionary with all modules available
@param unlink: this boolean Flag determines wether to establish links or to
break them
"""
@@ -829,28 +1133,37 @@
for param in self.parameters.values ():
param.updateLinks (self, unlink)
+ for item in self.labels.values ():
+ item.updateLinks (self, unlink)
+
# =============================================================================
# This class implements a parameter item of the repository
# =============================================================================
class Parameter (BaseItem):
+ """
+ A parameter object of the repository.
+ @ivar fullName: fully qualified name of the paramter
+ @ivar dbType: the type of the parameter in the backend database
+ """
+
# ---------------------------------------------------------------------------
# Create a new parameter wrapper instance
# ---------------------------------------------------------------------------
- def __init__ (self, session, predefined):
+ def __init__ (self, predefined):
"""
- @param session: language interface session
@param predefined: dictionary with predefined ('builtin') values
"""
- BaseItem.__init__ (self, session, u'gnue_parameter', predefined)
+ BaseItem.__init__ (self, u'gnue_parameter', predefined)
+
self.fullName = self.gnue_name
- if NONREF_TYPES.has_key (self.gnue_type):
+ if self.gnue_type in NONREF_TYPES:
self.dbType = self.gnue_type
else:
self.dbType = REF_TYPE
@@ -875,7 +1188,58 @@
self.gnue_procedure = aProcedure
+# =============================================================================
+# Label class
+# =============================================================================
+class Label (BaseItem):
+ """
+ A label object in the repository.
+
+ @ivar order: the search order of a label which is either gnue_search or if
+ that is None gnue_info
+ @ivar search: True, if gnue_search is not None
+ """
+
+ # ---------------------------------------------------------------------------
+ # Create a new property item
+ # ---------------------------------------------------------------------------
+
+ def __init__ (self, predefined):
+ """
+ @param predefined: dictionary with predefined ('builtin') values
+ @param moduleLookup: (raw) lookup-dictionary with all modules available
+ """
+
+ BaseItem.__init__ (self, u'gnue_label', predefined)
+
+ self.order = self.gnue_search or self.gnue_info
+ self.search = self.gnue_search is not None
+
+
+ # ---------------------------------------------------------------------------
+ # Update links
+ # ---------------------------------------------------------------------------
+
+ def updateLinks (self, aParent, unlink = False):
+ """
+ Update the link to the owning property or procedure of a label
+
+ @param aParent: the owning property or procedure
+ @param unlink: if set to True the reference will be cleared
+ """
+
+ if unlink:
+ self.gnue_procedure = None
+ self.gnue_property = None
+
+ else:
+ if self.gnue_property:
+ self.gnue_property = aParent
+ else:
+ self.gnue_procedure = aParent
+
+
# =============================================================================
# Type checking support
# =============================================================================
@@ -898,13 +1262,16 @@
def verifyBasetype (typename, length, scale):
"""
- This function verifies a given typename with length and scale. If this
- combination makes no sense a TypeFormatError will be raised. If typename
- is no valid base type a TypeNameError will be raised.
+ Verify a given typename with length and scale. If this combination makes no
+ sense a TypeFormatError will be raised. If typename is no valid base type a
+ TypeNameError will be raised.
@param typename: name of the datatype
@param length: length of the datatype
@param scale: scale of the datatype
+
+ @raises TypeFormatError: the combination of length and scale is not valid
+ @raises TypeNameError: typename is not a valid base type
"""
if not BASE_TYPES.has_key (typename):
@@ -944,6 +1311,8 @@
@return: If 'typename' is a reference type this function returns the class
definition of this reference type, otherwise None
+
+ @raises TypeFormatError: the type, length and scale combination is not valid
"""
if classes.has_key (typename):
@@ -1091,3 +1460,31 @@
raise InvalidNameError, name
return result
+
+
+# -----------------------------------------------------------------------------
+# Create a list of languages in descending order
+# -----------------------------------------------------------------------------
+
+def getLanguages (language):
+ """
+ Create an ordered list of languages to fetch labels for. The list starts with
+ the most specific language and contains at least 'C'. The language 'de_AT'
+ will result in a list ['de_AT', 'de', 'C'].
+
+ @param language: language (locale) to create a list for, e.g. 'de_AT'
+ @result: list of language-codes in descending order
+ """
+
+ 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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnue] r7915 - in trunk/gnue-appserver/src: . gcd gld,
johannes <=