1 ##############################################################################
3 # Copyright (c) 2004-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
5 # WARNING: This program as such is intended to be used by professional
6 # programmers who take the whole responsability of assessing all potential
7 # consequences resulting from its eventual inadequacies and bugs
8 # End users who are looking for a ready-to-use solution with commercial
9 # garantees and support are strongly adviced to contract a Free Software
12 # This program is Free Software; you can redistribute it and/or
13 # modify it under the terms of the GNU General Public License
14 # as published by the Free Software Foundation; either version 2
15 # of the License, or (at your option) any later version.
17 # This program is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # GNU General Public License for more details.
22 # You should have received a copy of the GNU General Public License
23 # along with this program; if not, write to the Free Software
24 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 ##############################################################################
30 from pyparsing import *
35 from osv import fields,osv
38 from cube import levels
41 class olap_fact_database(osv.osv):
42 _name = "olap.fact.database"
43 _description = "Olap Fact Database"
47 def _connection_get(self,cr,uid,ids,field_name,arg,context = {}):
49 Return a connection string url needed by SQL Alchemy. Exemple:
50 'postgres://scott:tiger@localhost:5432/mydatabase'
53 for obj in self.browse(cr,uid,ids,context):
54 res[obj.id] = '%s://%s:%s@%s:%d/%s' % (obj.type,obj.db_login,obj.db_password,obj.db_host,obj.db_port,obj.db_name)
57 def test_connection(self,cr,uid,ids,context = {}):
59 self_obj = self.browse(cr,uid,ids,context)
65 password = obj.db_password
67 if type == 'postgres':
68 tdb = psycopg2.connect('host=%s port=%s dbname=%s user=%s password=%s' % (host,port,db_name,user,password))
72 tdb = MySQLdb.connect(host = host,port = port,db = db,user = user,passwd = passwd)
75 raise osv.except_osv('Error (MySQLdb) : ',e)
76 elif type == 'oracle':
79 tdb = cx_Oracle.connect(user,password,host)
82 raise osv.except_osv('Error (cx_Oracle) : ',e)
85 raise osv.except_osv('BI Error !',e)
90 'name': fields.char('Fact name',size = 64,required = True),
91 'db_name': fields.char('Database name',size = 64,required = True , help = "Name of the database to be used for analysis."),
92 'db_login': fields.char('Database login',size = 64,required = True, help = "Login for the database name specified."),
93 'db_password': fields.char('Database password',size = 64,invisible = True,required = True, help = "Password for the login."),
94 'db_host': fields.char('Database host',size = 64,required = True , help= "Give hostname to make connection to the database."),
95 'db_port': fields.integer('Database port',required = True, help = " Port to be used in connection"),
96 'type': fields.selection([('mysql','MySQL' ),('postgres','PostgreSQL' ),('oracle','Oracle' )],'Database type',required = True ),
97 'connection_type': fields.selection([('socket','Socket' ),('port','Port' )],'Connection type',required = True ),
98 'connection_url': fields.function(_connection_get,method = True,type = 'char',string = 'Connection URL',size = 128 ),
99 'table_ids': fields.one2many('olap.database.tables','fact_database_id','Tables' ),
100 'loaded': fields.boolean('Loaded',readonly = True ),
103 'type': lambda * args: 'postgres',
104 'connection_type': lambda * args: 'port',
105 'db_host': lambda * args: 'localhost',
106 'db_name': lambda * args: 'terp',
107 'db_port': lambda * args: '5432',
108 'loaded' : lambda * args: False,
112 class olap_schema(osv.osv ):
113 _name = "olap.schema"
114 _description = "Olap Schema"
116 def _app_detect(self,cr,uid,ids,field_name,arg,context = {}):
118 Return a Application type
122 for obj in self.browse(cr,uid,ids,context):
123 if obj.database_id.type == 'postgres':
124 e = sqlalchemy.create_engine(obj.database_id.connection_url)
125 app_objs = self.pool.get('olap.application')
126 app_ids = app_objs.search(cr,uid,[] )
127 app_res = app_objs.browse(cr,uid,app_ids)
128 for app_obj in app_res:
130 result = e.execute(app_obj.query)
132 res[obj.id] = app_obj.name + ' Application'
136 if not res.has_key(obj.id):
137 res[obj.id] = "Unknown Application"
139 res[obj.id] = "Unknown Application"
143 'name': fields.char('Schema name',size = 64,required = True),
144 'note': fields.text('Schema description' ),
145 'cube_ids': fields.one2many('olap.cube','schema_id','Cubes'),
146 'database_id': fields.many2one('olap.fact.database','Database Connection',required = True),
147 'loaded': fields.boolean('Loading Datastructure',readonly = True),
148 'configure': fields.boolean('Configuring Datastructure',readonly = True),
149 'ready': fields.boolean('Ready',readonly = True),
150 'state': fields.selection([
151 ('none','Nothing has been Configured'),
152 ('dbconnect','Database Connected' ),
153 ('dbload','The Structure is Loaded'),
154 ('dbconfigure','The Structure is Configured.'),
155 ('dbready','Schema is ready to use'),
156 ('done','We Can Start building Cube'),
157 ],'Schema State',readonly = True),
158 'app_detect': fields.function(_app_detect,method = True,type = 'char',string = 'Connection URL',size = 128),
162 'loaded' : lambda * args: False,
163 'state': lambda * a: 'none',
164 'configure': lambda * a: False,
165 'ready': lambda * a: False
168 def action_dbconnect(self,cr,uid,ids,context = {}):
169 schema = self.browse(cr,uid,ids,context)[0]
170 type = schema.database_id.type
173 if type == 'postgres':
174 host = schema.database_id.db_host and "host=%s" % schema.database_id.db_host or ''
175 port = schema.database_id.db_port and "port=%s" % schema.database_id.db_port or ''
176 name = schema.database_id.db_name and "dbname=%s" % schema.database_id.db_name or ''
177 user = schema.database_id.db_login and "user=%s" % schema.database_id.db_login or ''
178 password = schema.database_id.db_password and "password=%s" % schema.database_id.db_password or ''
179 tdb = psycopg2.connect('%s %s %s %s %s' % (host,port,name,user,password))
181 elif type == 'mysql':
184 host = schema.database_id.db_host or ''
185 port = schema.database_id.db_port or ''
186 db = schema.database_id.db_name or ''
187 user = schema.database_id.db_login or ''
188 passwd = schema.database_id.db_password or ''
189 tdb = MySQLdb.connect(host = host,port = port,db = db,user = user,passwd = passwd)
191 raise osv.except_osv('Error (MySQLdb) : ',e)
193 elif type == 'oracle':
196 host = schema.database_id.db_host or ''
197 port = schema.database_id.db_port or ''
198 db = schema.database_id.db_name or ''
199 user = schema.database_id.db_name.upper() or ''
200 password = int(schema.database_id.db_password) or ''
201 tdb = cx_Oracle.connect(user,password,host)
203 raise osv.except_osv('Error (cx_Oracle) : ',e)
206 self.write(cr,uid,id,{'state':'dbconnect'})
209 raise osv.except_osv('BI Error !',e)
213 def action_dbload(self,cr,uid,ids,context = {}):
215 id_change = self.browse(cr,uid,id)
216 self.write(cr,uid,id,{'loaded':True})
217 self.write(cr,uid,id,{'state':'dbload'})
221 def action_dbconfigure(self,cr,uid,ids,context = {}):
223 id_browsed = self.browse(cr,uid,id)
224 if not id_browsed.state == 'dbconfigure':
225 self.write(cr,uid,id,{'state':'dbconfigure'})
226 self.write(cr,uid,id,{'configure':True})
229 def action_dbready(self,cr,uid,ids,context = {}):
231 self.write(cr,uid,id,{'ready':True})
232 self.write(cr,uid,id,{'state':'done'})
235 def action_done(self,cr,uid,ids,context = {}):
237 self.write(cr,uid,id,{'state':'done'})
240 def create_xml_schema(self,cr,uid,xml_schema,context = {}):
242 This function fill in the database according to a XML schema.
246 <Table name="sales_fact_1997"/>
247 <Dimension name="Gender" foreignKey="customer_id">
248 <Hierarchy hasAll="true" allMemberName="All Genders" primaryKey="customer_id">
249 <Table name="customer"/>
250 <Level name="Gender" column="gender" uniqueMembers="true"/>
253 <Dimension name="Time" foreignKey="time_id">
254 <Hierarchy hasAll="false" primaryKey="time_id">
255 <Table name="time_by_day"/>
256 <Level name="Year" column="the_year" type="Numeric" uniqueMembers="true"/>
257 <Level name="Quarter" column="quarter" uniqueMembers="false"/>
258 <Level name="Month" column="month_of_year" type="Numeric" uniqueMembers="false"/>
261 <Measure name="Store Sales" column="store_sales" aggregator="sum" formatString="#,###.##"/>
262 <Measure name="Store Cost" column="store_cost" aggregator="sum" formatString="#,###.00"/>
263 <CalculatedMember name="Profit" dimension="Measures" formula="[Measures].
264 [Store Sales]-[Measures].[Store Cost]">
265 <CalculatedMemberProperty name="FORMAT_STRING" value="$#,##0.00"/>
270 raise 'Not implemented !'
272 def request(self,cr,uid,name,request,context = {}):
273 ids = self.search(cr,uid,[('name','=',name)])
275 raise 'Schema not found !'
276 schema = self.browse(cr,uid,ids[0],context)
277 # warehouse = cube.warehouse()
278 # find_table = warehouse.match_table(cr, uid, request, context)
279 print 'Parsing MDX...'
281 mdx_parser = cube.mdx_parser()
282 mdx = mdx_parser.parse(request)
284 print 'Validating MDX...'
286 validate,cubex = mdx.validate(schema)
288 print 'Running MDX...'
289 res_comp = self.pool.get('res.company').search(cr,uid,([]))
290 res_comp = self.pool.get('res.company').browse(cr,uid,res_comp)
291 currency = res_comp[0].currency_id.name
292 print " Default Currency",currency
293 data = mdx.run(currency)
294 # qry_obj = self.pool.get('olap.query.logs')
295 # qry_id = qry_obj.search(cr, uid, [('query','=', request)])
299 # qry = qry_obj.browse(cr, uid, qry_id)[0]
301 # if qry.count >=3 and qry.table_name!='':
302 # data = warehouse.run(currency, qry)
304 # qry.count = qry.count +1
305 # qry_obj.write(cr, uid, qry_id, {'count': qry.count})
307 # data = mdx.run(currency)
309 # data = mdx.run(currency)
310 print 'Running Done...'
311 print 'Formatting Output...'
312 # if cubex.query_log and flag:
314 log = context.get('log')
316 connection = schema.database_id.connection_url
317 # warehouse.log(cr,uid,cubex,request,data,connection,context)
318 mdx.log(cr,uid,cubex,request,context)
319 return cube.mdx_output(data)
322 class olap_database_tables(osv.osv):
323 _name = "olap.database.tables"
324 _description = "Olap Database Tables"
326 'table_db_name': fields.char('Table Name',size = 64,required = True,readonly = True),
327 'name': fields.char('End-User Name',size = 64,required = True),
328 'columns': fields.one2many('olap.database.columns','table_id','Columns'),
329 'fact_database_id': fields.many2one('olap.fact.database','Database Id',required = True,ondelete = 'cascade',readonly = True),
330 'active': fields.boolean('Active'),
331 'hide': fields.boolean('Hidden'),
334 'active': lambda * args: True,
335 'hide': lambda * args: False
337 def name_get(self,cr,uid,ids,context = {}):
339 for t in self.browse(cr,uid,ids,context):
340 if t.name <> t.table_db_name:
341 result.append((t.id,t.name + ' (' + t.table_db_name + ')'))
343 result.append((t.id,t.name))
346 def show_col_view(self,cr,uid,ids,context = {}):
347 ids_cols = self.pool.get('olap.database.columns').search(cr,uid,([('table_id','=',ids[0])]))
348 id = self.pool.get('ir.ui.view').search(cr,uid,([('name','=','olap.database.columns.tree')]),context = {})[0]
350 'domain': "[('id','in', [" + ','.join(map(str,ids_cols)) + "])]",
351 'name': 'Database Columns',
354 'res_model': 'olap.database.columns',
355 'views': [(id,'tree'),(False,'form')],
356 'type': 'ir.actions.act_window',
359 def hide_col(self,cr,uid,ids,context = {}):
360 # To hide all the related columns also
362 self.write(cr,uid,id,{'hide':True})
365 def show_col(self,cr,uid,ids,context = {}):
366 # To show or unhide all the columns also
368 self.write(cr,uid,id,{'hide':False})
372 olap_database_tables()
374 class olap_database_columns(osv.osv):
375 _name = "olap.database.columns"
376 _description = "Olap Database Columns"
378 'timestamp': 'TimeStamp without Time Zone',
379 'timestampz': 'TimeStamp with Time Zone',
380 'numeric': 'Numeric',
382 'float8': 'Double Precesion',
383 'varchar': 'Character Varying',
386 'int2':'Small Integer',
388 'int8':'Big Integer',
391 'time': 'TimeStamp without Time Zone',
394 def _datatypes_get(self,*args,**argv):
395 return self.datatypes.items()
397 'column_db_name': fields.char('Column DBName',size = 64,required = True,readonly = True),
398 'name': fields.char('Column Name',size = 64,required = True),
399 'table_id': fields.many2one('olap.database.tables','Table Id',required = True,ondelete = 'cascade',select = True,readonly = True),
400 'primary_key': fields.boolean('Primary Key'),
401 'type': fields.selection(_datatypes_get,'Type',size = 64,required = True,readonly = True),
402 'related_to': fields.many2one('olap.database.tables','Related To',required = False,readonly = True),
403 'active': fields.boolean('Active'),
404 'hide': fields.boolean('Hidden'),
407 'hide': lambda * args: False,
408 'active': lambda * args: True,
409 'primary_key': lambda * args: False,
411 def name_get(self,cr,uid,ids,context = {}):
413 for t in self.browse(cr,uid,ids,context):
414 if t.name <> t.column_db_name:
415 result.append((t.id,t.table_id.table_db_name + ' (' + t.name + ')'))
417 result.append((t.id,t.table_id.table_db_name + ' (' + t.name + ')'))
421 def search(self,cr,uid,args,offset = 0,limit = None,order = None,
422 context = None,count = False):
424 return super(olap_database_columns,self).search(cr,uid,args,offset,limit,
425 order,context = context,count = count)
426 col_pool = self.pool.get('olap.database.columns')
427 if context and context.has_key('fk') and context['fk']:
428 if context.has_key('dim_x') and context['dim_x']:
429 dim_obj = self.pool.get('olap.dimension').browse(cr,uid,int(context['dim_x']))
431 make_ids.append(dim_obj.cube_id.table_id.column_link_id.table_id.id)
433 for lines in dim_obj.cube_id.table_id.line_ids:
434 make_ids.append(lines.field_id.related_to.id)
435 make_ids.append(lines.field_id.table_id.id)
436 args = [('table_id','in',make_ids),('related_to','<>',False),('hide','<>',True),('active','<>',False)]
437 return super(olap_database_columns,self).search(cr,uid,args,offset,limit,order,context = context,count = count)
439 if args and context and context.has_key('flag') and context['flag']:
440 ids = args[0][2][0][2]
443 col_obj = col_pool.browse(cr,uid,ids)
445 for lines in col_obj:
446 make_ids.append(lines.related_to.id)
447 link_id = col_pool.browse(cr,uid,int(context['link_col']))
448 make_ids.append(link_id.table_id.id)
449 args = ['|',('table_id','in',make_ids),('related_to','in',make_ids),('primary_key','<>',True),('hide','<>',True),('active','<>',False)]
450 ids = super(olap_database_columns,self).search(cr,uid,args,offset,limit,order,context = context,count = count)
452 elif context and context.has_key('master_dim') and context['master_dim']:
454 col_obj = col_pool.browse(cr,uid,int(context['link_col']))
455 args = ['|',('table_id','=',col_obj.related_to.id),('related_to','=',col_obj.table_id.id),('hide','<>',True),('active','<>',False)]
456 return super(olap_database_columns,self).search(cr,uid,args,offset,limit,order,context = context,count = count)
458 col = col_pool.browse(cr,uid,int(context['link_col']))
459 base_table = col.table_id
460 args = ['|',('table_id','=',base_table.id),('related_to','=',base_table.id),('hide','<>',True),('active','<>',False)]
461 return super(olap_database_columns,self).search(cr,uid,args,offset,limit,order,context = context,count = count)
464 if context and context.has_key('filter_cols_cube'):
465 cube_obj = self.pool.get('olap.cube').browse(cr,uid,int(context['filter_cols_cube']))
467 make_ids.append(cube_obj.table_id.column_link_id.related_to.id)
468 for lines in cube_obj.table_id.line_ids:
469 make_ids.append(lines.table_id.id)
471 make_ids.append(cube_obj.table_id.line_ids[len(cube_obj.table_id.line_ids) - 1].field_id.related_to.id)
472 args = [('table_id','in',make_ids),('related_to','=',False),('primary_key','<>',True),('type','not in',['date','timestamp','timestampz','time']),('hide','<>',True),('active','<>',False)]
473 ids = super(olap_database_columns,self).search(cr,uid,args,offset,limit,
474 order,context = context,count = count)
477 elif context and context.has_key('filter_cols_hier'):
478 hier_obj = self.pool.get('olap.hierarchy').browse(cr,uid,int(context['filter_cols_hier']))
480 if hier_obj.table_id.line_ids:
481 for lines in hier_obj.table_id.line_ids:
482 make_ids.append(lines.field_id.related_to.id)
485 make_ids.append(hier_obj.table_id.column_link_id.related_to.id)
486 make_ids.append(hier_obj.table_id.column_link_id.table_id.id)
487 args = [('table_id','in',make_ids),('hide','<>',True),('active','<>',False)]
488 ids = super(olap_database_columns,self).search(cr,uid,args,offset,limit,
489 order,context = context,count = count)
492 args = [('table_id','=',hier_obj.table_id.column_link_id.related_to.id)]
493 ids = super(olap_database_columns,self).search(cr,uid,args,offset,limit,
494 order,context = context,count = count)
496 elif context and context.has_key('fk') and context['fk']:
497 args = [('primary_key','=',True),('hide','<>',True),('active','<>',False)]
500 if context and context.has_key('master_dim') and context['master_dim']:
501 dim_obj = self.pool.get('olap.dimension').browse(cr,uid,int(context['master_dim']))
502 lines = dim_obj.cube_id.table_id.line_ids
505 table_ids.append(line.table_id.id)
506 args = [('table_id','in',table_ids),('related_to','<>',False),('hide','<>',True),('active','<>',False)]
507 elif context and context.has_key('master_schema') and context['master_schema']:
508 args = [('primary_key','=','True')]
509 return super(olap_database_columns,self).search(cr,uid,args,offset,limit,
510 order,context = context,count = count)
513 def hide_col(self,cr,uid,ids,context = {}):
515 self.write(cr,uid,id,{'hide':True})
518 def show_col(self,cr,uid,ids,context = {}):
520 self.write(cr,uid,id,{'hide':True})
523 def field_add(self,cr,uid,ids,context = {}):
524 col_data = self.pool.get('olap.database.columns').read(cr,uid,ids,[],context)[0]
526 if col_data['related_to']:
527 table_id = col_data['related_to'][0]
529 table_id = col_data['table_id'][0]
530 if context['parent_id']:
531 parent_id = context['parent_id']
533 'cube_table_id':parent_id,
537 id = self.pool.get('olap.cube.table.line').create(cr,uid,val,context)
539 parent_id = self.pool.get('olap.cube.table').create(cr,uid,{'name':col_data['table_id'][1]},context)
540 ctx_list = [('client','web'),('app','bi'),('id',parent_id)]
543 def make_hierarchy(self,cr,uid,ids,context = {}):
544 col_data = self.pool.get('olap.database.columns').read(cr,uid,ids,[],context)[0]
546 if context and context.has_key('hier_parent_id')and context['hier_parent_id']:
547 hier_obj = self.pool.get('olap.hierarchy').browse(cr,uid,context['hier_parent_id'])
548 pk_table = hier_obj.table_id.name
549 elif context and context.has_key('hier_parent_table'):
550 cube_table_obj = self.pool.get('olap.cube.table').browse(cr,uid,context['hier_parent_table'])
551 pk_table = cube_table_obj.name
553 'field_name':col_data['name'],
554 'name':col_data['name'],
555 'primary_key_table':pk_table
557 if context['hier_parent_id']:
558 id = self.pool.get('olap.hierarchy').write(cr,uid,context['hier_parent_id'],val,context)
560 if context['parent_name']: val['name'] = context['parent_name']
561 if context['parent_dimension'] :val['dimension_id'] = context['parent_dimension']
562 if context['hier_parent_table'] : val['table_id'] = context['hier_parent_table']
563 if context['parent_field_name'] : val['field_name'] = context['parent_field_name']
564 if context['parent_level'] : val['level_ids'] = conext['parent_level']
565 if context['parent_member_all']: val['member_all'] = context['parent_member_all']
566 if context['parent_member_default'] : val['member_default'] = context['parent_member_default']
567 if context['parent_type']: val['type'] = context['parent_type']
568 val['primary_key_table'] = col_data['table_id'][1]
569 id = self.pool.get('olap.hierarchy').create(cr,uid,val,context)
570 ctx_list = [('client','web'),('app','bi'),('id',id)]
573 olap_database_columns()
575 class olap_cube_table(osv.osv):
576 _name = "olap.cube.table"
577 _description = "Olap cube table"
579 def write(self,cr,uid,ids,vals,context = None):
580 if vals and vals.get('available_table_ids',0) and context and (context.has_key('master_dim') or context.has_key('d_id') or context.has_key('parent_schema_id')):
581 new_fields = vals['available_table_ids'][0][2]
583 for data in self.browse(cr,uid,ids):
585 for line in data.line_ids:
586 orignal_lines.append(line.id)
589 for line in data.line_ids:
590 orignal_fields.append(line.field_id.id)
591 if len(orignal_fields) < len(new_fields):
592 if new_fields[:len(orignal_fields)] == orignal_fields:
593 new_fields = new_fields[len(orignal_fields):]
594 cols_obj = self.pool.get('olap.database.columns').browse(cr,uid,new_fields)
596 val['cube_table_id'] = ids[0]
598 val['table_id'] = col.table_id.id
599 val['field_id'] = col.id
600 id = self.pool.get('olap.cube.table.line').create(cr,uid,val,context = context)
602 cols_obj = self.pool.get('olap.database.columns').unlink(cr,uid,orignal_lines)
603 cols_obj = self.pool.get('olap.database.columns').browse(cr,uid,new_fields)
605 val['cube_table_id'] = ids[0]
607 val['table_id'] = col.table_id.id
608 val['field_id'] = col.id
609 id = self.pool.get('olap.cube.table.line').create(cr,uid,val,context = context)
611 elif len(orignal_fields) > len(new_fields):
612 if orignal_fields[:len(new_fields)] == new_fields:
613 remove_id = orignal_lines[len(new_fields):]
614 id = self.pool.get('olap.cube.table.line').unlink(cr,uid,remove_id,context = context)
617 id = self.pool.get('olap.cube.table.line').unlink(cr,uid,orignal_lines ,context = context)
618 cols_obj = self.pool.get('olap.database.columns').browse(cr,uid,new_fields)
620 val['cube_table_id'] = ids[0]
622 val['table_id'] = col.table_id.id
623 val['field_id'] = col.id
624 id = self.pool.get('olap.cube.table.line').create(cr,uid,val,context = context)
625 return super(olap_cube_table,self).write(cr,uid,ids,vals,context)
627 def create(self,cr,uid,vals,context = None):
628 cube_table_id = super(olap_cube_table,self).create(cr,uid,vals,context)
629 if vals and vals.get('available_table_ids',0) and context and (context.has_key('d_id') or context.has_key('parent_schema_id') or context.has_key('master_dim') or context.has_key('d_id')):
630 lines_ids = vals['available_table_ids'][0][2]
631 cols_obj = self.pool.get('olap.database.columns').browse(cr,uid,lines_ids)
633 val['cube_table_id'] = cube_table_id
635 val['table_id'] = col.table_id.id
636 val['field_id'] = col.id
637 id = self.pool.get('olap.cube.table.line').create(cr,uid,val,context = context)
640 def search(self,cr,uid,args,offset = 0,limit = None,order = None,
641 context = None,count = False):
642 if context and context.has_key('parent_schema_id'):
643 args = [('schema_id','=',context['parent_schema_id'])]
644 if context and context.has_key('d_id'):
645 dim_obj = self.pool.get('olap.dimension').browse(cr,uid,int(context['d_id']))
646 args = [('schema_id','=',dim_obj.cube_id.schema_id.id)]
647 return super(olap_cube_table,self).search(cr,uid,args,offset,limit,order,context = context,count = count)
649 def _available_table_get(self,cr,uid,ids,name,arg,context = None):
652 parent_table_ids = []
653 field_obj = self.pool.get('olap.database.columns')
654 for table in self.browse(cr,uid,ids,context):
657 ids = map(lambda x: x.field_id.id,table.line_ids)
658 result[table.id] = ids
660 result[table.id] = []
663 def _set_schema(self,cr,uid,context = {}):
664 if context and context.has_key('d_id'):
665 dim_obj = self.pool.get('olap.dimension').browse(cr,uid,int(context['d_id']))
666 return dim_obj.cube_id.schema_id.id
667 if context and context.has_key('parent_schema_id'):
668 return context['parent_schema_id']
670 def _set_name(self,cr,uid,context = {}):
671 if context and context.has_key('d_id'):
672 dim_obj = self.pool.get('olap.dimension').browse(cr,uid,int(context['d_id']))
673 return dim_obj.cubeAid.table_id.name
675 def _get_id(self,cr,uid,ids,context = {}):
676 if context and context.has_key('d_id'):
677 dim_obj = self.pool.get('olap.dimension').browse(cr,uid,int(context['d_id']))
678 table_id = self.pool.get('olap.database.tables').search(cr,uid,[('table_db_name','in',[dim_obj.cube_id.table_id.name]),('fact_database_id','=',dim_obj.cube_id.schema_id.database_id.id)])
679 col_ids = self.pool.get('olap.database.columns').search(cr,uid,[('table_id','in',table_id),('hide','<>',True),('related_to','<>',False)])
681 col_ids = self.pool.get('olap.database.columns').search(cr,uid,[('primary_key','=',True),('hide','<>',True)])
684 def _def_set(self,cr,uid,context = {}):
688 'name': fields.char('Table name',size = 64,required = True),
689 'line_ids': fields.one2many('olap.cube.table.line','cube_table_id','Database Tables',required = True),
690 'schema_id':fields.many2one('olap.schema','Schema id',ondelete = 'cascade'),
691 'column_link_id':fields.many2one('olap.database.columns','Relational Column' ,required = True),
692 'available_table_ids': fields.function(
693 _available_table_get,
695 relation = 'olap.database.columns',
696 string = 'Available Tables',
701 'schema_id':_set_schema,
703 def field_add(self,cr,uid,ids,context = {}):
707 class olap_cube_table_line(osv.osv):
708 _name = "olap.cube.table.line"
709 _description = "Olap cube table"
710 _rec_name = 'table_id'
712 'cube_table_id': fields.many2one('olap.cube.table','Cube Table',required = True,ondelete = 'cascade'),
713 'table_id': fields.many2one('olap.database.tables','Database Table',required = True,ondelete = 'cascade'),
714 'field_id': fields.many2one('olap.database.columns','Link Field'),
716 # Set the Table when changing field_id
717 def onchange_field_id(self,*args,**argv):
719 olap_cube_table_line()
721 class olap_cube(osv.osv):
723 _description = "Olap cube"
725 def _set_schema(self,cr,uid,context = {}):
726 if context and context.has_key('schema_id'):
727 return context['schema_id']
731 'name': fields.char('Cube name',size = 64,required = True),
732 'table_id': fields.many2one('olap.cube.table','Fact table',size = 64,required = True, help="Table(s) for cube."),
733 'schema_id': fields.many2one('olap.schema','Schema',readonly = True),
734 'dimension_ids': fields.one2many('olap.dimension','cube_id','Dimensions'),
735 'measure_ids': fields.one2many('olap.measure','cube_id','Measures'),
736 'query_log': fields.boolean('Query Logging', help = "Enabling this will log all the queries in the browser"),
737 'query_ids': fields.one2many('olap.query.logs','cube_id','Queries'),
740 'schema_id':_set_schema
744 class olap_query_logs(osv.osv):
745 _name = "olap.query.logs"
746 _description = "Olap query logs"
748 'user_id' : fields.many2one('res.users','Tiny ERP User'),
749 'query':fields.text('Query',required = True),
750 'time':fields.datetime('Time',required = True),
751 'result_size':fields.integer('Result Size',readonly = True),
752 'cube_id': fields.many2one('olap.cube','Cube',required = True),
753 'count': fields.integer('Count', readonly=True),
754 'schema_id': fields.many2one('olap.schema','Schema',readonly = True),
755 # 'table_name': fields.char('Table Name', size=164, readonly = True),
759 'count':lambda * args: 0
764 class olap_dimension(osv.osv):
765 _name = "olap.dimension"
766 _description = "Olap dimension"
768 def _set_cube(self,cr,uid,context = {}):
769 if context and context.has_key('cube_id'):
770 return context['cube_id']
774 'name': fields.char('Dimension name',size = 64,required = True),
775 'cube_id': fields.many2one('olap.cube','Cube',required = True),
776 'hierarchy_ids': fields.one2many('olap.hierarchy','dimension_id','Hierarchies'),
784 class olap_hierarchy(osv.osv):
785 _name = "olap.hierarchy"
786 _description = "Olap hierarchy"
787 _order = "sequence, id"
790 'date_year': 'Year of Date',
791 'date_quarter': 'Quarter of Date',
792 'date_month': 'Month of Date',
793 'many2one': 'Many2one'
796 def _set_dimension(self,cr,uid,context = {}):
797 if context and context.has_key('dimension_id'):
798 return context['dimension_id']
801 def _set_name(self,cr,uid,context = {}):
802 if context and context.has_key('dimension_id'):
803 dim_obj = self.pool.get('olap.dimension').browse(cr,uid,int(context['dimension_id']))
807 def _hierarchy_get(self,*args,**argv):
808 return self.hierarchy_type.items()
811 'name': fields.char('Hierarchy name',size = 64,required = True),
812 'primary_key': fields.char('Primary key',size = 64),
813 'primary_key_table': fields.char('Primary key table',size = 64),
814 'sequence': fields.integer('Sequence',required = True),
815 'dimension_id': fields.many2one('olap.dimension','Dimension',required = True),
816 'level_ids': fields.one2many('olap.level','hierarchy_id','Levels'),
817 'table_id': fields.many2one('olap.cube.table','Fact table(s)',required = True , help ="Table(s) to make hierarchy on the cube."),
820 'sequence': lambda * args: 1,
821 'primary_key': lambda * args: 'id',
822 'dimension_id':_set_dimension,
828 class olap_level(osv.osv):
830 _description = "Olap level"
831 _order = "sequence, id"
833 'normal': levels.level_normal(),
834 'date_year': levels.level_date_year(),
835 'date_quarter': levels.level_date_quarter(),
836 'date_month': levels.level_date_month()
839 def _set_hierarchy(self,cr,uid,context = {}):
840 if context and context.has_key('hierarchy_id'):
841 return context['hierarchy_id']
844 def _set_name(self,cr,uid,context = {}):
845 if context and context.has_key('hierarchy_id'):
846 hier_obj = self.pool.get('olap.hierarchy').browse(cr,uid,int(context['hierarchy_id']))
849 def onchange_column_name(self,cr,uid,ids,column,context = {}):
853 col = self.pool.get('olap.database.columns').browse(cr,uid,column)
854 val['table_name'] = col.table_id.table_db_name
855 val['column_id_name'] = col.column_db_name
856 if (col.type == 'date'):
857 val['type'] = 'date_year'
860 def _type_get(self,cr,uid,*args,**argv):
861 keys = self._types.keys()
862 return map(lambda x: (x,x),keys)
866 'name': fields.char('Level name',size = 64,required = True),
867 'column_name':fields.many2one('olap.database.columns','Columns Name',required = True),
868 'column_id_name': fields.char('Column ID',size = 64,required = True),
869 'type': fields.selection(selection = _type_get,string = 'Level class',size = 64,required = True),
870 'table_name': fields.char('Table name',size = 64,required = True,help = "The name of the table on which the column is defined. If False, take the table from the hierarchy."),
871 'sequence': fields.integer('Sequence',required = True),
872 'hierarchy_id': fields.many2one('olap.hierarchy','Hierarchy',required = True),
876 'column_id_name': lambda * args: 'name',
877 'sequence':lambda * args: '1',
878 'type':lambda * args:'normal',
879 'hierarchy_id':_set_hierarchy,
886 class olap_measure(osv.osv):
887 _name = "olap.measure"
888 _description = "Olap measure"
890 def _set_cube(self,cr,uid,context = {}):
891 if context and context.has_key('cube_id'):
892 return context['cube_id']
895 def onchange_measure_name(self,cr,uid,ids,column,context = {}):
899 col = self.pool.get('olap.database.columns').browse(cr,uid,column)
900 val['table_name'] = col.table_id.table_db_name
901 val['value_column_id_name'] = col.column_db_name
902 val['name'] = col.column_db_name
906 'name': fields.char('Measure name',size = 64,required = True),
907 'cube_id': fields.many2one('olap.cube','Cube',required = True),
908 'value_column': fields.many2one('olap.database.columns','Fact Table Column'),
909 'value_column_id_name': fields.char('Column ID',size = 64),
910 'table_name': fields.char('Table name',size = 64,help = "The name of the table on which the column is defined. If False, take the table from the cube."),
911 'measure_type':fields.selection([('fact_column','Fact Table Column'),('sql_expr','SQL Expression')],'Measure Type',required = True,help = "Select between auto column or sql expression for the measures"),
912 'value_sql': fields.char('SQL Expression',size = 200,help = "You can provide valid sql expression. Make sure it have function with fully qualified column name like (sum,avg ...)(tablename.columnname (+,- ...) tablename.columnname)"),
913 'agregator': fields.selection([('sum','Sum'),('count','count'),('avg','Average')],'Agregator',required = True),
914 'datatype': fields.selection([('int','Integer'),('float','Float')],'Datatype',required = True),
915 'formatstring': fields.selection([
916 ('none','None (0000.00)'),
917 ('cr_prefix','Prefix Default Currency (EUR 0000.00)'),
918 ('cr_postfix','Postfix Default Currency(0000.00 EUR)'),
919 ('cr_prefix_comma','Prefix Default Currency with comma seperator (EUR 0,000.00)'),
920 ('cr_postfix_comma','Postfix Default Currency with comma seperator (0,000.00 EUR)'),
921 ('comma_sep', 'Comma Seperator (0,000)')
923 'Format string',required = True, help=" Let you specify how the measure to be displayed in cube browser"),
926 'agregator': lambda * args: 'sum',
927 'datatype': lambda * args: 'float',
928 'formatstring': lambda * args: 'none',
930 'measure_type':lambda * args:'fact_column',
934 class olap_application(osv.osv):
935 _name = "olap.application"
936 _description = "Olap application"
938 'name': fields.char('Application name',size = 64,required = True),
939 'query':fields.text('Application Query'),
940 'table_ids':fields.one2many('olap.application.table','application_id','Tables'),
941 'field_ids': fields.one2many('olap.application.field','application_id','Fields'),
946 class olap_application_table(osv.osv):
947 _name = "olap.application.table"
948 _description = "Olap application table"
950 'name': fields.char('Application table name',size = 64,required = True),
951 'table_name': fields.char('Table name',size = 64,required = True),
952 'is_hidden': fields.boolean('Hidden'),
953 'application_id': fields.many2one('olap.application','Application Id',required = True),
955 olap_application_table()
957 class olap_application_field(osv.osv):
958 _name = "olap.application.field"
959 _description = "Olap application field"
961 'name': fields.char('Application field name',size = 64,required = True),
962 'table_name': fields.char('Application table name',size = 64),
963 'field_name':fields.char('Field name',size = 64),
964 'is_hidden': fields.boolean('Hidden'),
965 'application_id': fields.many2one('olap.application','Application Id',required = True),
967 olap_application_field()
969 class olap_saved_query(osv.osv):
970 _name = "olap.saved.query"
971 _decription = "Olap Saved Query"
972 # _rec_name = 'user_id'
974 'name': fields.text('Query Name',size = 64),
975 'user_id' : fields.many2one('res.users','User'),
976 'query': fields.text('Query',required = True),
977 'cube_id': fields.many2one('olap.cube','Cube',required = True),
978 'mdx_id': fields.char('Module', size=64),
979 'schema_id': fields.many2one('olap.schema','Schema',required = True),
980 'time':fields.datetime('Time',required = True),
981 'axis_keys': fields.text('Axis Keys'),
984 # Wizard for the Load Data Structure
985 # Replacement for the Load Wizard according to the new structure
986 class bi_load_db_wizard(osv.osv_memory):
987 _name = 'bi.load.db.wizard'
989 def _get_fact_table(self,cr,uid,ctx):
990 if ctx and ctx.has_key('active_id'):
991 schema_obj = self.pool.get('olap.schema').browse(cr,uid,ctx['active_id'])
992 return schema_obj.name
995 def _get_db_name(self,cr,uid,ctx):
996 if ctx and ctx.has_key('active_id'):
997 schema_obj = self.pool.get('olap.schema').browse(cr,uid,ctx['active_id'])
998 return schema_obj.database_id.name
1002 'fact_table':fields.char('Fact Name' ,size = 64,readonly = True),
1003 'db_name':fields.char('Database Name',size = 64,readonly = True)
1007 'fact_table':_get_fact_table,
1008 'db_name':_get_db_name,
1011 def action_load(self,cr,uid,ids,context = None):
1012 if context and context.has_key('active_id'):
1013 lines = self.pool.get('olap.schema').browse(cr,uid,context['active_id'])
1014 pool = pooler.get_pool(cr.dbname)
1015 # lines=pool.get('olap.schema').browse(cr, uid, part['id'],context)
1016 id_db = lines.database_id.id
1017 type = lines.database_id.type
1018 db_name = lines.database_id.db_name
1019 tobj = pool.get('olap.database.tables')
1020 tcol = pool.get('olap.database.columns')
1021 if type == 'postgres':
1022 # host = lines.database_id.db_host and "host=%s" % lines.database_id.db_host or ''
1023 # port = lines.database_id.db_port and "port=%s" % lines.database_id.db_port or ''
1024 # name = lines.database_id.db_name and "dbname=%s" % lines.database_id.db_name or ''
1025 # user = lines.database_id.db_login and "user=%s" % lines.database_id.db_login or ''
1026 # password = lines.database_id.db_password and "password=%s" % lines.database_id.db_password or ''
1027 # tdb = psycopg2.connect('%s %s %s %s %s' % (host, port, name, user, password))
1028 # cr_db = tdb.cursor()
1029 # cr.execute('select table_db_name,id from olap_database_tables where fact_database_id=%d', (id_db,))
1030 # tables = dict(cr.fetchall())
1031 # # Format for storing the tables
1032 # # tables['table_db_name']=id
1033 # tables_id = map(lambda x: str(tables[x]),tables)
1036 # cr.execute('select column_db_name,id,table_id from olap_database_columns where table_id in (' + ','.join(tables_id) +')')
1038 # cr.execute('select column_db_name,id,table_id from olap_database_columns')
1040 # for data in cr.fetchall():
1041 # cols[str(data[1])]=(data[0],int(data[2]))
1042 # # Format of storing the cols
1043 # # cols['id']=(col_db_name,table_id)
1044 # print 'Creating / Updating Tables...'
1045 # cr_db.execute("select table_name, table_catalog from INFORMATION_SCHEMA.tables as a where a.table_schema = 'public'")
1046 # for table in cr_db.fetchall():
1048 # 'fact_database_id':id_db,
1049 # 'table_db_name':table[0]
1052 # if table[0] in tables.keys():
1053 # table_id=tobj.write(cr,uid,[tables[table[0]]], val, context)
1055 # val['name']=table[0]
1056 # tables[val['name']] = tobj.create(cr,uid,val, context)
1057 # print 'Creating / Updating Columns...'
1058 # cr_db.execute("""SELECT
1059 # table_name, column_name, udt_name
1061 # INFORMATION_SCHEMA.columns
1062 # WHERE table_schema = 'public'""")
1064 # for col in cr_db.fetchall():
1066 # 'table_id': tables[col[0]],
1067 # 'column_db_name': col[1],
1071 # id_made=filter(lambda x:(int(cols[x][1])==int(tables[col[0]])),cols)
1072 # if col[1] in cols.keys() and col[0] in tables.keys()and id_made:
1073 # col_id=tcol.write(cr,uid,cols[tables[str(col[0])]], val, context)
1075 # val['name']=col[1]
1076 # id_made = tcol.create(cr,uid,val, context)
1077 # cols[str(id_made)] = (val['name'],int(val['table_id']))
1078 # print 'Creating / Updating Constraints...'
1079 # cr_db.execute("""select
1080 # table_name,column_name
1082 # INFORMATION_schema.key_column_usage
1084 # constraint_name in (
1085 # select constraint_name from INFORMATION_SCHEMA .table_constraints
1087 # constraint_type = 'PRIMARY KEY')""")
1088 # print "Updating the Primary Key Constraint"
1089 # for constraint in cr_db.fetchall():
1091 # 'primary_key':True
1094 # id_to_write=filter(lambda x:(int(cols[x][1])==int(tables[constraint[0]])and(constraint[1]==cols[x][0])),cols)
1095 # col_id=tcol.write(cr,uid,int(id_to_write[0]),val,context)
1096 # print "Updating the Foreign key constraint"
1097 # cr_db.execute("""select
1098 # constraint_name,table_name
1100 # INFORMATION_schema.constraint_column_usage
1102 # constraint_name in (
1103 # select constraint_name from INFORMATION_SCHEMA.table_constraints
1105 # constraint_type = 'FOREIGN KEY')""")
1106 # for_key=dict(cr_db.fetchall())
1108 # cr_db.execute("""select
1109 # table_name,column_name,constraint_name
1111 # INFORMATION_schema.key_column_usage
1113 # constraint_name in (
1114 # select constraint_name from INFORMATION_SCHEMA.table_constraints
1116 # constraint_type = 'FOREIGN KEY')""")
1118 # for constraint in cr_db.fetchall():
1120 # 'related_to':tables[for_key[constraint[2]]]
1122 # id_to_write=filter(lambda x:(int(cols[x][1])==int(tables[constraint[0]])and (constraint[1]==cols[x][0])),cols)
1123 # col_id=tcol.write(cr,uid,int(id_to_write[0]),val,context)
1125 host = lines.database_id.db_host and "host=%s" % lines.database_id.db_host or ''
1126 port = lines.database_id.db_port and "port=%s" % lines.database_id.db_port or ''
1127 name = lines.database_id.db_name and "dbname=%s" % lines.database_id.db_name or ''
1128 user = lines.database_id.db_login and "user=%s" % lines.database_id.db_login or ''
1129 password = lines.database_id.db_password and "password=%s" % lines.database_id.db_password or ''
1130 tdb = psycopg2.connect('%s %s %s %s %s' % (host,port,name,user,password))
1131 cr_db = tdb.cursor()
1132 cr.execute('select table_db_name,id from olap_database_tables where fact_database_id=%d',(id_db,))
1133 tables = dict(cr.fetchall())
1134 # Format for storing the tables
1135 # tables['table_db_name']=id
1136 tables_id = map(lambda x: str(tables[x]),tables)
1137 # Format of storing the cols
1138 # cols['id']=(col_db_name,table_id)
1139 print 'Creating / Updating Tables...'
1140 cr_db.execute("select table_name, table_catalog from INFORMATION_SCHEMA.tables as a where a.table_schema = 'public'")
1141 for table in cr_db.fetchall():
1143 'fact_database_id':id_db,
1144 'table_db_name':table[0]
1146 if table[0] in tables.keys():
1147 table_id = tobj.write(cr,uid,[tables[table[0]]],val,context)
1149 val['name'] = table[0]
1150 tables[val['name']] = tobj.create(cr,uid,val,context)
1152 print 'Creating / Updating Columns ....'
1155 cr.execute('select column_db_name,id,table_id from olap_database_columns where table_id in (' + ','.join(tables_id) + ')')
1157 # cr.execute('select column_db_name,id,table_id from olap_database_columns ')
1158 cr.execute("select olap_database_columns.column_db_name, olap_database_columns.id, olap_database_columns.table_id from olap_database_columns join olap_database_tables on olap_database_columns.table_id = olap_database_tables.id where olap_database_tables.fact_database_id=%d",(id_db,))
1162 table_col[str(tables[x])] = [{}]
1163 for data in cr.fetchall():
1164 cols[str(data[1])] = (data[0],int(data[2]))
1165 table_col[str(data[2])][0][data[0]] = data[1]
1166 cols_name[str(data[0])] = (data[1],int(data[2]))
1167 cr_db.execute("""SELECT
1168 table_name, column_name, udt_name
1170 INFORMATION_SCHEMA.columns
1171 WHERE table_schema = 'public'""")
1172 for col in cr_db.fetchall():
1174 'table_id': tables[col[0]],
1175 'column_db_name': col[1],
1178 id_made = filter(lambda x:(int(cols[x][1]) == int(tables[col[0]])),cols)
1179 if col[0] in tables.keys() and col[1] in cols_name.keys() and id_made:
1180 if table_col[str(tables[col[0]])][0] and col[1] in table_col[str(tables[col[0]])][0].keys():
1181 col_id = tcol.write(cr,uid,table_col[str(tables[col[0]])][0][col[1]],val,context)
1183 val['name'] = col[1]
1184 id_made = tcol.create(cr,uid,val,context)
1185 cols[str(id_made)] = (val['name'],int(val['table_id']))
1187 val['name'] = col[1]
1188 id_made = tcol.create(cr,uid,val,context)
1189 cols[str(id_made)] = (val['name'],int(val['table_id']))
1191 print 'Creating / Updating Constraints...'
1192 cr_db.execute("""select
1193 table_name,column_name
1195 INFORMATION_schema.key_column_usage
1197 constraint_name in (
1198 select constraint_name from INFORMATION_SCHEMA .table_constraints
1200 constraint_type = 'PRIMARY KEY')""")
1202 print "Updating the Primary Key Constraint"
1203 for constraint in cr_db.fetchall():
1208 id_to_write = filter(lambda x:(int(cols[x][1]) == int(tables[constraint[0]])and(constraint[1] == cols[x][0])),cols)
1209 col_id = tcol.write(cr,uid,int(id_to_write[0]),val,context)
1211 print "Updating the Foreign key constraint"
1212 cr_db.execute("""select
1213 constraint_name,table_name
1215 INFORMATION_schema.constraint_column_usage
1217 constraint_name in (
1218 select constraint_name from INFORMATION_SCHEMA.table_constraints
1220 constraint_type = 'FOREIGN KEY')""")
1221 for_key = dict(cr_db.fetchall())
1223 cr_db.execute("""select
1224 table_name,column_name,constraint_name
1226 INFORMATION_schema.key_column_usage
1228 constraint_name in (
1229 select constraint_name from INFORMATION_SCHEMA.table_constraints
1231 constraint_type = 'FOREIGN KEY')""")
1233 for constraint in cr_db.fetchall():
1235 'related_to':tables[for_key[constraint[2]]]
1237 id_to_write = filter(lambda x:(int(cols[x][1]) == int(tables[constraint[0]])and (constraint[1] == cols[x][0])),cols)
1239 col_id = tcol.write(cr,uid,int(id_to_write[0]),val,context)
1242 elif type == 'mysql':
1245 host = lines.database_id.db_host or ''
1246 port = lines.database_id.db_port or ''
1247 db = lines.database_id.db_name or ''
1248 user = lines.database_id.db_login or ''
1249 passwd = lines.database_id.db_password or ''
1250 tdb = MySQLdb.connect(host = host,port = port,db = db,user = user,passwd = passwd)
1253 raise osv.except_osv('MySQLdb Packages Not Installed.',e)
1255 cr_db = tdb.cursor()
1256 cr.execute('select table_db_name,id from olap_database_tables where fact_database_id=%d',(id_db,))
1257 tables = dict(cr.fetchall())
1258 tables_id = map(lambda x: str(tables[x]),tables)
1261 cr.execute('select column_db_name,id,table_id from olap_database_columns where table_id in (' + ','.join(tables_id) + ')')
1263 cr.execute('select column_db_name,id,table_id from olap_database_columns')
1265 for data in cr.fetchall():
1266 cols[str(data[1])] = (data[0],int(data[2]))
1267 cr_db.execute("select table_name, table_catalog from INFORMATION_SCHEMA.tables where table_schema =%s",(db_name))
1269 for table in cr_db.fetchall():
1271 'fact_database_id':id_db,
1272 'table_db_name':table[0]
1275 if table[0] in tables.keys():
1276 table_id = tobj.write(cr,uid,[tables[table[0]]],val,context)
1279 val['name'] = table[0]
1280 tables[val['name']] = tobj.create(cr,uid,val,context)
1281 cr_db.execute("""SELECT
1282 table_name, column_name, data_type
1284 INFORMATION_SCHEMA.columns
1285 WHERE table_schema = %s""",(db_name))
1287 for col in cr_db.fetchall():
1290 'table_id': tables[col[0]],
1291 'column_db_name': col[1],
1295 id_made = filter(lambda x:(int(cols[x][1]) == int(tables[col[0]])),cols)
1296 if col[1] in cols.keys() and col[0] in tables.keys()and id_made:
1297 col_id = tcol.write(cr,uid,cols[tables[str(col[0])]],val,context)
1299 val['name'] = col[1]
1300 id_made = tcol.create(cr,uid,val,context)
1301 cols[str(id_made)] = (val['name'],int(val['table_id']))
1303 cr_db.execute("""select
1304 REFERENCED_COLUMN_NAME,REFERENCED_TABLE_NAME,COLUMN_NAME,TABLE_NAME
1306 INFORMATION_schema.key_column_usage
1307 where table_schema= %s and
1308 constraint_name in (
1309 select constraint_name from INFORMATION_SCHEMA .table_constraints
1311 constraint_type in('PRIMARY KEY','FOREIGN KEY'))
1313 # lines=pool.get('olap.schema').browse(cr, uid, part['id'],context)
1314 for constraint in cr_db.fetchall():
1318 'related_to':tables[constraint[1]]
1325 id_to_write = filter(lambda x:(int(cols[x][1]) == int(tables[constraint[3]])and(constraint[2] == cols[x][0])),cols)
1326 col_id = tcol.write(cr,uid,int(id_to_write[0]),val,context)
1328 elif type == 'oracle':
1331 host = lines.database_id.db_host or ''
1332 port = lines.database_id.db_port or ''
1333 db = lines.database_id.db_name or ''
1334 user = lines.database_id.db_login.upper() or ''
1335 passwd = lines.database_id.db_password or ''
1336 tdb = cx_Oracle.connect(user,passwrd,host)
1339 raise osv.except_osv('cx_Oracle Packages Not Installed.',e)
1341 cr_db = tdb.cursor()
1342 cr.execute('select table_db_name,id from olap_database_tables where fact_database_id=%d',(id_db,))
1343 tables = dict(cr.fetchall())
1344 tables_id = map(lambda x: str(tables[x]),tables)
1347 cr.execute('select column_db_name,id,table_id from olap_database_columns where table_id in (' + ','.join(tables_id) + ')')
1349 cr.execute('select column_db_name,id,table_id from olap_database_columns')
1351 for data in cr.fetchall():
1352 cols[str(data[1])] = (data[0],int(data[2]))
1354 cr_db.execute("select table_name from all_tables where owner =%s",(user))
1355 temp = cr_db.fetchall()
1358 'fact_database_id':id_db,
1359 'table_db_name':table[0]
1362 if table[0] in tables.keys():
1363 table_id = tobj.write(cr,uid,[tables[table[0]]],val,context)
1366 val['name'] = table[0]
1367 tables[val['name']] = tobj.create(cr,uid,val,context)
1369 cr_db.execute("""SELECT
1370 table_name, column_name, data_type
1373 WHERE owner = %s""",(user))
1374 temp = cr_db.fetchall()
1376 if col[2] == 'NUMBER':
1377 type_col = 'numeric'
1378 elif col[2] == 'DATE':
1380 elif col[2] == 'VARCHAR2':
1381 type_col = 'varchar'
1385 'table_id': tables[col[0]],
1386 'column_db_name': col[1],
1390 id_made = filter(lambda x:(int(cols[x][1]) == int(tables[col[0]])),cols)
1391 if col[1] in cols.keys() and col[0] in tables.keys()and id_made:
1392 col_id = tcol.write(cr,uid,cols[tables[str(col[0])]],val,context)
1394 val['name'] = col[1]
1395 id_made = tcol.create(cr,uid,val,context)
1396 cols[str(id_made)] = (val['name'],int(val['table_id']))
1398 cr_db.execute("""select
1399 table_name,column_name,constraint_name
1403 constraint_name in (
1404 select constraint_name from all_constraints
1406 constraint_type = 'P' and owner= %s)
1408 temp = cr_db.fetchall()
1410 for constraint in temp:
1412 'primary_key' : True
1414 pk_table[constraint[2]] = constraint[0]
1416 id_to_write = filter(lambda x : (int(cols[x][1]) == int(tables[constraint[0]])and(constraint[1] == cols[x][0])),cols)
1417 col_id = tcol.write(cr,uid,int(id_to_write[0]),val,context)
1419 cr_db.execute("""select
1420 constraint_name,r_constraint_name from all_constraints
1422 constraint_type = 'R' and owner = %s
1424 constraints_map = {}
1425 for data in cr_db.fetchall():
1426 constraints_map[data[0]] = data[1]
1428 cr_db.execute("""select
1429 table_name,column_name,constraint_name
1433 constraint_name in (
1434 select constraint_name from all_constraints
1436 constraint_type = 'R' and owner = %s)
1440 temp = cr_db.fetchall()
1441 for constraint in temp:
1442 rel_constraint_name = constraints_map[constraint[2]]
1443 req_table = pk_table[rel_constraint_name]
1445 'related_to' : tables[req_table]
1447 id_to_write = filter(lambda x:(int(cols[x][1]) == int(tables[constraint[0]])and (constraint[1] == cols[x][0])),cols)
1448 col_id = tcol.write(cr,uid,int(id_to_write[0]),val,context)
1450 temp = pooler.get_pool(cr.dbname).get('olap.fact.database').write(cr,uid,[id_db],{'loaded':True})
1451 wf_service = netsvc.LocalService('workflow')
1452 wf_service.trg_validate(uid,'olap.schema',context['active_id'],'dbload',cr)
1453 model_data_ids = self.pool.get('ir.model.data').search(cr,uid,[('model','=','ir.ui.view'),('name','=','view_olap_schema_form')])
1454 resource_id = self.pool.get('ir.model.data').read(cr,uid,model_data_ids,fields = ['res_id'])[0]['res_id']
1456 return {'type':'ir.actions.act_window_close' }
1459 # 'name': 'view_olap_schema_form',
1460 # 'view_type': 'form',
1461 # 'view_mode': 'form,tree',
1462 # 'res_id': context['active_id'],
1463 # 'res_model': 'olap.schema',
1464 # 'view': [(resource_id,'form')],
1465 # 'type': 'ir.actions.act_window_close'
1469 def action_cancel(self,cr,uid,ids,context = None):
1471 return {'type':'ir.actions.act_window_close' }
1477 # Wizard for the Automatic Application Configuration
1478 # Replacement for the Load Wizard according to the new structure
1479 class bi_auto_configure_wizard(osv.osv_memory):
1480 _name = 'bi.auto.configure.wizard'
1483 def _get_name(self,cr,uid,ctx):
1484 if ctx and ctx.has_key('active_id'):
1485 schema_obj = self.pool.get('olap.schema').browse(cr,uid,ctx['active_id'])
1486 return schema_obj.name
1490 'name':fields.char('Fact Name' ,size = 64,readonly = True),
1498 def action_load(self,cr,uid,ids,context = None):
1501 appfieldnew_vals = {}
1503 ids = pooler.get_pool(cr.dbname).get('olap.schema').browse(cr,uid,context['active_id'])
1505 if ids.app_detect == "Unknown Application":
1506 raise wizard.except_wizard('Warning','The Application is Unknown, we can not configure it automatically.')
1509 app_objs = pooler.get_pool(cr.dbname).get('olap.application')
1510 app_ids = app_objs.search(cr,uid,[])
1511 app_res = app_objs.browse(cr,uid,app_ids)
1513 for x_app in app_res:
1514 app_id = x_app['id']
1516 apptab_objs = pooler.get_pool(cr.dbname).get('olap.application.table')
1517 apptab_ids = apptab_objs.search(cr,uid,[])
1518 apptab_res = apptab_objs.browse(cr,uid,apptab_ids)
1520 map_apptab_name = {}
1521 map_apptab_name_id = {}
1522 for aptab in apptab_res:
1523 apptab_name.append(aptab.name)
1524 map_apptab_name_id[aptab.table_name] = aptab
1526 appfield_objs = pooler.get_pool(cr.dbname).get('olap.application.field')
1527 appfield_ids = appfield_objs.search(cr,uid,[])
1528 appfield_res = appfield_objs.browse(cr,uid,appfield_ids)
1529 appfield_data_res = appfield_objs.browse(cr,uid,appfield_ids)
1531 for apcol in appfield_res:
1532 appcol_name.append(apcol.name)
1534 dbtab_obj = pooler.get_pool(cr.dbname).get('olap.database.tables')
1535 # id_tables=dbtab_obj.search(cr,uid,[('fact_database_id','=',ids.database_id.id),('table_db_name','not in',['inherit','res_roles','user_rule_group_rel','res_roles_users_rel','group_rule_group_rel'])])
1536 id_tables = dbtab_obj.search(cr,uid,[('fact_database_id','=',ids.database_id.id)])
1537 tables_main = dbtab_obj.read(cr,uid,id_tables,context = {'wizard':True})
1538 for tables in tables_main:
1539 end_user_name = {'name':(" ").join(map(lambda x:x.capitalize(),tables['table_db_name'].split("_")))}
1540 table_new = dbtab_obj.write(cr,uid,tables['id'],end_user_name)
1541 if not(tables['table_db_name'].startswith('ir') or tables['table_db_name'].startswith('wkf') or tables['table_db_name'].startswith('res_groups') or tables['table_db_name'].startswith('res_role')) and tables['table_db_name'] not in ['inherit','user_rule_group_rel','group_rule_group_rel']:
1544 if len(apptab_ids) == 0 and (tables['table_db_name'] not in apptab_name):
1545 vals['table_name'] = tables['table_db_name']
1546 vals['name'] = (" ").join(map(lambda x:x.capitalize(),tables['name'].split("_")))
1547 vals['is_hidden'] = tables['hide']
1548 vals['application_id'] = app_id
1549 table_new = dbtab_obj.write(cr,uid,tables['id'],{'hide':False})
1550 apptab_new_obj = apptab_objs.create(cr,uid,vals)
1552 if map_apptab_name_id.has_key(tables['table_db_name']):
1553 app_table = map_apptab_name_id[tables['table_db_name']]
1554 if ((app_table['table_name'] == tables['table_db_name']) and not (app_table['table_name'] == tables['name'])):
1555 vals['name'] = (" ").join(map(lambda x:x.capitalize(),tables['name'].split("_")))
1556 vals['is_hidden'] = tables['hide']
1557 tables_obj_new = apptab_objs.write(cr,uid,app_table['id'],vals)
1559 vals['table_name'] = tables['table_db_name']
1560 vals['name'] = (" ").join(map(lambda x:x.capitalize(),tables['table_db_name'].split("_")))
1561 vals['is_hidden'] = tables['hide']
1562 vals['application_id'] = app_id
1563 apptab_new_obj = apptab_objs.create(cr,uid,vals)
1564 id_columns = pooler.get_pool(cr.dbname).get('olap.database.columns').search(cr,uid,[('table_id','in',id_tables)])
1565 columns = pooler.get_pool(cr.dbname).get('olap.database.columns').read(cr,uid,id_columns,[])
1566 for columns in columns:
1568 if len(appfield_ids) == 0 and (columns['column_db_name'] not in appcol_name):
1569 vals['field_name'] = columns['column_db_name']
1570 vals['table_name'] = columns['table_id'][1]
1571 vals['name'] = (" ").join(map(lambda x:x.capitalize(),columns['name'].split("_")))
1572 vals['is_hidden'] = columns['hide']
1573 vals['application_id'] = x_app['id']
1574 appfield_new_obj = appfield_objs.create(cr,uid,vals)
1576 filter_column = filter(lambda x: columns['column_db_name'] == x['field_name'] and columns['table_id'][1] == x['table_name'],appfield_data_res)
1577 if map_apptab_name_id.has_key(columns['table_id'][1]) and filter_column:
1578 table_id_write = map_apptab_name_id[columns['table_id'][1]]
1579 vals['name'] = (" ").join(map(lambda x:x.capitalize(),columns['name'].split("_")))
1580 vals['is_hidden'] = columns['hide']
1581 appfield_new_obj = appfield_objs.write(cr,uid,filter_column[0]['id'],vals)
1583 vals['field_name'] = columns['column_db_name']
1584 vals['table_name'] = columns['table_id'][1]
1585 vals['name'] = (" ").join(map(lambda x:x.capitalize(),columns['name'].split("_")))
1586 vals['is_hidden'] = columns['hide']
1587 vals['application_id'] = x_app['id']
1588 appfield_new_obj = appfield_objs.create(cr,uid,vals)
1591 database_tables = pooler.get_pool(cr.dbname).get('olap.database.tables')
1592 id_tables = database_tables.search(cr,uid,[('fact_database_id','=',ids.database_id.id)])
1593 tables = database_tables.read(cr,uid,id_tables,[])
1595 for table in tables:
1597 if (table['table_db_name'].startswith('ir') or table['table_db_name'].startswith('wkf')) or (table['table_db_name'].startswith('res_groups')) or (table['table_db_name'] in ['inherit','res_roles','user_rule_group_rel','res_roles_users_rel','group_rule_group_rel']):
1599 vals['active'] = False
1600 make_id.append(table['id'])
1601 database_tables.write(cr,uid,table['id'],vals)
1603 database_columns = pooler.get_pool(cr.dbname).get('olap.database.columns')
1604 id_columns = database_columns.search(cr,uid,[('table_id','in',make_id)])
1605 columns = database_columns.read(cr,uid,id_columns,[])
1609 vals['active'] = False
1610 database_columns.write(cr,uid,col['id'],vals)
1613 wf_service = netsvc.LocalService('workflow')
1614 wf_service.trg_validate(uid,'olap.schema',context['active_id'],'dbconfigure',cr)
1615 model_data_ids = self.pool.get('ir.model.data').search(cr,uid,[('model','=','ir.ui.view'),('name','=','view_olap_schema_form')])
1616 resource_id = self.pool.get('ir.model.data').read(cr,uid,model_data_ids,fields = ['res_id'])[0]['res_id']
1618 return {'type':'ir.actions.act_window_close' }
1620 def action_cancel(self,cr,uid,ids,context = None):
1622 return {'type':'ir.actions.act_window_close' }
1624 bi_auto_configure_wizard()
1627 class olap_warehouse_wizard(osv.osv_memory):
1628 _name = "olap.warehouse.wizard"
1629 _description = "Olap Warehouse"
1631 def _get_queries(self, cr, uid, context = {}):
1632 query_obj = self.pool.get('olap.query.logs')
1633 qry_ids = query_obj.search(cr, uid, [('user_id','=',uid),('count','>=',3)])
1636 for id in query_obj.browse(cr,uid,qry_ids,context):
1640 query = query + '\n'+id.query
1644 def action_ok(self, cr, uid, ids, context = {}):
1645 return {'type':'ir.actions.act_window_close' }
1648 'query': fields.text('Query', readonly=True),
1651 'query': _get_queries,
1653 olap_warehouse_wizard()
1654 class olap_parameters_config_wizard(osv.osv_memory):
1655 _name = "olap.parameters.config.wizard"
1656 _description = "Olap Server Parameters"
1658 def _get_host(self,cr,uid,context = None):
1659 obj = self.pool.get('olap')
1660 objid = self.pool.get('ir.model.data')
1661 aid = objid._get_id(cr,uid,'olap','menu_url_cube_browser')
1662 aid = objid.browse(cr,uid,aid,context = context).res_id
1663 aid = self.pool.get('ir.actions.url').browse(cr,uid,aid,context = context)
1664 s_p = Literal("http://").suppress() + Word(alphanums + "_" + ".") + Literal(":").suppress() + Word(nums) + Literal("/").suppress() + Word(alphanums + "_" + " ").suppress()
1665 return s_p.parseString(aid.url)[0]
1667 def _get_port(self,cr,uid,context = None):
1668 obj = self.pool.get('olap')
1669 objid = self.pool.get('ir.model.data')
1670 aid = objid._get_id(cr,uid,'olap','menu_url_cube_browser')
1671 aid = objid.browse(cr,uid,aid,context = context).res_id
1672 aid = self.pool.get('ir.actions.url').browse(cr,uid,aid,context = context)
1673 s_p = Literal("http://").suppress() + Word(alphanums + "_" + ".") + Literal(":").suppress() + Word(nums) + Literal("/").suppress() + Word(alphanums + "_" + " ").suppress()
1674 return s_p.parseString(aid.url)[1]
1677 'host_name' : fields.char('Server Name',size = 64,help = "Put here the server address or IP \
1678 Put localhost if its not clear.",required = True),
1679 'host_port' : fields.char('Port',size = 4,help = "Put the port for the server. Put 8080 if \
1680 its not clear.",required = True),
1684 'host_name': _get_host,
1685 'host_port': _get_port,
1688 def action_cancel(self,cr,uid,ids,conect = None):
1690 'view_type': 'form',
1691 "view_mode": 'form',
1692 'res_model': 'ir.actions.configuration.wizard',
1693 'type': 'ir.actions.act_window',
1697 def action_config(self,cr,uid,ids,context = None):
1698 conf = self.browse(cr,uid,ids[0],context)
1699 obj = self.pool.get('olap')
1700 objid = self.pool.get('ir.model.data')
1701 aid = objid._get_id(cr,uid,'olap','menu_url_cube_browser')
1702 aid = objid.browse(cr,uid,aid,context = context).res_id
1703 self.pool.get('ir.actions.url').write(cr,uid,[aid],{'url': 'http://' + (conf.host_name or 'localhost') + ':' + (conf.host_port or '8080') + '/browser'})
1705 aid = objid._get_id(cr,uid,'olap','menu_url_cube_designer')
1706 aid = objid.browse(cr,uid,aid,context = context).res_id
1707 self.pool.get('ir.actions.url').write(cr,uid,[aid],{'url': 'http://' + (conf.host_name or 'localhost') + ':' + (conf.host_port or '8080') + '/designer'})
1710 'view_type': 'form',
1711 "view_mode": 'form',
1712 'res_model': 'ir.actions.configuration.wizard',
1713 'type': 'ir.actions.act_window',
1716 olap_parameters_config_wizard()
1718 # vim: ts=4 sts=4 sw=4 si et