|
@@ -0,0 +1,246 @@
|
|
|
+import re
|
|
|
+from gluon import DAL, Field
|
|
|
+from gluon.dal import Row, Rows
|
|
|
+
|
|
|
+dal_field_type = dict(
|
|
|
+ id='id',
|
|
|
+ bit='boolean',
|
|
|
+ tinyint='boolean',
|
|
|
+ int='integer',
|
|
|
+ bigint='bigint',
|
|
|
+ double='double',
|
|
|
+ float='double',
|
|
|
+ mediumblob='blob',
|
|
|
+ blob='blob',
|
|
|
+ varchar='string',
|
|
|
+ text='text'
|
|
|
+)
|
|
|
+
|
|
|
+def search_objects(objs, **kargs):
|
|
|
+ ''' search list of objects, matching supplied fields'''
|
|
|
+ return filter(lambda s: all([ s[k] == v for k,v in kargs.iteritems() ]), objs)
|
|
|
+def search_objects2(axes, sensor_name, module_mark):
|
|
|
+ for ax in axes:
|
|
|
+ if (ax['sensor_name'] == sensor_name) and (ax['module_mark'] == module_mark):
|
|
|
+ return ax['unit']
|
|
|
+ return None
|
|
|
+
|
|
|
+
|
|
|
+class DBConnector(object):
|
|
|
+ def __init__(self, name, host, database):
|
|
|
+ self.axis_list = 'Axislist'
|
|
|
+ self.sensor_list = 'Sensorlist'
|
|
|
+ self.name = name
|
|
|
+ self.host = host
|
|
|
+ self.database = database
|
|
|
+ self.uri = "%s/%s" % (self.host, self.database)
|
|
|
+ self.connector = DAL( self.uri, migrate=False, pool_size=1, lazy_tables=True)
|
|
|
+ def extract(self):
|
|
|
+ modules = self.extract_modules()
|
|
|
+ sensors = self.extract_sensors(modules)
|
|
|
+ return modules, sensors
|
|
|
+ def connect(self, modules=None, sensors=None):
|
|
|
+ if modules is None or sensors is None:
|
|
|
+ modules, sensors = extract()
|
|
|
+ for mod in modules:
|
|
|
+ s = search_objects(sensors, module_mark=mod['mark'])
|
|
|
+ f = [ Field(k['name'], type=k['type'], length=k['length'], rname=k['rname']) for k in s ]
|
|
|
+ self.connector.define_table(mod['name'], *f)
|
|
|
+ def reconnect(self):
|
|
|
+ self.connector.reconnect()
|
|
|
+
|
|
|
+class KITCube(DBConnector):
|
|
|
+ def __init__(self, name, host, database, modules, ignore_fields=[], field_type_fix={}):
|
|
|
+ self.ignore_fields = ignore_fields
|
|
|
+ self.field_type_fix = field_type_fix
|
|
|
+ super(KITCube, self).__init__(name, host, database)
|
|
|
+
|
|
|
+ if isinstance(modules, basestring):
|
|
|
+ self.module_pattern = re.compile(modules)
|
|
|
+ else:
|
|
|
+ self.module_pattern = None
|
|
|
+
|
|
|
+ def extract_modules(self):
|
|
|
+ tables = self.connector.executesql('show tables')
|
|
|
+ if self.module_pattern is not None:
|
|
|
+ matches = [ (tname, self.module_pattern.match(tname)) for tname, in tables ]
|
|
|
+ modules = [ dict(name=tname, mark=int(m.group('mod_mark'))) for tname, m in matches if m ]
|
|
|
+ return modules
|
|
|
+
|
|
|
+ def extract_sensors(self, modules):
|
|
|
+ fld_type_pattern = re.compile('(?P<fld_type>\w+)\((?P<fld_length>\d*)\)')
|
|
|
+ sensor_units = self.extract_units()
|
|
|
+ sensors = []
|
|
|
+
|
|
|
+ for mod in modules:
|
|
|
+ cols = self.connector.executesql('show columns from ' + mod['name'])
|
|
|
+ for fld_name, fld_type, _, fld_key, _, _ in cols:
|
|
|
+ if '.' in fld_name:
|
|
|
+ rname = fld_name
|
|
|
+ fld_name = fld_name.replace('.', '_')
|
|
|
+ else:
|
|
|
+ rname = None
|
|
|
+ fld_name_long = mod['name'] + '.' + fld_name
|
|
|
+
|
|
|
+ if fld_key == 'PRI':
|
|
|
+ fld_type = 'id'
|
|
|
+ if fld_name_long in self.field_type_fix.keys():
|
|
|
+ fld_type = self.field_type_fix[fld_name_long]
|
|
|
+
|
|
|
+ m = fld_type_pattern.match(fld_type)
|
|
|
+ if m:
|
|
|
+ fld_type = m.group('fld_type')
|
|
|
+ fld_length = m.group('fld_length')
|
|
|
+ else:
|
|
|
+ fld_length = None
|
|
|
+
|
|
|
+ if fld_name_long in self.ignore_fields:
|
|
|
+ continue
|
|
|
+ if fld_type in ['mediumblob', 'blob']:
|
|
|
+ continue
|
|
|
+
|
|
|
+ s = search_objects(sensor_units, module=mod['mark'], name=rname)
|
|
|
+ try:
|
|
|
+ unit = s[0]['unit']
|
|
|
+ except:
|
|
|
+ unit = None
|
|
|
+
|
|
|
+ sensors.append(dict(module_mark=mod['mark'],
|
|
|
+ name=fld_name, type=fld_type,
|
|
|
+ length=fld_length, rname=rname,
|
|
|
+ unit=unit))
|
|
|
+ return sensors
|
|
|
+
|
|
|
+ def extract_units(self):
|
|
|
+ self.connector.define_table(self.axis_list,
|
|
|
+ Field('id'), Field('unit', 'string'))
|
|
|
+ self.connector.define_table(self.sensor_list,
|
|
|
+ Field('id'), Field('name', 'string'),
|
|
|
+ Field('module', 'integer'),
|
|
|
+ Field('axis', 'reference %s' % self.axis_list))
|
|
|
+
|
|
|
+ sensortable = self.connector[self.sensor_list]
|
|
|
+ axistable = self.connector[self.axis_list]
|
|
|
+
|
|
|
+ records = self.connector(sensortable.axis==axistable.id).select()
|
|
|
+ sensor_units = [ dict(name=r[self.sensor_list].name,
|
|
|
+ module=r[self.sensor_list].module,
|
|
|
+ unit=r[self.axis_list].unit) for r in records ]
|
|
|
+ return sensor_units
|
|
|
+
|
|
|
+ # def set_tables(self):
|
|
|
+ # for mod in self.modules:
|
|
|
+ # mark = mod['mark']
|
|
|
+ # fields = []
|
|
|
+ # for sns in self.sensors:
|
|
|
+ # if sns['module_mark'] == mark:
|
|
|
+ # fields.append(
|
|
|
+ # Field(sns['name'], sns['type'], length=sns['length'], rname=sns['rname']))
|
|
|
+ # self.connector.define_table(mod['name'], *fields)
|
|
|
+
|
|
|
+
|
|
|
+ # def extract_sensors(self, modules):
|
|
|
+ # sensors = []
|
|
|
+ # fld_type_pattern = re.compile('(?P<fld_type>\w+)\((?P<fld_length>\d*)\)')
|
|
|
+ # sensors.append(dict(module_mark=mod['mark'], name=fld_name, type=fld_type, length=fld_length, rname=rname))
|
|
|
+ # return sensors
|
|
|
+ # def extract_sensoraxis(self):
|
|
|
+ # axes = self.extract_axes()
|
|
|
+ # for mod in self.modules:
|
|
|
+ # for sns in mod['sensors']:
|
|
|
+ # unit = search_dicts(axes, sensor_name=(sns['rname'] or sns['name']), module_mark=mod['mark'])
|
|
|
+ # sns.update({'unit': unit})
|
|
|
+ # def extract_axes(self):
|
|
|
+ # q = (self._sql[self.sensor_list].axis == self._sql[self.axis_list].id)
|
|
|
+ # res = self._sql(q).select(self._sql[self.sensor_list].name,
|
|
|
+ # self._sql[self.sensor_list].module,
|
|
|
+ # self._sql[self.axis_list].unit)
|
|
|
+ # axes = [{ 'sensor_name': r[self.sensor_list].name,
|
|
|
+ # 'module_mark': r[self.sensor_list].module,
|
|
|
+ # 'unit': r[self.axis_list].unit
|
|
|
+ # } for r in res]
|
|
|
+ # return axes
|
|
|
+ # def get(self):
|
|
|
+ # self.extract_modules()
|
|
|
+ # self.extract_sensors()
|
|
|
+ # self.extract_sensoraxis()
|
|
|
+ # return self.modules
|
|
|
+ # def tables(self, _info):
|
|
|
+ # pass
|
|
|
+
|
|
|
+def extract_db_info(config, _sql=None):
|
|
|
+ host = config['host']
|
|
|
+ server = config['server']
|
|
|
+ database = config['database']
|
|
|
+ sensor_groups = config['sensor_groups']
|
|
|
+ axis_list = config['axislist']
|
|
|
+ sensor_list = config['sensorlist']
|
|
|
+ ignore_fields = config['field_ignore']
|
|
|
+ field_type_fix = config['field_type_fix']
|
|
|
+
|
|
|
+ if not _sql:
|
|
|
+ _sql = DAL( "%s/%s" % (host, database), migrate=False, pool_size=1)
|
|
|
+
|
|
|
+ _sql.define_table(axis_list, Field('id'), Field('unit', 'string'))
|
|
|
+ _sql.define_table(sensor_list, Field('id'),
|
|
|
+ Field('name', 'string'),
|
|
|
+ Field('axis', 'reference %s' % axis_list),
|
|
|
+ Field('module', 'integer'))
|
|
|
+
|
|
|
+ q = _sql[sensor_list].axis == _sql[axis_list].id
|
|
|
+ r = _sql(q).select(_sql[sensor_list].name, _sql[sensor_list].module, _sql[axis_list].unit)
|
|
|
+ sensor_axis = r
|
|
|
+
|
|
|
+ tables_in_db = _sql.executesql('show tables')
|
|
|
+
|
|
|
+ if isinstance(sensor_groups, basestring):
|
|
|
+ pattern = re.compile(sensor_groups)
|
|
|
+ tables = [tab[0] for tab in tables_in_db if pattern.match(tab[0])]
|
|
|
+
|
|
|
+ fld_pattern = re.compile('(?P<fld_type>\w+)\((?P<fld_length>\d*)\)')
|
|
|
+ mod_pattern = re.compile('\w+_(?P<mod_number>\d{3})_\w+')
|
|
|
+
|
|
|
+ modules = { tab[0]:[ ] for tab in tables }
|
|
|
+ print tables, modules
|
|
|
+
|
|
|
+ for tab in tables:
|
|
|
+ m = mod_pattern.match(tab)
|
|
|
+ mod_number = int(m.group('mod_number'))
|
|
|
+
|
|
|
+ # columns from mysql table
|
|
|
+ cols =_sql.executesql('show columns from %s' % tab)
|
|
|
+
|
|
|
+ # extract fields from database and construct DAL fields
|
|
|
+ for fld_name, fld_type, _, fld_key, _, _ in cols:
|
|
|
+ if '.' in fld_name:
|
|
|
+ rname = '`' + fld_name + '`'
|
|
|
+ fld_name = fld_name.replace('.', '_')
|
|
|
+ else:
|
|
|
+ rname = None
|
|
|
+
|
|
|
+ field_long_name = '%s.%s' % (tab, fld_name)
|
|
|
+ if field_long_name in field_type_fix.keys():
|
|
|
+ fld_type = field_type_fix[field_long_name]
|
|
|
+
|
|
|
+ m = fld_pattern.match(fld_type)
|
|
|
+ if m:
|
|
|
+ fld_type = m.group('fld_type')
|
|
|
+ fld_length = m.group('fld_length')
|
|
|
+ else:
|
|
|
+ fld_length = None
|
|
|
+
|
|
|
+ if fld_key == 'PRI':
|
|
|
+ fld_type = 'id'
|
|
|
+
|
|
|
+ if fld_type in ['mediumblob', 'blob']:
|
|
|
+ continue
|
|
|
+ if field_long_name in ignore_fields:
|
|
|
+ continue
|
|
|
+
|
|
|
+ axis = sensor_axis.find(lambda r:
|
|
|
+ r[sensor_list].name == fld_name and r[sensor_list].module == mod_number).first()
|
|
|
+ if axis:
|
|
|
+ axis = axis[axis_list].unit
|
|
|
+
|
|
|
+ modules[tab].append(dict(name=fld_name, type=fld_type, axis=axis))
|
|
|
+ return modules
|