2017-12-15 12:04:17 +00:00
|
|
|
from datasette.app import Datasette
|
2018-03-30 05:10:09 +00:00
|
|
|
import itertools
|
2018-06-17 19:16:04 +00:00
|
|
|
import json
|
2017-12-15 12:04:17 +00:00
|
|
|
import os
|
2018-05-31 13:40:30 +00:00
|
|
|
import pytest
|
2018-04-09 00:06:10 +00:00
|
|
|
import random
|
2017-12-15 12:04:17 +00:00
|
|
|
import sqlite3
|
2018-04-03 13:46:11 +00:00
|
|
|
import sys
|
2018-03-30 05:10:09 +00:00
|
|
|
import string
|
2017-12-15 12:04:17 +00:00
|
|
|
import tempfile
|
|
|
|
import time
|
|
|
|
|
|
|
|
|
2018-06-05 03:53:12 +00:00
|
|
|
class TestClient:
|
|
|
|
def __init__(self, sanic_test_client):
|
|
|
|
self.sanic_test_client = sanic_test_client
|
|
|
|
|
|
|
|
def get(self, path, allow_redirects=True):
|
|
|
|
return self.sanic_test_client.get(
|
|
|
|
path,
|
|
|
|
allow_redirects=allow_redirects,
|
|
|
|
gather_request=False
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2018-06-24 00:59:37 +00:00
|
|
|
@pytest.fixture(scope="session")
|
|
|
|
def app_client(
|
|
|
|
sql_time_limit_ms=None,
|
|
|
|
max_returned_rows=None,
|
|
|
|
cors=False,
|
|
|
|
config=None,
|
|
|
|
filename="fixtures.db",
|
|
|
|
):
|
2017-12-15 12:04:17 +00:00
|
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
2018-06-21 15:21:09 +00:00
|
|
|
filepath = os.path.join(tmpdir, filename)
|
2017-12-15 12:04:17 +00:00
|
|
|
conn = sqlite3.connect(filepath)
|
|
|
|
conn.executescript(TABLES)
|
|
|
|
os.chdir(os.path.dirname(filepath))
|
2018-06-24 00:59:37 +00:00
|
|
|
plugins_dir = os.path.join(tmpdir, "plugins")
|
2018-04-16 05:22:01 +00:00
|
|
|
os.mkdir(plugins_dir)
|
2018-06-24 00:59:37 +00:00
|
|
|
open(os.path.join(plugins_dir, "my_plugin.py"), "w").write(PLUGIN1)
|
|
|
|
open(os.path.join(plugins_dir, "my_plugin_2.py"), "w").write(PLUGIN2)
|
2018-05-25 01:12:27 +00:00
|
|
|
config = config or {}
|
2018-06-24 00:59:37 +00:00
|
|
|
config.update(
|
|
|
|
{
|
|
|
|
"default_page_size": 50,
|
|
|
|
"max_returned_rows": max_returned_rows or 100,
|
|
|
|
"sql_time_limit_ms": sql_time_limit_ms or 200,
|
|
|
|
}
|
|
|
|
)
|
2017-12-15 12:04:17 +00:00
|
|
|
ds = Datasette(
|
|
|
|
[filepath],
|
2018-06-24 00:59:37 +00:00
|
|
|
cors=cors,
|
2018-03-27 16:18:32 +00:00
|
|
|
metadata=METADATA,
|
2018-04-16 05:22:01 +00:00
|
|
|
plugins_dir=plugins_dir,
|
2018-05-25 01:12:27 +00:00
|
|
|
config=config,
|
2017-12-15 12:04:17 +00:00
|
|
|
)
|
2018-06-24 00:59:37 +00:00
|
|
|
ds.sqlite_functions.append(("sleep", 1, lambda n: time.sleep(float(n))))
|
2018-06-05 03:53:12 +00:00
|
|
|
client = TestClient(ds.app().test_client)
|
2018-04-19 05:24:48 +00:00
|
|
|
client.ds = ds
|
|
|
|
yield client
|
2017-12-15 12:04:17 +00:00
|
|
|
|
|
|
|
|
2018-05-31 13:40:30 +00:00
|
|
|
@pytest.fixture(scope='session')
|
2018-05-05 22:41:37 +00:00
|
|
|
def app_client_shorter_time_limit():
|
|
|
|
yield from app_client(20)
|
2018-04-18 01:08:51 +00:00
|
|
|
|
|
|
|
|
2018-05-31 13:40:30 +00:00
|
|
|
@pytest.fixture(scope='session')
|
|
|
|
def app_client_returned_rows_matches_page_size():
|
2018-04-26 04:04:12 +00:00
|
|
|
yield from app_client(max_returned_rows=50)
|
|
|
|
|
|
|
|
|
2018-06-04 16:02:07 +00:00
|
|
|
@pytest.fixture(scope='session')
|
|
|
|
def app_client_larger_cache_size():
|
|
|
|
yield from app_client(config={
|
|
|
|
'cache_size_kb': 2500,
|
|
|
|
})
|
|
|
|
|
|
|
|
|
2018-06-18 03:21:02 +00:00
|
|
|
@pytest.fixture(scope='session')
|
|
|
|
def app_client_csv_max_mb_one():
|
|
|
|
yield from app_client(config={
|
|
|
|
'max_csv_mb': 1,
|
|
|
|
})
|
|
|
|
|
|
|
|
|
2018-06-21 15:21:09 +00:00
|
|
|
@pytest.fixture(scope="session")
|
|
|
|
def app_client_with_dot():
|
|
|
|
yield from app_client(filename="fixtures.dot.db")
|
|
|
|
|
|
|
|
|
2018-06-24 00:59:37 +00:00
|
|
|
@pytest.fixture(scope='session')
|
|
|
|
def app_client_with_cors():
|
|
|
|
yield from app_client(cors=True)
|
|
|
|
|
|
|
|
|
2018-03-30 06:26:22 +00:00
|
|
|
def generate_compound_rows(num):
|
|
|
|
for a, b, c in itertools.islice(
|
|
|
|
itertools.product(string.ascii_lowercase, repeat=3), num
|
|
|
|
):
|
|
|
|
yield a, b, c, '{}-{}-{}'.format(a, b, c)
|
|
|
|
|
|
|
|
|
2018-04-09 00:06:10 +00:00
|
|
|
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()
|
|
|
|
]),
|
2018-04-17 01:41:17 +00:00
|
|
|
'text': rand.choice(['$null', '$blah']),
|
2018-04-09 00:06:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-03-27 16:18:32 +00:00
|
|
|
METADATA = {
|
2018-06-17 19:16:04 +00:00
|
|
|
'title': 'Datasette Fixtures',
|
|
|
|
'description': 'An example SQLite database demonstrating Datasette',
|
|
|
|
'license': 'Apache License 2.0',
|
|
|
|
'license_url': 'https://github.com/simonw/datasette/blob/master/LICENSE',
|
|
|
|
'source': 'tests/fixtures.py',
|
|
|
|
'source_url': 'https://github.com/simonw/datasette/blob/master/tests/fixtures.py',
|
2018-03-27 16:18:32 +00:00
|
|
|
'databases': {
|
2018-06-17 18:34:16 +00:00
|
|
|
'fixtures': {
|
2018-03-27 16:18:32 +00:00
|
|
|
'description': 'Test tables description',
|
|
|
|
'tables': {
|
|
|
|
'simple_primary_key': {
|
|
|
|
'description_html': 'Simple <em>primary</em> key',
|
|
|
|
'title': 'This <em>HTML</em> is escaped',
|
2018-04-09 04:58:25 +00:00
|
|
|
},
|
|
|
|
'sortable': {
|
|
|
|
'sortable_columns': [
|
|
|
|
'sortable',
|
|
|
|
'sortable_with_nulls',
|
|
|
|
'sortable_with_nulls_2',
|
2018-04-17 01:41:17 +00:00
|
|
|
'text',
|
2018-04-09 04:58:25 +00:00
|
|
|
]
|
|
|
|
},
|
|
|
|
'no_primary_key': {
|
|
|
|
'sortable_columns': [],
|
2018-04-26 03:42:57 +00:00
|
|
|
'hidden': True,
|
2018-04-09 04:58:25 +00:00
|
|
|
},
|
2018-04-14 14:06:52 +00:00
|
|
|
'units': {
|
|
|
|
'units': {
|
|
|
|
'distance': 'm',
|
|
|
|
'frequency': 'Hz'
|
|
|
|
}
|
|
|
|
},
|
2018-04-22 20:46:18 +00:00
|
|
|
'primary_key_multiple_columns_explicit_label': {
|
2018-04-22 17:51:43 +00:00
|
|
|
'label_column': 'content2',
|
|
|
|
},
|
2018-06-04 16:02:07 +00:00
|
|
|
},
|
|
|
|
'queries': {
|
2018-06-21 04:54:36 +00:00
|
|
|
'pragma_cache_size': 'PRAGMA cache_size;',
|
2018-07-16 02:33:30 +00:00
|
|
|
'neighborhood_search': {
|
|
|
|
'sql': '''
|
|
|
|
select neighborhood, facet_cities.name, state
|
|
|
|
from facetable
|
|
|
|
join facet_cities
|
|
|
|
on facetable.city_id = facet_cities.id
|
|
|
|
where neighborhood like '%' || :text || '%'
|
|
|
|
order by neighborhood;
|
|
|
|
''',
|
|
|
|
'title': 'Search neighborhoods',
|
|
|
|
'description_html': '<b>Demonstrating</b> simple like search',
|
|
|
|
},
|
2018-03-27 16:18:32 +00:00
|
|
|
}
|
2018-04-09 04:58:25 +00:00
|
|
|
},
|
2018-03-27 16:18:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-28 20:42:48 +00:00
|
|
|
PLUGIN1 = '''
|
2018-04-16 05:22:01 +00:00
|
|
|
from datasette import hookimpl
|
|
|
|
import pint
|
|
|
|
|
|
|
|
ureg = pint.UnitRegistry()
|
|
|
|
|
|
|
|
|
|
|
|
@hookimpl
|
|
|
|
def prepare_connection(conn):
|
|
|
|
def convert_units(amount, from_, to_):
|
|
|
|
"select convert_units(100, 'm', 'ft');"
|
|
|
|
return (amount * ureg(from_)).to(to_).to_tuple()[0]
|
|
|
|
conn.create_function('convert_units', 3, convert_units)
|
2018-04-18 03:12:21 +00:00
|
|
|
|
|
|
|
|
|
|
|
@hookimpl
|
|
|
|
def extra_css_urls():
|
|
|
|
return ['https://example.com/app.css']
|
|
|
|
|
|
|
|
|
|
|
|
@hookimpl
|
|
|
|
def extra_js_urls():
|
|
|
|
return [{
|
2018-05-28 20:42:48 +00:00
|
|
|
'url': 'https://example.com/jquery.js',
|
2018-04-18 03:12:21 +00:00
|
|
|
'sri': 'SRIHASH',
|
2018-05-28 20:42:48 +00:00
|
|
|
}, 'https://example.com/plugin1.js']
|
|
|
|
'''
|
|
|
|
|
|
|
|
PLUGIN2 = '''
|
|
|
|
from datasette import hookimpl
|
|
|
|
|
|
|
|
|
|
|
|
@hookimpl
|
|
|
|
def extra_js_urls():
|
|
|
|
return [{
|
|
|
|
'url': 'https://example.com/jquery.js',
|
|
|
|
'sri': 'SRIHASH',
|
|
|
|
}, 'https://example.com/plugin2.js']
|
2018-04-16 05:22:01 +00:00
|
|
|
'''
|
2018-03-27 16:18:32 +00:00
|
|
|
|
2017-12-15 12:04:17 +00:00
|
|
|
TABLES = '''
|
|
|
|
CREATE TABLE simple_primary_key (
|
2018-04-14 14:55:27 +00:00
|
|
|
id varchar(30) primary key,
|
2017-12-15 12:04:17 +00:00
|
|
|
content text
|
|
|
|
);
|
|
|
|
|
2018-04-14 14:55:27 +00:00
|
|
|
CREATE TABLE primary_key_multiple_columns (
|
|
|
|
id varchar(30) primary key,
|
|
|
|
content text,
|
|
|
|
content2 text
|
|
|
|
);
|
|
|
|
|
2018-04-22 20:46:18 +00:00
|
|
|
CREATE TABLE primary_key_multiple_columns_explicit_label (
|
|
|
|
id varchar(30) primary key,
|
|
|
|
content text,
|
|
|
|
content2 text
|
|
|
|
);
|
|
|
|
|
2017-12-15 12:04:17 +00:00
|
|
|
CREATE TABLE compound_primary_key (
|
|
|
|
pk1 varchar(30),
|
|
|
|
pk2 varchar(30),
|
|
|
|
content text,
|
|
|
|
PRIMARY KEY (pk1, pk2)
|
|
|
|
);
|
|
|
|
|
|
|
|
INSERT INTO compound_primary_key VALUES ('a', 'b', 'c');
|
|
|
|
|
2018-03-30 05:10:09 +00:00
|
|
|
CREATE TABLE compound_three_primary_keys (
|
|
|
|
pk1 varchar(30),
|
|
|
|
pk2 varchar(30),
|
|
|
|
pk3 varchar(30),
|
|
|
|
content text,
|
|
|
|
PRIMARY KEY (pk1, pk2, pk3)
|
|
|
|
);
|
|
|
|
|
2018-04-14 14:55:27 +00:00
|
|
|
CREATE TABLE foreign_key_references (
|
|
|
|
pk varchar(30) primary key,
|
|
|
|
foreign_key_with_label varchar(30),
|
|
|
|
foreign_key_with_no_label varchar(30),
|
|
|
|
FOREIGN KEY (foreign_key_with_label) REFERENCES simple_primary_key(id),
|
|
|
|
FOREIGN KEY (foreign_key_with_no_label) REFERENCES primary_key_multiple_columns(id)
|
|
|
|
);
|
|
|
|
|
2018-04-09 00:06:10 +00:00
|
|
|
CREATE TABLE sortable (
|
|
|
|
pk1 varchar(30),
|
|
|
|
pk2 varchar(30),
|
|
|
|
content text,
|
|
|
|
sortable integer,
|
|
|
|
sortable_with_nulls real,
|
|
|
|
sortable_with_nulls_2 real,
|
2018-04-17 01:41:17 +00:00
|
|
|
text text,
|
2018-04-09 00:06:10 +00:00
|
|
|
PRIMARY KEY (pk1, pk2)
|
|
|
|
);
|
2018-03-30 05:10:09 +00:00
|
|
|
|
2017-12-15 12:04:17 +00:00
|
|
|
CREATE TABLE no_primary_key (
|
|
|
|
content text,
|
|
|
|
a text,
|
|
|
|
b text,
|
|
|
|
c text
|
|
|
|
);
|
|
|
|
|
|
|
|
CREATE TABLE [123_starts_with_digits] (
|
|
|
|
content text
|
|
|
|
);
|
|
|
|
|
|
|
|
CREATE VIEW paginated_view AS
|
|
|
|
SELECT
|
|
|
|
content,
|
|
|
|
'- ' || content || ' -' AS content_extra
|
|
|
|
FROM no_primary_key;
|
|
|
|
|
|
|
|
CREATE TABLE "Table With Space In Name" (
|
|
|
|
pk varchar(30) primary key,
|
|
|
|
content text
|
|
|
|
);
|
|
|
|
|
|
|
|
CREATE TABLE "table/with/slashes.csv" (
|
|
|
|
pk varchar(30) primary key,
|
|
|
|
content text
|
|
|
|
);
|
|
|
|
|
|
|
|
CREATE TABLE "complex_foreign_keys" (
|
|
|
|
pk varchar(30) primary key,
|
|
|
|
f1 text,
|
|
|
|
f2 text,
|
|
|
|
f3 text,
|
|
|
|
FOREIGN KEY ("f1") REFERENCES [simple_primary_key](id),
|
|
|
|
FOREIGN KEY ("f2") REFERENCES [simple_primary_key](id),
|
|
|
|
FOREIGN KEY ("f3") REFERENCES [simple_primary_key](id)
|
|
|
|
);
|
|
|
|
|
2018-04-22 17:51:43 +00:00
|
|
|
CREATE TABLE "custom_foreign_key_label" (
|
|
|
|
pk varchar(30) primary key,
|
|
|
|
foreign_key_with_custom_label text,
|
2018-04-22 20:46:18 +00:00
|
|
|
FOREIGN KEY ("foreign_key_with_custom_label") REFERENCES [primary_key_multiple_columns_explicit_label](id)
|
2018-04-22 17:51:43 +00:00
|
|
|
);
|
|
|
|
|
2018-04-14 14:06:52 +00:00
|
|
|
CREATE TABLE units (
|
|
|
|
pk integer primary key,
|
|
|
|
distance int,
|
|
|
|
frequency int
|
|
|
|
);
|
|
|
|
|
|
|
|
INSERT INTO units VALUES (1, 1, 100);
|
|
|
|
INSERT INTO units VALUES (2, 5000, 2500);
|
|
|
|
INSERT INTO units VALUES (3, 100000, 75000);
|
|
|
|
|
2018-06-21 14:56:28 +00:00
|
|
|
CREATE TABLE tags (
|
|
|
|
tag TEXT PRIMARY KEY
|
|
|
|
);
|
|
|
|
|
2018-05-05 22:01:14 +00:00
|
|
|
CREATE TABLE searchable (
|
|
|
|
pk integer primary key,
|
|
|
|
text1 text,
|
2018-05-05 22:33:08 +00:00
|
|
|
text2 text,
|
|
|
|
[name with . and spaces] text
|
2018-05-05 22:01:14 +00:00
|
|
|
);
|
|
|
|
|
2018-06-21 14:56:28 +00:00
|
|
|
CREATE TABLE searchable_tags (
|
|
|
|
searchable_id integer,
|
|
|
|
tag text,
|
|
|
|
PRIMARY KEY (searchable_id, tag),
|
|
|
|
FOREIGN KEY (searchable_id) REFERENCES searchable(pk),
|
|
|
|
FOREIGN KEY (tag) REFERENCES tags(tag)
|
|
|
|
);
|
|
|
|
|
2018-05-05 22:33:08 +00:00
|
|
|
INSERT INTO searchable VALUES (1, 'barry cat', 'terry dog', 'panther');
|
|
|
|
INSERT INTO searchable VALUES (2, 'terry dog', 'sara weasel', 'puma');
|
2018-05-05 22:01:14 +00:00
|
|
|
|
2018-06-21 14:56:28 +00:00
|
|
|
INSERT INTO tags VALUES ("canine");
|
|
|
|
INSERT INTO tags VALUES ("feline");
|
|
|
|
|
|
|
|
INSERT INTO searchable_tags (searchable_id, tag) VALUES
|
|
|
|
(1, "feline"),
|
|
|
|
(2, "canine")
|
|
|
|
;
|
|
|
|
|
2018-05-05 22:01:14 +00:00
|
|
|
CREATE VIRTUAL TABLE "searchable_fts"
|
2018-05-05 22:33:08 +00:00
|
|
|
USING FTS3 (text1, text2, [name with . and spaces], content="searchable");
|
|
|
|
INSERT INTO "searchable_fts" (rowid, text1, text2, [name with . and spaces])
|
|
|
|
SELECT rowid, text1, text2, [name with . and spaces] FROM searchable;
|
2018-05-05 22:01:14 +00:00
|
|
|
|
2018-04-03 13:39:50 +00:00
|
|
|
CREATE TABLE [select] (
|
|
|
|
[group] text,
|
|
|
|
[having] text,
|
|
|
|
[and] text
|
|
|
|
);
|
|
|
|
INSERT INTO [select] VALUES ('group', 'having', 'and');
|
|
|
|
|
2018-07-24 03:07:57 +00:00
|
|
|
CREATE TABLE infinity (
|
|
|
|
value REAL
|
|
|
|
);
|
|
|
|
INSERT INTO infinity VALUES
|
|
|
|
(1e999),
|
|
|
|
(-1e999),
|
|
|
|
(1.5)
|
|
|
|
;
|
|
|
|
|
2018-05-15 15:52:02 +00:00
|
|
|
CREATE TABLE facet_cities (
|
|
|
|
id integer primary key,
|
|
|
|
name text
|
|
|
|
);
|
|
|
|
INSERT INTO facet_cities (id, name) VALUES
|
|
|
|
(1, 'San Francisco'),
|
|
|
|
(2, 'Los Angeles'),
|
|
|
|
(3, 'Detroit'),
|
|
|
|
(4, 'Memnonia')
|
|
|
|
;
|
|
|
|
|
2018-05-12 22:29:06 +00:00
|
|
|
CREATE TABLE facetable (
|
|
|
|
pk integer primary key,
|
2018-05-15 15:52:02 +00:00
|
|
|
planet_int integer,
|
2018-06-21 04:30:13 +00:00
|
|
|
on_earth integer,
|
2018-05-12 22:29:06 +00:00
|
|
|
state text,
|
2018-05-15 15:52:02 +00:00
|
|
|
city_id integer,
|
|
|
|
neighborhood text,
|
|
|
|
FOREIGN KEY ("city_id") REFERENCES [facet_cities](id)
|
2018-05-12 22:29:06 +00:00
|
|
|
);
|
2018-06-21 04:30:13 +00:00
|
|
|
INSERT INTO facetable
|
|
|
|
(planet_int, on_earth, state, city_id, neighborhood)
|
|
|
|
VALUES
|
|
|
|
(1, 1, 'CA', 1, 'Mission'),
|
|
|
|
(1, 1, 'CA', 1, 'Dogpatch'),
|
|
|
|
(1, 1, 'CA', 1, 'SOMA'),
|
|
|
|
(1, 1, 'CA', 1, 'Tenderloin'),
|
|
|
|
(1, 1, 'CA', 1, 'Bernal Heights'),
|
|
|
|
(1, 1, 'CA', 1, 'Hayes Valley'),
|
|
|
|
(1, 1, 'CA', 2, 'Hollywood'),
|
|
|
|
(1, 1, 'CA', 2, 'Downtown'),
|
|
|
|
(1, 1, 'CA', 2, 'Los Feliz'),
|
|
|
|
(1, 1, 'CA', 2, 'Koreatown'),
|
|
|
|
(1, 1, 'MI', 3, 'Downtown'),
|
|
|
|
(1, 1, 'MI', 3, 'Greektown'),
|
|
|
|
(1, 1, 'MI', 3, 'Corktown'),
|
|
|
|
(1, 1, 'MI', 3, 'Mexicantown'),
|
|
|
|
(2, 0, 'MC', 4, 'Arcadia Planitia')
|
2018-05-12 22:29:06 +00:00
|
|
|
;
|
|
|
|
|
2017-12-15 12:04:17 +00:00
|
|
|
INSERT INTO simple_primary_key VALUES (1, 'hello');
|
|
|
|
INSERT INTO simple_primary_key VALUES (2, 'world');
|
|
|
|
INSERT INTO simple_primary_key VALUES (3, '');
|
|
|
|
|
2018-04-14 14:55:27 +00:00
|
|
|
INSERT INTO primary_key_multiple_columns VALUES (1, 'hey', 'world');
|
2018-04-22 20:46:18 +00:00
|
|
|
INSERT INTO primary_key_multiple_columns_explicit_label VALUES (1, 'hey', 'world2');
|
2018-04-14 14:55:27 +00:00
|
|
|
|
|
|
|
INSERT INTO foreign_key_references VALUES (1, 1, 1);
|
|
|
|
|
2017-12-15 12:04:17 +00:00
|
|
|
INSERT INTO complex_foreign_keys VALUES (1, 1, 2, 1);
|
2018-04-22 17:51:43 +00:00
|
|
|
INSERT INTO custom_foreign_key_label VALUES (1, 1);
|
2017-12-15 12:04:17 +00:00
|
|
|
|
|
|
|
INSERT INTO [table/with/slashes.csv] VALUES (3, 'hey');
|
|
|
|
|
|
|
|
CREATE VIEW simple_view AS
|
|
|
|
SELECT content, upper(content) AS upper_content FROM simple_primary_key;
|
|
|
|
|
|
|
|
''' + '\n'.join([
|
|
|
|
'INSERT INTO no_primary_key VALUES ({i}, "a{i}", "b{i}", "c{i}");'.format(i=i + 1)
|
|
|
|
for i in range(201)
|
2018-03-30 05:10:09 +00:00
|
|
|
]) + '\n'.join([
|
2018-03-30 06:26:22 +00:00
|
|
|
'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)
|
2018-04-09 00:06:10 +00:00
|
|
|
]) + '\n'.join([
|
|
|
|
'''INSERT INTO sortable VALUES (
|
|
|
|
"{pk1}", "{pk2}", "{content}", {sortable},
|
2018-04-17 01:41:17 +00:00
|
|
|
{sortable_with_nulls}, {sortable_with_nulls_2}, "{text}");
|
2018-04-09 00:06:10 +00:00
|
|
|
'''.format(
|
|
|
|
**row
|
|
|
|
).replace('None', 'null') for row in generate_sortable_rows(201)
|
2017-12-15 12:04:17 +00:00
|
|
|
])
|
2018-04-03 13:46:11 +00:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
2018-06-17 19:16:04 +00:00
|
|
|
# Can be called with data.db OR data.db metadata.json
|
|
|
|
db_filename = sys.argv[-1]
|
|
|
|
metadata_filename = None
|
|
|
|
if db_filename.endswith(".json"):
|
|
|
|
metadata_filename = db_filename
|
|
|
|
db_filename = sys.argv[-2]
|
|
|
|
if db_filename.endswith(".db"):
|
|
|
|
conn = sqlite3.connect(db_filename)
|
2018-04-03 13:46:11 +00:00
|
|
|
conn.executescript(TABLES)
|
2018-06-17 19:16:04 +00:00
|
|
|
print("Test tables written to {}".format(db_filename))
|
|
|
|
if metadata_filename:
|
|
|
|
open(metadata_filename, 'w').write(json.dumps(METADATA))
|
|
|
|
print("- metadata written to {}".format(metadata_filename))
|
2018-04-03 13:46:11 +00:00
|
|
|
else:
|
2018-06-17 19:16:04 +00:00
|
|
|
print("Usage: {} db_to_write.db [metadata_to_write.json]".format(
|
|
|
|
sys.argv[0]
|
|
|
|
))
|