mirror of
https://github.com/simonw/sqlite-utils.git
synced 2026-08-13 12:54:12 +02:00
154 lines
3.6 KiB
Python
154 lines
3.6 KiB
Python
import pytest
|
|
|
|
from sqlite_utils import Database
|
|
from sqlite_utils.utils import sqlite3
|
|
|
|
BASELINE_ROWS = [(1, "one"), (2, "two")]
|
|
|
|
|
|
def insert(table):
|
|
table.insert({"id": 3, "value": "three"}, pk="id")
|
|
|
|
|
|
def insert_all(table):
|
|
table.insert_all(
|
|
[
|
|
{"id": 3, "value": "three"},
|
|
{"id": 4, "value": "four"},
|
|
],
|
|
pk="id",
|
|
batch_size=1,
|
|
)
|
|
|
|
|
|
def upsert(table):
|
|
table.upsert({"id": 2, "value": "TWO"}, pk="id")
|
|
|
|
|
|
def upsert_all(table):
|
|
table.upsert_all(
|
|
[
|
|
{"id": 2, "value": "TWO"},
|
|
{"id": 3, "value": "three"},
|
|
],
|
|
pk="id",
|
|
batch_size=1,
|
|
)
|
|
|
|
|
|
def update(table):
|
|
table.update(2, {"value": "TWO"})
|
|
|
|
|
|
def delete(table):
|
|
table.delete(2)
|
|
|
|
|
|
def delete_where(table):
|
|
table.delete_where("id > ?", [1])
|
|
|
|
|
|
MUTATOR_CASES = (
|
|
pytest.param(
|
|
insert,
|
|
[(1, "one"), (2, "two"), (3, "three")],
|
|
id="insert",
|
|
),
|
|
pytest.param(
|
|
insert_all,
|
|
[(1, "one"), (2, "two"), (3, "three"), (4, "four")],
|
|
id="insert_all",
|
|
),
|
|
pytest.param(
|
|
upsert,
|
|
[(1, "one"), (2, "TWO")],
|
|
id="upsert",
|
|
),
|
|
pytest.param(
|
|
upsert_all,
|
|
[(1, "one"), (2, "TWO"), (3, "three")],
|
|
id="upsert_all",
|
|
),
|
|
pytest.param(
|
|
update,
|
|
[(1, "one"), (2, "TWO")],
|
|
id="update",
|
|
),
|
|
pytest.param(delete, [(1, "one")], id="delete"),
|
|
pytest.param(delete_where, [(1, "one")], id="delete_where"),
|
|
)
|
|
|
|
|
|
class RollbackTest(Exception):
|
|
pass
|
|
|
|
|
|
def seed_database(path):
|
|
conn = sqlite3.connect(str(path))
|
|
try:
|
|
conn.execute("create table items (id integer primary key, value text)")
|
|
conn.executemany("insert into items values (?, ?)", BASELINE_ROWS)
|
|
conn.commit()
|
|
finally:
|
|
conn.close()
|
|
return Database(path)
|
|
|
|
|
|
def current_rows(db):
|
|
return db.conn.execute("select id, value from items order by id").fetchall()
|
|
|
|
|
|
def persisted_rows(path):
|
|
conn = sqlite3.connect(str(path))
|
|
try:
|
|
return conn.execute("select id, value from items order by id").fetchall()
|
|
finally:
|
|
conn.close()
|
|
|
|
|
|
@pytest.mark.parametrize("mutate,expected_rows", MUTATOR_CASES)
|
|
def test_mutator_commits_by_default(tmp_path, mutate, expected_rows):
|
|
path = tmp_path / "default.db"
|
|
db = seed_database(path)
|
|
|
|
assert not db.conn.in_transaction
|
|
mutate(db["items"])
|
|
assert current_rows(db) == expected_rows
|
|
assert not db.conn.in_transaction
|
|
|
|
db.close()
|
|
assert persisted_rows(path) == expected_rows
|
|
|
|
|
|
@pytest.mark.parametrize("mutate,expected_rows", MUTATOR_CASES)
|
|
def test_mutator_commits_with_outer_atomic(tmp_path, mutate, expected_rows):
|
|
path = tmp_path / "atomic.db"
|
|
db = seed_database(path)
|
|
|
|
with db.atomic():
|
|
assert db.conn.in_transaction
|
|
mutate(db["items"])
|
|
assert current_rows(db) == expected_rows
|
|
assert db.conn.in_transaction
|
|
|
|
assert current_rows(db) == expected_rows
|
|
assert not db.conn.in_transaction
|
|
db.close()
|
|
assert persisted_rows(path) == expected_rows
|
|
|
|
|
|
@pytest.mark.parametrize("mutate,expected_rows", MUTATOR_CASES)
|
|
def test_mutator_rolls_back_outer_atomic(tmp_path, mutate, expected_rows):
|
|
path = tmp_path / "rollback.db"
|
|
db = seed_database(path)
|
|
|
|
with pytest.raises(RollbackTest), db.atomic():
|
|
mutate(db["items"])
|
|
assert current_rows(db) == expected_rows
|
|
assert db.conn.in_transaction
|
|
raise RollbackTest
|
|
|
|
assert current_rows(db) == BASELINE_ROWS
|
|
assert not db.conn.in_transaction
|
|
db.close()
|
|
assert persisted_rows(path) == BASELINE_ROWS
|