Commit 8841b03a authored by LE GAC Renaud's avatar LE GAC Renaud
Browse files

Add logic for computed column in List.

parent 5c3e636d
......@@ -185,23 +185,54 @@ class List(BaseReport):
BaseReport.__init__(self, config, selector)
# database field maps and address
# NOTE: not defined for "rownumber" column
# decode column configuration
columns = [Storage(el) for el in json.loads(config.columns)]
maps = [split_dbfield(el.dbfield) for el in columns if el.dbfield]
# columns and maps are persistent
# Add database field map (tablename, fieldname, keyname)
map(self._add_map, columns)
# add the dataIndex (DataFrame, Ext.data.Store, Ext.grid.Panel)
map(self._add_dataIndex, columns)
# columns are persistent
self._columns = columns
self._maps = maps
# instantiate and fill the DataFrame
self._do_metric()
def _add_map(self, column):
"""Helper function to add the database field map
to the column configuration.
@type column: gluon.storage.Storage
@param column:
"""
if column.dbfield:
column.map = split_dbfield(column.dbfield)
def _add_dataIndex(self, column):
"""Helper function to add the dataIndex to the column configuration
when it is not defined. It is equal to the C{dbfield} property in
which dots are removed
@type column: gluon.storage.Storage
@param column:
"""
if not (column.dataIndex or column.xtype == "rownumberer"):
column.dataIndex = column.dbfield.replace('.', '')
def _do_data(self):
def _do_data(self, maps):
"""Build a temporarily list with the raw data for each series.
This method handle the "year" database field.
@type maps: list
@param maps: the database field map (tablename, fieldname, keyname)
@rtype: list
"""
......@@ -209,7 +240,6 @@ class List(BaseReport):
config = self.config
db = self.db
maps = self._maps
selector = self.selector
# the year axis is on
......@@ -242,16 +272,36 @@ class List(BaseReport):
"""
# dataIndex can not contains dot !
dataIndex = [''.join(el) for el in self._maps]
columns = self._columns
# extract data from the database
maps = [el.map for el in columns if el.dbfield]
index = [el.dataIndex for el in columns if el.dbfield]
data = self._do_data()
data = self._do_data(maps)
# protection
if not data:
index = [el.dataIndex for el in columns if el.dataIndex]
self.df = pd.DataFrame(columns=dataIndex)
return
self.df = pd.DataFrame(data, columns=dataIndex)
# fill the DataFrame
df = pd.DataFrame(data, columns=index)
# add the computed column
for el in columns:
if el.eval:
df[el.dataIndex] = df.eval(el.eval)
# re-order the column to follow user requirement
# skip rownumberer column (None index)
index = [el.dataIndex for el in columns if el.dataIndex]
df = df[index]
# make the data frame persistent
self.df = df
def _encode(self, value):
"""Encode date and timedelta with a define format.
......@@ -292,53 +342,52 @@ class List(BaseReport):
"""
db = self.db
maps = self._maps
columns = self._columns
store = self._store
# convert the database field into the configuration of an Ext.data.Field
for map in maps:
# convert the columns into the configuration of an Ext.data.Field
for el in columns:
# protection against rownumberer column
if not el.dataIndex:
continue
cfg = Storage()
tablename, fieldname, keyname = map
cfg = Storage(name=el.dataIndex)
# the special case: the year
if tablename == 'year':
cfg.name = 'year'
# the pseudo field year
if el.dbfield == 'year':
cfg.type ='int'
store.fields.append(cfg)
continue
# standard processing extract type from the database field
dbfield = db[tablename][fieldname]
# the store index is derived from the dbfield name
# it will be used by the grid via the dataIndex property
# The name can not contain dot.
cfg.name = ''.join(map)
# build the configuration for the Ext.data.Field
cfg.type = dbfield.type
if dbfield.type in ('string', 'text', 'json'):
cfg.type = 'string'
elif dbfield.type == 'date':
cfg.type = 'date'
cfg.dateFormat = 'Y-m-d'
elif dbfield.type == 'datetime':
cfg.type = 'date'
cfg.dateFormat = 'Y-m-d H:i:s'
elif dbfield.type == 'double':
# the computed column
elif el.eval:
cfg.type = 'float'
elif dbfield.type == 'integer':
cfg.type = 'int'
elif dbfield.type == 'time':
cfg.type = 'date'
cfg.dateFormat = 'H:i:s'
# standard database field, extract the type from the database field
else:
tablename, fieldname, keyname = el.map
dbfield = db[tablename][fieldname]
cfg.type = dbfield.type
if dbfield.type in ('string', 'text', 'json'):
cfg.type = 'string'
elif dbfield.type == 'date':
cfg.type = 'date'
cfg.dateFormat = 'Y-m-d'
elif dbfield.type == 'datetime':
cfg.type = 'date'
cfg.dateFormat = 'Y-m-d H:i:s'
elif dbfield.type == 'double':
cfg.type = 'float'
elif dbfield.type == 'integer':
cfg.type = 'int'
elif dbfield.type == 'time':
cfg.type = 'date'
cfg.dateFormat = 'H:i:s'
store.fields.append(cfg)
......@@ -355,14 +404,13 @@ class List(BaseReport):
grid = Storage(columns=[], features=[])
# column from the configuration
# remove non Ext JS property
for cfg in self._columns:
for key in ('dbfield', 'eval'):
if key in cfg:
del cfg[key]
# encode the dataIndex
# not needed for rownumberercolumn
if cfg.dbfield:
cfg.dataIndex = cfg.dbfield.replace('.', '')
del cfg.dbfield
grid.columns.append(cfg)
# features from the configuration
......@@ -390,14 +438,13 @@ class List(BaseReport):
@return: the configuration of the C{Ext.data.Store}.
"""
self._map = dict()
self._store = Store(data=[], fields=[])
config = self.config
store = Store(data=[], fields=[])
store.groupField = config.group_field.replace('.', '')
store.sorters = [el.replace('.', '') for el in config.sorters]
self._store.groupField = config.group_field.replace('.', '')
self._store.sorters = [el.replace('.', '') for el in config.sorters]
self._store = store
self._set_store_fields()
self._set_store_data()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment