From 8483a9b9dffcd8d0226670b70c899d00eccd618d Mon Sep 17 00:00:00 2001 From: Renaud Le Gac <legac@cppm.in2p3.fr> Date: Wed, 20 Mar 2013 17:37:36 +0100 Subject: [PATCH] Upgrade to run with alias tables. --- controllers/plugin_dbui.py | 6 +++++- modules/plugin_dbui/__init__.py | 1 + modules/plugin_dbui/dbsvc.py | 25 +++++++++++++++++++++---- modules/plugin_dbui/helper.py | 14 ++++++++++++++ static/plugin_dbui/CHANGELOG | 1 + 5 files changed, 42 insertions(+), 5 deletions(-) diff --git a/controllers/plugin_dbui.py b/controllers/plugin_dbui.py index bb9e574c..240d54b2 100644 --- a/controllers/plugin_dbui.py +++ b/controllers/plugin_dbui.py @@ -110,8 +110,12 @@ def dbui_conf(): di[action].append({'name': method, 'len': nargs}) # the stores configuration (static, for each table,...) + # NOTE: the interface require a store for all tables including alias. + # The only way to extract them is to scan the attributes list of + # the DAL since the method db.tables() or any variant return + # tables but not the alias one storeCfgs = plugins.dbui.static_stores - for table in db: + for table in dbui.get_all_tables(db): cfg = dbui.to_jsonstore(table) storeCfgs[cfg['storeId']] = cfg diff --git a/modules/plugin_dbui/__init__.py b/modules/plugin_dbui/__init__.py index e406624c..0a5ead8a 100755 --- a/modules/plugin_dbui/__init__.py +++ b/modules/plugin_dbui/__init__.py @@ -50,6 +50,7 @@ from storemodifier import AddStore, StoreModifier from helper import (as_list, decode_field, encode_field, + get_all_tables, get_create_id, get_field_validators, get_file_paths, diff --git a/modules/plugin_dbui/dbsvc.py b/modules/plugin_dbui/dbsvc.py index 59d43a4b..62d85757 100644 --- a/modules/plugin_dbui/dbsvc.py +++ b/modules/plugin_dbui/dbsvc.py @@ -10,6 +10,7 @@ from gluon.contrib import simplejson as json from gluon.storage import Storage from helper import (encode_field, decode_field, + get_all_tables, get_foreign_field, is_foreign_field, rows_serializer) @@ -168,6 +169,7 @@ class DbSvc(BaseSvc): def _is_fields_values_valid(self, table, fields): """Helper method to check each field value against its validators. + Return an empty dictionary when everything is OK or a dictionary with fields failing check: {field1: error1, field2: error2,...} @@ -176,6 +178,14 @@ class DbSvc(BaseSvc): db = self.environment['db'] for (field, val) in fields.items(): + + # NOTE: checks are not applied to foreign fields since + # consistency is garanty by the interface via the use of + # combobox. This approach help when running with alias table + # since validation crashed in that case. + if is_foreign_field(db[table][field]): + continue + errmsg = db[table][field].validate(val)[1] if errmsg: di[encode_field(table, field)] = errmsg @@ -183,12 +193,17 @@ class DbSvc(BaseSvc): return di - def _is_table_in_db(self, table): + def _is_table_in_db(self, tablename): """Helper method to check that a table exist in the database. + The method handles regular and alias tables. + Raise the DbSvcException if not. """ - if table not in self.environment['db'].tables: + db = self.environment['db'] + tablenames = [table._tablename for table in get_all_tables(db)] + + if tablename not in tablenames: raise DbSvcException(TABLE_NOT_IN_DB % table) @@ -439,12 +454,14 @@ class DbSvc(BaseSvc): query = self._encode_query(arg['where']) # Count the number of record in the table --require for the paging + # NOTE: the usual method db(db.table).count() failed with alias table + # it is why we use a more complicated approach. if query: - nrecords = db(query).count() + nrecords = len(db(query).select()) else: table = arg['tableName'] - nrecords = db(db[table].id).count() + nrecords = db(db[table]).count() # handle paging options (see Ext.PagingToolbar) kwargs = {} diff --git a/modules/plugin_dbui/helper.py b/modules/plugin_dbui/helper.py index 47f4d2a2..27ba60f5 100644 --- a/modules/plugin_dbui/helper.py +++ b/modules/plugin_dbui/helper.py @@ -8,6 +8,7 @@ import subprocess import tempfile from gluon import current +from gluon.dal import Table from gluon.http import HTTP from gluon.validators import (IS_DATE_IN_RANGE, IS_DATETIME_IN_RANGE, @@ -65,6 +66,19 @@ def encode_field(*args): return ''.join([el[0].upper()+el[1:].lower() for el in args if len(el)]) +def get_all_tables(dal): + """Helper function to return a list of all gluon.dal.Table + house by the DAL object. The list includes alias table. + + It is recommend to use standard iterator provided by + the DAL object. However by contruction, they ignore + alias table. + + """ + li = [dal[attr] for attr in dir(dal) if isinstance(dal[attr], Table)] + return li + + def get_create_id(table, **kwargs): """Helper function to find the id of a row identified by a set of field value pairs. diff --git a/static/plugin_dbui/CHANGELOG b/static/plugin_dbui/CHANGELOG index 05348e5a..0beb3aad 100644 --- a/static/plugin_dbui/CHANGELOG +++ b/static/plugin_dbui/CHANGELOG @@ -1,6 +1,7 @@ --------------------------------- CHANGE LOG ---------------------------------- HEAD + - Upgrade to run with alias table. 0.4.10.3 (Mar 2013) - Fix a bug in App.BasePanelWithSelector for IE. -- GitLab