From d62ba74e92c673f170c444899e14cae4b065e79a Mon Sep 17 00:00:00 2001 From: Javier Sancho Date: Tue, 29 May 2018 13:03:09 +0200 Subject: [PATCH] Fix number of rows returned when limit is present or pagination is needed --- datasette_pytables/__init__.py | 22 ++++++++++++++++------ tests/test_api.py | 29 ++++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/datasette_pytables/__init__.py b/datasette_pytables/__init__.py index b3d5b9a..86f879c 100644 --- a/datasette_pytables/__init__.py +++ b/datasette_pytables/__init__.py @@ -145,18 +145,14 @@ class Connection: 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: @@ -170,7 +166,14 @@ class Connection: rows.append(Row({'count(*)': int(table.nrows)})) else: if type(table) is tables.table.Table: + 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'] @@ -190,7 +193,14 @@ class Connection: else: # Any kind of array rowid = start - 1 + 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() rowid += 1 for field in fields: diff --git a/tests/test_api.py b/tests/test_api.py index 39c4122..97e07dc 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -55,6 +55,30 @@ def test_database_page(app_client): }] == data['tables'] def test_custom_sql(app_client): + response = app_client.get( + '/test_tables.json?' + urlencode({ + 'sql': 'select identity from [/group1/table1]', + '_shape': 'objects' + }), + gather_request=False + ) + data = response.json + assert { + 'sql': 'select identity from [/group1/table1]', + 'params': {} + } == data['query'] + assert 1000 == len(data['rows']) + assert [ + {'identity': 'This is particle: 0'}, + {'identity': 'This is particle: 1'}, + {'identity': 'This is particle: 2'}, + {'identity': 'This is particle: 3'} + ] == data['rows'][:4] + assert ['identity'] == data['columns'] + assert 'test_tables' == data['database'] + assert data['truncated'] + +def test_custom_complex_sql(app_client): response = app_client.get( '/test_tables.json?' + urlencode({ 'sql': 'select identity from [/group1/table1] where speed > 100 and idnumber < 55', @@ -63,7 +87,6 @@ def test_custom_sql(app_client): gather_request=False ) data = response.json - print("*************************", data) assert { 'sql': 'select identity from [/group1/table1] where speed > 100 and idnumber < 55', 'params': {} @@ -77,7 +100,7 @@ def test_custom_sql(app_client): ] == data['rows'] assert ['identity'] == data['columns'] assert 'test_tables' == data['database'] - assert False == data['truncated'] + assert not data['truncated'] def test_custom_pytables_sql(app_client): response = app_client.get( @@ -100,7 +123,7 @@ def test_custom_pytables_sql(app_client): ] == data['rows'][:3] assert ['identity'] == data['columns'] assert 'test_tables' == data['database'] - assert data['truncated'] + assert not data['truncated'] def test_invalid_custom_sql(app_client): response = app_client.get( -- 2.39.2