import locale import mdx_input import sqlalchemy import common import slicer import datetime import pooler import copy class mapper(object): def __init__(self, size): self.size = size class query(object): def __init__(self, axis, cube, slicer_obj=None, *args): super(query, self).__init__() self.object = False self.cube = cube self.axis = axis if not slicer_obj: slicer_obj = slicer.slicer([]) self.slicer = slicer_obj # # Generate the cube with 'False' values # This function could be improved # def _cube_create(self, cube_size): cube_data = [False] while cube_size: newcube = [] for i in range(cube_size.pop()): newcube.append(copy.deepcopy(cube_data)) cube_data = newcube return cube_data def run(self,currency): db = sqlalchemy.create_engine(self.object.schema_id.database_id.connection_url,encoding='utf-8') metadata = sqlalchemy.MetaData(db) print 'Connected to database...', self.object.schema_id.database_id.connection_url # # Compute axis # axis = [] axis_result = [] cube_size = [] cross = False cross_all = [] for ax in self.axis: if ax.name == 'cross': cross = True cross = ax.run(metadata) cube_size[-1] = cube_size[-1] * len(cross) temp = axis_result[0][:] cross_all.append(cross) final_axis = [] for cr in cross: for el in axis_result[-1]: t = copy.deepcopy(el) t = list(t) t[0].append(cr['value'][0][0]) t.append(cr['value'][0][1]) final_axis.append(tuple(t)) axis_result[-1]=final_axis[:] final_axis=[] len_axis = len(axis[-1]) len_cross = len(cross) delta_count = 0 d=0 for data in common.xcombine(axis[-1],cross): flag = False make_where = [] temp_where = [] temp_column = [] if 'whereclause' in data[0]['query'].keys(): flag = True temp_where = data[0]['query']['whereclause'][0] data[0]['query']['whereclause']=str(data[0]['query']['whereclause'][0]) if isinstance(type(data[0]['query']['column'][0]),type(sqlalchemy.sql.expression._BindParamClause)): temp_column = data[0]['query']['column'][0] data[0]['query']['column'][0] = str(data[0]['query']['column'][0]) data_temp = copy.deepcopy(data[0]) if 'whereclause' in data[1]['query'].keys(): if 'whereclause' in data_temp['query'].keys(): make_where.append(data[1]['query']['whereclause'][0]) else: make_where.append(data[1]['query']['whereclause'][0]) delta_count = delta_count + 1 if delta_count >= len_cross and len_cross!=1: delta_count = 0 data_temp['delta'] = d d = d + 1 else: data_temp['delta'] = d d = d + 1 if flag: data[0]['query']['whereclause']=[temp_where] data_temp['query']['whereclause'] = [temp_where] if make_where: if 'whereclause' in data_temp['query'].keys(): data_temp['query']['whereclause'].append(make_where[0]) else: data_temp['query']['whereclause'] = make_where if temp_column: data[0]['query']['column'] = [temp_column] data_temp['query']['column'] = [temp_column] final_axis.append(data_temp) axis[-1] = [] axis[-1] = final_axis else: cross = False result = ax.run(metadata) length = 0 axis_result2 = [] for r in result: length += len(r['value']) axis_result2 += map(lambda x: (map(lambda y: y or False,x[0]),x[1] or False), r['value']) axis_result.append(axis_result2) axis.append(result) cube_size.append(length) cube_data = self._cube_create(cube_size) cr = [] slice = self.slicer.run(metadata) position = 0 ax = [] for subset in common.xcombine(*axis): select,table_fact = self.cube.run(metadata) for s in subset+slice: for key,val in s['query'].items(): for v in val: if key=='column': v = v.label('p_%d' % (position,)) position += 1 select.append_column(v) elif key=='whereclause': select.append_whereclause(v) elif key=='group_by': select.append_group_by(v) else: raise 'Error, %s not implemented !'% (key,) # metadata.bind.echo = True query = select.execute() result = query.fetchall() for record in result: cube = cube_data r = list(record) value = False for s in subset: if s.has_key('format'): # To make use of the format string if specified for the measure # Its set to static for a testing if not currency: currency = "EUR" if isinstance(r[0],float) or isinstance(r[0],int) or isinstance(r[0],long): a = {'data':r[0]} r[0] = str(r[0]) else: r[0] = '0.0' a = {'data':0.0} if s['format'] == 'cr_prefix': r[0] = currency + " " + "%.2f"%a['data'] elif s['format'] == 'cr_postfix': r[0] = "%.2f"%a['data'] + " " + currency elif s['format'] == 'comma_sep': r[0] = locale.format("%(data).2f", a, 1) elif s['format'] == 'cr_prefix_comma': r[0] = locale.format("%(data).2f", a, 1) r[0] = currency + " " + str(r[0]) elif s['format'] == 'cr_postfix_comma': a['currency'] = currency r[0] = locale.format("%(data).2f %(currency)s", a, 1) cube = s['axis_mapping'].cube_set(cube, r, s['delta']) value = s['axis_mapping'].value_set(r) or value for s in slice: value = s['axis_mapping'].value_set(r) or value if value: assert not cube[0], 'Already a value in cube, this is a bug !' cube[0] = value i=0 for a in cube_data: i=i+1; return (axis_result, cube_data) def preprocess(self): wrapper = mdx_input.mdx_input() wrapper.parse(self) def validate(self, schema): """ This function takes a query object and validate and assign fact data to it. Browse object from Tiny ERP""" cube = self.cube.validate(schema) self.object = cube if not self.object: raise "Cube '%s' not found in the schema '%s' !"%(cube.name, schema.name) self.slicer.validate(cube) for axis in self.axis: axis.validate(cube) for dimension in cube.dimension_ids: pass return True,cube def __repr__(self): res = '