kopia lustrzana https://github.com/simonw/datasette
Work in progress with failing tests
rodzic
7365c3f51c
commit
2f8359c6f2
|
@ -602,6 +602,11 @@ class TableView(RowTableShared):
|
|||
if where_clauses:
|
||||
where_clause = 'where {} '.format(' and '.join(where_clauses))
|
||||
|
||||
# Allow for custom sort order
|
||||
sort = special_args.get('_sort')
|
||||
if sort:
|
||||
order_by = sort
|
||||
|
||||
if order_by:
|
||||
order_by = 'order by {} '.format(order_by)
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from contextlib import contextmanager
|
||||
from collections import namedtuple
|
||||
import base64
|
||||
import hashlib
|
||||
import json
|
||||
|
@ -12,6 +13,17 @@ import shutil
|
|||
import urllib
|
||||
|
||||
|
||||
Sort = namedtuple('Sort', ['column', 'desc', 'nulls_last'])
|
||||
sort_mapping = {
|
||||
'_sort': Sort('_sort', False, False),
|
||||
'_sort_asc': Sort('_sort', False, False),
|
||||
'_sort_desc': Sort('_sort_desc', True, False),
|
||||
'_sort_nulls_last': Sort('_sort_nulls_last', False, True),
|
||||
'_sort_asc_nulls_last': Sort('_sort_nulls_last', False, True),
|
||||
'_sort_desc_nulls_last': Sort('_sort_desc_nulls_last', True, True),
|
||||
}
|
||||
|
||||
|
||||
def compound_pks_from_path(path):
|
||||
return [
|
||||
urllib.parse.unquote_plus(b) for b in path.split(',')
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from datasette.app import Datasette
|
||||
import itertools
|
||||
import os
|
||||
import random
|
||||
import sqlite3
|
||||
import string
|
||||
import tempfile
|
||||
|
@ -33,6 +34,25 @@ def generate_compound_rows(num):
|
|||
yield a, b, c, '{}-{}-{}'.format(a, b, c)
|
||||
|
||||
|
||||
def generate_sortable_rows(num):
|
||||
rand = random.Random(42)
|
||||
for a, b in itertools.islice(
|
||||
itertools.product(string.ascii_lowercase, repeat=2), num
|
||||
):
|
||||
yield {
|
||||
'pk1': a,
|
||||
'pk2': b,
|
||||
'content': '{}-{}'.format(a, b),
|
||||
'sortable': rand.randint(-100, 100),
|
||||
'sortable_with_nulls': rand.choice([
|
||||
None, rand.random(), rand.random()
|
||||
]),
|
||||
'sortable_with_nulls_2': rand.choice([
|
||||
None, rand.random(), rand.random()
|
||||
]),
|
||||
}
|
||||
|
||||
|
||||
METADATA = {
|
||||
'title': 'Datasette Title',
|
||||
'description': 'Datasette Description',
|
||||
|
@ -69,7 +89,6 @@ CREATE TABLE compound_primary_key (
|
|||
|
||||
INSERT INTO compound_primary_key VALUES ('a', 'b', 'c');
|
||||
|
||||
|
||||
CREATE TABLE compound_three_primary_keys (
|
||||
pk1 varchar(30),
|
||||
pk2 varchar(30),
|
||||
|
@ -78,6 +97,15 @@ CREATE TABLE compound_three_primary_keys (
|
|||
PRIMARY KEY (pk1, pk2, pk3)
|
||||
);
|
||||
|
||||
CREATE TABLE sortable (
|
||||
pk1 varchar(30),
|
||||
pk2 varchar(30),
|
||||
content text,
|
||||
sortable integer,
|
||||
sortable_with_nulls real,
|
||||
sortable_with_nulls_2 real,
|
||||
PRIMARY KEY (pk1, pk2)
|
||||
);
|
||||
|
||||
CREATE TABLE no_primary_key (
|
||||
content text,
|
||||
|
@ -134,4 +162,11 @@ CREATE VIEW simple_view AS
|
|||
'INSERT INTO compound_three_primary_keys VALUES ("{a}", "{b}", "{c}", "{content}");'.format(
|
||||
a=a, b=b, c=c, content=content
|
||||
) for a, b, c, content in generate_compound_rows(1001)
|
||||
]) + '\n'.join([
|
||||
'''INSERT INTO sortable VALUES (
|
||||
"{pk1}", "{pk2}", "{content}", {sortable},
|
||||
{sortable_with_nulls}, {sortable_with_nulls_2});
|
||||
'''.format(
|
||||
**row
|
||||
).replace('None', 'null') for row in generate_sortable_rows(201)
|
||||
])
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from .fixtures import (
|
||||
app_client,
|
||||
generate_compound_rows,
|
||||
generate_sortable_rows,
|
||||
)
|
||||
import pytest
|
||||
|
||||
|
@ -13,7 +14,7 @@ def test_homepage(app_client):
|
|||
assert response.json.keys() == {'test_tables': 0}.keys()
|
||||
d = response.json['test_tables']
|
||||
assert d['name'] == 'test_tables'
|
||||
assert d['tables_count'] == 8
|
||||
assert d['tables_count'] == 9
|
||||
|
||||
|
||||
def test_database_page(app_client):
|
||||
|
@ -99,6 +100,16 @@ def test_database_page(app_client):
|
|||
'outgoing': [],
|
||||
},
|
||||
'label_column': None,
|
||||
}, {
|
||||
'columns': [
|
||||
'pk1', 'pk2', 'content', 'sortable', 'sortable_with_nulls',
|
||||
'sortable_with_nulls_2'
|
||||
],
|
||||
'name': 'sortable',
|
||||
'count': 201,
|
||||
'hidden': False,
|
||||
'foreign_keys': {'incoming': [], 'outgoing': []},
|
||||
'label_column': None,
|
||||
}, {
|
||||
'columns': ['pk', 'content'],
|
||||
'name': 'table/with/slashes.csv',
|
||||
|
@ -247,6 +258,30 @@ def test_paginate_compound_keys_with_extra_filters(app_client):
|
|||
assert expected == [f['content'] for f in fetched]
|
||||
|
||||
|
||||
@pytest.mark.parametrize('query_string,sort_key', [
|
||||
('_sort=sortable', lambda row: row['sortable']),
|
||||
('_sort_desc=sortable', lambda row: -row['sortable']),
|
||||
])
|
||||
def test_sortable(app_client, query_string, sort_key):
|
||||
path = '/test_tables/sortable.jsono?{}'.format(query_string)
|
||||
fetched = []
|
||||
page = 0
|
||||
while path:
|
||||
page += 1
|
||||
assert page < 100
|
||||
response = app_client.get(path, gather_request=False)
|
||||
fetched.extend(response.json['rows'])
|
||||
path = response.json['next_url']
|
||||
assert 5 == page
|
||||
expected = list(generate_sortable_rows(201))
|
||||
expected.sort(key=sort_key)
|
||||
assert [
|
||||
r['content'] for r in expected
|
||||
] == [
|
||||
r['content'] for r in fetched
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize('path,expected_rows', [
|
||||
('/test_tables/simple_primary_key.json?content=hello', [
|
||||
['1', 'hello'],
|
||||
|
|
Ładowanie…
Reference in New Issue