'binary_or': '|',
}
+ def _serialize_table_name(self, table_name):
+ return table_name.replace('/', '%')
+
+ def _deserialize_table_name(self, table_name):
+ return table_name.replace('%', '/')
+
def table_names(self):
return [
- node._v_pathname
+ self._serialize_table_name(node._v_pathname)
for node in self.conn.h5file
if not(isinstance(node, tables.group.Group))
]
def table_count(self, table_name):
- table = self.conn.h5file.get_node(table_name)
+ table = self.conn.h5file.get_node(self._deserialize_table_name(table_name))
return int(table.nrows)
def table_info(self, table_name):
- table = self.conn.h5file.get_node(table_name)
- colnames = ['value']
+ table = self.conn.h5file.get_node(self._deserialize_table_name(table_name))
+ columns = [
+ {
+ 'name': 'value',
+ 'type': table.dtype.name,
+ }
+ ]
if isinstance(table, tables.table.Table):
- colnames = table.colnames
+ columns = [
+ {
+ 'name': colname,
+ 'type': table.coltypes[colname],
+ }
+ for colname in table.colnames
+ ]
return [
{
- 'idx': idx,
- 'name': colname,
- 'primary_key': False,
+ 'cid': cid,
+ 'name': column['name'],
+ 'type': column['type'],
+ 'notnull': True,
+ 'default_value': None,
+ 'is_pk': False,
}
- for idx, colname in enumerate(colnames)
+ for cid, column in enumerate(columns)
]
def hidden_table_names(self):
def table_exists(self, table_name):
try:
- self.conn.h5file.get_node(table_name)
+ self.conn.h5file.get_node(self._deserialize_table_name(table_name))
return True
except:
return False
def table_definition(self, table_type, table_name):
+ table_name = self._deserialize_table_name(table_name)
table = self.conn.h5file.get_node(table_name)
colnames = ['value']
if isinstance(table, tables.table.Table):
truncated = False
description = ()
+ # Some Datasette queries uses glob operand, not supported by Pytables
+ if ' glob ' in sql:
+ return results, truncated, description
+
parsed_sql = parse_sql(sql, params)
while isinstance(parsed_sql['from'], dict):
# Pytables does not support subqueries
parsed_sql['from'] = parsed_sql['from']['value']['from']
- table = self.conn.h5file.get_node(parsed_sql['from'])
+ table = self.conn.h5file.get_node(self._deserialize_table_name(parsed_sql['from']))
table_rows = []
fields = parsed_sql['select']
colnames = ['value']
start = 0
end = table.nrows
- # Use 'where' statement or get all the rows
- def _cast_param(field, pname):
- # Cast value to the column type
+ def _get_field_type(field):
coltype = table.dtype.name
if type(table) is tables.table.Table:
coltype = table.coltypes[field]
+ return coltype
+
+ # Use 'where' statement or get all the rows
+ def _cast_param(field, pname):
+ # Cast value to the column type
+ coltype = _get_field_type(field)
fcast = None
if coltype == 'string':
fcast = str
if 'limit' in parsed_sql:
limit = int(parsed_sql['limit'])
+ # Offset
+ offset = None
+ if 'offset' in parsed_sql:
+ offset = int(parsed_sql['offset'])
+
# Truncate if needed
if page_size and max_returned_rows and truncate:
if max_returned_rows == page_size:
# Execute query
if query:
- if not ' glob ' in query:
- table_rows = table.where(query, params, start, end)
+ table_rows = table.where(query, params, start, end)
elif orderby:
table_rows = table.itersorted(orderby, start=start, stop=end)
else:
# Get results
get_rowid = make_get_rowid()
get_row_value = make_get_row_value()
+ if offset:
+ table_rows = table_rows[offset:]
count = 0
for table_row in table_rows:
count += 1
row['count(*)'] = int(table.nrows)
elif field_name.get('json_type'):
field_name = field_name.get('json_type')
- row['json_type(' + field_name + ')'] = table.coltypes[field_name]
+ row['json_type(' + field_name + ')'] = _get_field_type(field_name)
else:
raise Exception("Function not recognized")
else: