h5file = tables.open_file(path)
for table in filter(lambda node: not(isinstance(node, tables.group.Group)), h5file):
- colnames = []
+ colnames = ['value']
if isinstance(table, tables.table.Table):
colnames = table.colnames
table = self.h5file.get_node(parsed_sql['from'])
table_rows = []
fields = parsed_sql['select']
+ colnames = ['value']
+ if type(table) is tables.table.Table:
+ colnames = table.colnames
query = ''
start = 0
# Use 'where' statement or get all the rows
def _cast_param(field, pname):
# Cast value to the column type
+ coltype = table.dtype.name
if type(table) is tables.table.Table:
coltype = table.coltypes[field]
- else:
- coltype = table.dtype.name
fcast = None
if coltype == 'string':
fcast = str
query = parsed_sql['where']
# Limit number of rows
+ limit = None
if 'limit' in parsed_sql:
- max_rows = int(parsed_sql['limit'])
- if end - start > max_rows:
- end = start + max_rows
+ limit = int(parsed_sql['limit'])
# Truncate if needed
if page_size and max_returned_rows and truncate:
if max_returned_rows == page_size:
max_returned_rows += 1
- if end - start > max_returned_rows:
- end = start + max_returned_rows
- truncated = True
# Execute query
if query:
table_rows = table.iterrows(start, end)
# Prepare rows
- if len(fields) == 1 and type(fields[0]['value']) is dict and \
- fields[0]['value'].get('count') == '*':
- rows.append(Row({'count(*)': int(table.nrows)}))
- else:
+ def normalize_field_value(value):
+ if type(value) is bytes:
+ return value.decode('utf-8')
+ elif not type(value) in (int, float, complex):
+ return str(value)
+ else:
+ return value
+
+ def make_get_rowid():
if type(table) is tables.table.Table:
- for table_row in table_rows:
- row = Row()
- for field in fields:
- field_name = field['value']
- if type(field_name) is dict and 'distinct' in field_name:
- field_name = field_name['distinct']
- if field_name == 'rowid':
- row['rowid'] = int(table_row.nrow)
- elif field_name == '*':
- for col in table.colnames:
- value = table_row[col]
- if type(value) is bytes:
- value = value.decode('utf-8')
- row[col] = value
- else:
- row[field_name] = table_row[field_name]
- rows.append(row)
+ def get_rowid(row):
+ return int(row.nrow)
else:
- # Any kind of array
rowid = start - 1
- for table_row in table_rows:
- row = Row()
+ def get_rowid(row):
+ nonlocal rowid
rowid += 1
- for field in fields:
- field_name = field['value']
- if type(field_name) is dict and 'distinct' in field_name:
- field_name = field_name['distinct']
- if field_name == 'rowid':
- row['rowid'] = rowid
- else:
- value = table_row
- if type(value) is bytes:
- value = value.decode('utf-8')
- row['value'] = value
- rows.append(row)
+ return rowid
+ return get_rowid
+
+ def make_get_row_value():
+ if type(table) is tables.table.Table:
+ def get_row_value(row, field):
+ return row[field]
+ else:
+ def get_row_value(row, field):
+ return row
+ return get_row_value
+
+ if len(fields) == 1 and type(fields[0]['value']) is dict and \
+ fields[0]['value'].get('count') == '*':
+ rows.append(Row({'count(*)': int(table.nrows)}))
+ else:
+ get_rowid = make_get_rowid()
+ get_row_value = make_get_row_value()
+ count = 0
+ for table_row in table_rows:
+ count += 1
+ if limit and count > limit:
+ break
+ if truncate and max_returned_rows and count > max_returned_rows:
+ truncated = True
+ break
+ row = Row()
+ for field in fields:
+ field_name = field['value']
+ if type(field_name) is dict and 'distinct' in field_name:
+ field_name = field_name['distinct']
+ if field_name == 'rowid':
+ row['rowid'] = get_rowid(table_row)
+ elif field_name == '*':
+ for col in colnames:
+ row[col] = normalize_field_value(get_row_value(table_row, col))
+ else:
+ row[field_name] = normalize_field_value(get_row_value(table_row, field_name))
+ rows.append(row)
# Prepare query description
for field in [f['value'] for f in fields]:
if field == '*':
- if type(table) is tables.table.Table:
- for col in table.colnames:
- description.append((col,))
- else:
- description.append(('value',))
+ for col in colnames:
+ description.append((col,))
else:
description.append((field,))
elif sql == 'select sql from sqlite_master where name = :n and type="table"':
try:
table = self.h5file.get_node(params['n'])
+ colnames = ['value']
+ if type(table) is tables.table.Table:
+ colnames = table.colnames
row = Row()
- row['sql'] = 'CREATE TABLE {} ()'.format(params['n'])
+ row['sql'] = 'CREATE TABLE {} ({})'.format(params['n'], ", ".join(colnames))
return [row]
except:
return []
else:
raise Exception("SQLite queries cannot be executed with this connector")
+
class Row(list):
def __init__(self, values=None):
self.labels = []