From 25d0571fb4a85291df0f7cea4f1424588a7961fc Mon Sep 17 00:00:00 2001 From: Javier Sancho Date: Fri, 11 May 2018 10:35:34 +0200 Subject: [PATCH 1/1] Basic execute method for queries --- datasette_pytables/__init__.py | 65 ++++++++++++++++++++++++++++++++-- setup.py | 2 +- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/datasette_pytables/__init__.py b/datasette_pytables/__init__.py index dc68234..93be0f9 100644 --- a/datasette_pytables/__init__.py +++ b/datasette_pytables/__init__.py @@ -1,4 +1,6 @@ import tables +import sqlparse +from collections import OrderedDict _connector_type = 'pytables' @@ -27,10 +29,69 @@ def inspect(path): h5file.close() return h5tables, views, _connector_type +def _parse_sql(sql): + parsed = sqlparse.parse(sql) + stmt = parsed[0] + parsed_sql = {} + current_keyword = "" + for token in stmt.tokens: + if token.is_keyword: + if current_keyword in parsed_sql and parsed_sql[current_keyword] == '': + # Check composed keywords like 'order by' + del parsed_sql[current_keyword] + current_keyword += " " + str(token) + else: + current_keyword = str(token) + parsed_sql[current_keyword] = "" + else: + if not token.is_whitespace: + parsed_sql[current_keyword] += str(token) + return parsed_sql + class Connection: def __init__(self, path): self.path = path self.h5file = tables.open_file(path) - def execute(self, sql, params): - return [], False, [] + def execute(self, sql, params=None, truncate=False): + rows = [] + truncated = False + description = [] + + parsed_sql = _parse_sql(sql) + table = self.h5file.get_node(parsed_sql['from'][1:-1]) + table_rows = [] + fields = parsed_sql['select'].split(',') + + # Use 'where' statement or get all the rows + if 'where' in parsed_sql: + pass + else: + table_rows = table.iterrows() + + if len(fields) == 1 and fields[0] == 'count(*)': + rows.append(Row({'count(*)': table.nrows})) + else: + for table_row in table_rows: + row = Row() + for field in fields: + if field == 'rowid': + row[field] = table_row.nrow + elif field == '*': + for col in table.colnames: + row[col] = table_row[col] + else: + row[field] = table_row[field] + rows.append(row) + + description = ((col,) for col in table.colnames) + + if truncate: + return rows, truncated, description + else: + return rows + +class Row(OrderedDict): + def __getitem__(self, label): + if type(label) is int: + return super(OrderedDict, self).__getitem__(list(self.keys())[label]) diff --git a/setup.py b/setup.py index 4840847..72d1685 100644 --- a/setup.py +++ b/setup.py @@ -26,6 +26,6 @@ setup( 'pytables = datasette_pytables' ], }, - install_requires=['datasette'] + install_requires=['datasette', 'tables', 'sqlparse'] ) -- 2.39.2