forked from s3lph/matemat
refactor(db): greatly simplify database migrations
This commit is contained in:
parent
1823759433
commit
ddf5ed01a2
5 changed files with 75 additions and 1004 deletions
|
@ -4,7 +4,44 @@ from typing import Dict
|
||||||
import sqlite3
|
import sqlite3
|
||||||
|
|
||||||
|
|
||||||
def migrate_schema_1_to_2(c: sqlite3.Cursor):
|
def migrate_schema_1(c: sqlite3.Cursor):
|
||||||
|
c.execute('''
|
||||||
|
CREATE TABLE users (
|
||||||
|
user_id INTEGER PRIMARY KEY,
|
||||||
|
username TEXT UNIQUE NOT NULL,
|
||||||
|
email TEXT DEFAULT NULL,
|
||||||
|
password TEXT NOT NULL,
|
||||||
|
touchkey TEXT DEFAULT NULL,
|
||||||
|
is_admin INTEGER(1) NOT NULL DEFAULT 0,
|
||||||
|
is_member INTEGER(1) NOT NULL DEFAULT 1,
|
||||||
|
balance INTEGER(8) NOT NULL DEFAULT 0,
|
||||||
|
lastchange INTEGER(8) NOT NULL DEFAULT 0
|
||||||
|
)
|
||||||
|
''')
|
||||||
|
c.execute('''
|
||||||
|
CREATE TABLE products (
|
||||||
|
product_id INTEGER PRIMARY KEY,
|
||||||
|
name TEXT UNIQUE NOT NULL,
|
||||||
|
stock INTEGER(8) NOT NULL DEFAULT 0,
|
||||||
|
price_member INTEGER(8) NOT NULL,
|
||||||
|
price_non_member INTEGER(8) NOT NULL
|
||||||
|
)
|
||||||
|
''')
|
||||||
|
c.execute('''
|
||||||
|
CREATE TABLE consumption (
|
||||||
|
user_id INTEGER NOT NULL,
|
||||||
|
product_id INTEGER NOT NULL,
|
||||||
|
count INTEGER(8) NOT NULL DEFAULT 0,
|
||||||
|
PRIMARY KEY (user_id, product_id),
|
||||||
|
FOREIGN KEY (user_id) REFERENCES users(user_id)
|
||||||
|
ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
|
FOREIGN KEY (product_id) REFERENCES products(product_id)
|
||||||
|
ON DELETE CASCADE ON UPDATE CASCADE
|
||||||
|
)
|
||||||
|
''')
|
||||||
|
|
||||||
|
|
||||||
|
def migrate_schema_2(c: sqlite3.Cursor):
|
||||||
# Create missing tables
|
# Create missing tables
|
||||||
c.execute('''
|
c.execute('''
|
||||||
CREATE TABLE transactions (
|
CREATE TABLE transactions (
|
||||||
|
@ -115,7 +152,7 @@ def migrate_schema_1_to_2(c: sqlite3.Cursor):
|
||||||
c.execute('DROP TABLE consumption')
|
c.execute('DROP TABLE consumption')
|
||||||
|
|
||||||
|
|
||||||
def migrate_schema_2_to_3(c: sqlite3.Cursor):
|
def migrate_schema_3(c: sqlite3.Cursor):
|
||||||
# Add missing columns to users table
|
# Add missing columns to users table
|
||||||
c.execute('ALTER TABLE users ADD COLUMN receipt_pref INTEGER(1) NOT NULL DEFAULT 0')
|
c.execute('ALTER TABLE users ADD COLUMN receipt_pref INTEGER(1) NOT NULL DEFAULT 0')
|
||||||
c.execute('''ALTER TABLE users ADD COLUMN created INTEGER(8) NOT NULL DEFAULT 0''')
|
c.execute('''ALTER TABLE users ADD COLUMN created INTEGER(8) NOT NULL DEFAULT 0''')
|
||||||
|
@ -203,7 +240,7 @@ def migrate_schema_2_to_3(c: sqlite3.Cursor):
|
||||||
''')
|
''')
|
||||||
|
|
||||||
|
|
||||||
def migrate_schema_3_to_4(c: sqlite3.Cursor):
|
def migrate_schema_4(c: sqlite3.Cursor):
|
||||||
# Change receipts schema to allow null for transaction IDs
|
# Change receipts schema to allow null for transaction IDs
|
||||||
c.execute('''
|
c.execute('''
|
||||||
CREATE TEMPORARY TABLE receipts_temp (
|
CREATE TEMPORARY TABLE receipts_temp (
|
||||||
|
@ -241,7 +278,7 @@ def migrate_schema_3_to_4(c: sqlite3.Cursor):
|
||||||
c.execute('DROP TABLE receipts_temp')
|
c.execute('DROP TABLE receipts_temp')
|
||||||
|
|
||||||
|
|
||||||
def migrate_schema_4_to_5(c: sqlite3.Cursor):
|
def migrate_schema_5(c: sqlite3.Cursor):
|
||||||
# Change products schema to allow null for stock and add stockable column
|
# Change products schema to allow null for stock and add stockable column
|
||||||
c.execute('''
|
c.execute('''
|
||||||
CREATE TEMPORARY TABLE products_temp (
|
CREATE TEMPORARY TABLE products_temp (
|
||||||
|
@ -270,7 +307,7 @@ def migrate_schema_4_to_5(c: sqlite3.Cursor):
|
||||||
c.execute('DROP TABLE products_temp')
|
c.execute('DROP TABLE products_temp')
|
||||||
|
|
||||||
|
|
||||||
def migrate_schema_5_to_6(c: sqlite3.Cursor):
|
def migrate_schema_6(c: sqlite3.Cursor):
|
||||||
# Add custom_price column
|
# Add custom_price column
|
||||||
c.execute('''
|
c.execute('''
|
||||||
ALTER TABLE products ADD COLUMN
|
ALTER TABLE products ADD COLUMN
|
||||||
|
@ -278,7 +315,7 @@ def migrate_schema_5_to_6(c: sqlite3.Cursor):
|
||||||
''')
|
''')
|
||||||
|
|
||||||
|
|
||||||
def migrate_schema_6_to_7(c: sqlite3.Cursor):
|
def migrate_schema_7(c: sqlite3.Cursor):
|
||||||
# Add custom_price column
|
# Add custom_price column
|
||||||
c.execute('''
|
c.execute('''
|
||||||
ALTER TABLE users ADD COLUMN
|
ALTER TABLE users ADD COLUMN
|
||||||
|
@ -286,7 +323,7 @@ def migrate_schema_6_to_7(c: sqlite3.Cursor):
|
||||||
''')
|
''')
|
||||||
|
|
||||||
|
|
||||||
def migrate_schema_7_to_8(c: sqlite3.Cursor):
|
def migrate_schema_8(c: sqlite3.Cursor):
|
||||||
# Add ean column
|
# Add ean column
|
||||||
c.execute('''
|
c.execute('''
|
||||||
ALTER TABLE products ADD COLUMN ean TEXT DEFAULT NULL
|
ALTER TABLE products ADD COLUMN ean TEXT DEFAULT NULL
|
||||||
|
@ -297,7 +334,7 @@ def migrate_schema_7_to_8(c: sqlite3.Cursor):
|
||||||
''')
|
''')
|
||||||
|
|
||||||
|
|
||||||
def migrate_schema_8_to_9(c: sqlite3.Cursor):
|
def migrate_schema_9(c: sqlite3.Cursor):
|
||||||
c.execute('''
|
c.execute('''
|
||||||
CREATE TABLE tokens (
|
CREATE TABLE tokens (
|
||||||
token_id INTEGER PRIMARY KEY,
|
token_id INTEGER PRIMARY KEY,
|
||||||
|
@ -311,7 +348,7 @@ def migrate_schema_8_to_9(c: sqlite3.Cursor):
|
||||||
''')
|
''')
|
||||||
|
|
||||||
|
|
||||||
def migrate_schema_9_to_10(c: sqlite3.Cursor):
|
def migrate_schema_10(c: sqlite3.Cursor):
|
||||||
c.execute('''
|
c.execute('''
|
||||||
ALTER TABLE users RENAME TO users_old
|
ALTER TABLE users RENAME TO users_old
|
||||||
''')
|
''')
|
||||||
|
|
|
@ -1,764 +0,0 @@
|
||||||
from typing import Dict, List
|
|
||||||
|
|
||||||
SCHEMAS: Dict[int, List[str]] = dict()
|
|
||||||
|
|
||||||
SCHEMAS[1] = [
|
|
||||||
'''
|
|
||||||
CREATE TABLE users (
|
|
||||||
user_id INTEGER PRIMARY KEY,
|
|
||||||
username TEXT UNIQUE NOT NULL,
|
|
||||||
email TEXT DEFAULT NULL,
|
|
||||||
password TEXT NOT NULL,
|
|
||||||
touchkey TEXT DEFAULT NULL,
|
|
||||||
is_admin INTEGER(1) NOT NULL DEFAULT 0,
|
|
||||||
is_member INTEGER(1) NOT NULL DEFAULT 1,
|
|
||||||
balance INTEGER(8) NOT NULL DEFAULT 0,
|
|
||||||
lastchange INTEGER(8) NOT NULL DEFAULT 0
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE products (
|
|
||||||
product_id INTEGER PRIMARY KEY,
|
|
||||||
name TEXT UNIQUE NOT NULL,
|
|
||||||
stock INTEGER(8) NOT NULL DEFAULT 0,
|
|
||||||
price_member INTEGER(8) NOT NULL,
|
|
||||||
price_non_member INTEGER(8) NOT NULL
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE consumption (
|
|
||||||
user_id INTEGER NOT NULL,
|
|
||||||
product_id INTEGER NOT NULL,
|
|
||||||
count INTEGER(8) NOT NULL DEFAULT 0,
|
|
||||||
PRIMARY KEY (user_id, product_id),
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(user_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE,
|
|
||||||
FOREIGN KEY (product_id) REFERENCES products(product_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''']
|
|
||||||
|
|
||||||
SCHEMAS[2] = [
|
|
||||||
'''
|
|
||||||
CREATE TABLE users (
|
|
||||||
user_id INTEGER PRIMARY KEY,
|
|
||||||
username TEXT UNIQUE NOT NULL,
|
|
||||||
email TEXT DEFAULT NULL,
|
|
||||||
password TEXT NOT NULL,
|
|
||||||
touchkey TEXT DEFAULT NULL,
|
|
||||||
is_admin INTEGER(1) NOT NULL DEFAULT 0,
|
|
||||||
is_member INTEGER(1) NOT NULL DEFAULT 1,
|
|
||||||
balance INTEGER(8) NOT NULL DEFAULT 0,
|
|
||||||
lastchange INTEGER(8) NOT NULL DEFAULT 0
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE products (
|
|
||||||
product_id INTEGER PRIMARY KEY,
|
|
||||||
name TEXT UNIQUE NOT NULL,
|
|
||||||
stock INTEGER(8) NOT NULL DEFAULT 0,
|
|
||||||
price_member INTEGER(8) NOT NULL,
|
|
||||||
price_non_member INTEGER(8) NOT NULL
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE transactions ( -- "superclass" of the following 3 tables
|
|
||||||
ta_id INTEGER PRIMARY KEY,
|
|
||||||
user_id INTEGER NOT NULL,
|
|
||||||
value INTEGER(8) NOT NULL,
|
|
||||||
old_balance INTEGER(8) NOT NULL,
|
|
||||||
date INTEGER(8) DEFAULT (STRFTIME('%s', 'now')),
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(user_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE consumptions ( -- transactions involving buying a product
|
|
||||||
ta_id INTEGER PRIMARY KEY,
|
|
||||||
product_id INTEGER DEFAULT NULL,
|
|
||||||
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE,
|
|
||||||
FOREIGN KEY (product_id) REFERENCES products(product_id)
|
|
||||||
ON DELETE SET NULL ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE deposits ( -- transactions involving depositing cash
|
|
||||||
ta_id INTEGER PRIMARY KEY,
|
|
||||||
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE modifications ( -- transactions involving balance modification by an admin
|
|
||||||
ta_id INTEGER NOT NULL,
|
|
||||||
agent_id INTEGER NOT NULL,
|
|
||||||
reason TEXT DEFAULT NULL,
|
|
||||||
PRIMARY KEY (ta_id),
|
|
||||||
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE,
|
|
||||||
FOREIGN KEY (agent_id) REFERENCES users(user_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''']
|
|
||||||
|
|
||||||
SCHEMAS[3] = [
|
|
||||||
'''
|
|
||||||
CREATE TABLE users (
|
|
||||||
user_id INTEGER PRIMARY KEY,
|
|
||||||
username TEXT UNIQUE NOT NULL,
|
|
||||||
email TEXT DEFAULT NULL,
|
|
||||||
password TEXT NOT NULL,
|
|
||||||
touchkey TEXT DEFAULT NULL,
|
|
||||||
is_admin INTEGER(1) NOT NULL DEFAULT 0,
|
|
||||||
is_member INTEGER(1) NOT NULL DEFAULT 1,
|
|
||||||
balance INTEGER(8) NOT NULL DEFAULT 0,
|
|
||||||
lastchange INTEGER(8) NOT NULL DEFAULT 0,
|
|
||||||
receipt_pref INTEGER(1) NOT NULL DEFAULT 0,
|
|
||||||
created INTEGER(8) NOT NULL DEFAULT 0
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE products (
|
|
||||||
product_id INTEGER PRIMARY KEY,
|
|
||||||
name TEXT UNIQUE NOT NULL,
|
|
||||||
stock INTEGER(8) NOT NULL DEFAULT 0,
|
|
||||||
price_member INTEGER(8) NOT NULL,
|
|
||||||
price_non_member INTEGER(8) NOT NULL
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE transactions ( -- "superclass" of the following 3 tables
|
|
||||||
ta_id INTEGER PRIMARY KEY,
|
|
||||||
user_id INTEGER DEFAULT NULL,
|
|
||||||
value INTEGER(8) NOT NULL,
|
|
||||||
old_balance INTEGER(8) NOT NULL,
|
|
||||||
date INTEGER(8) DEFAULT (STRFTIME('%s', 'now')),
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(user_id)
|
|
||||||
ON DELETE SET NULL ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE consumptions ( -- transactions involving buying a product
|
|
||||||
ta_id INTEGER PRIMARY KEY,
|
|
||||||
product TEXT NOT NULL,
|
|
||||||
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE deposits ( -- transactions involving depositing cash
|
|
||||||
ta_id INTEGER PRIMARY KEY,
|
|
||||||
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE modifications ( -- transactions involving balance modification by an admin
|
|
||||||
ta_id INTEGER NOT NULL,
|
|
||||||
agent TEXT NOT NULL,
|
|
||||||
reason TEXT DEFAULT NULL,
|
|
||||||
PRIMARY KEY (ta_id),
|
|
||||||
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE receipts ( -- receipts sent to the users
|
|
||||||
receipt_id INTEGER PRIMARY KEY,
|
|
||||||
user_id INTEGER NOT NULL,
|
|
||||||
first_ta_id INTEGER NOT NULL,
|
|
||||||
last_ta_id INTEGER NOT NULL,
|
|
||||||
date INTEGER(8) DEFAULT (STRFTIME('%s', 'now')),
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(user_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE,
|
|
||||||
FOREIGN KEY (first_ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE SET NULL ON UPDATE CASCADE,
|
|
||||||
FOREIGN KEY (last_ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE SET NULL ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''']
|
|
||||||
|
|
||||||
SCHEMAS[4] = [
|
|
||||||
'''
|
|
||||||
CREATE TABLE users (
|
|
||||||
user_id INTEGER PRIMARY KEY,
|
|
||||||
username TEXT UNIQUE NOT NULL,
|
|
||||||
email TEXT DEFAULT NULL,
|
|
||||||
password TEXT NOT NULL,
|
|
||||||
touchkey TEXT DEFAULT NULL,
|
|
||||||
is_admin INTEGER(1) NOT NULL DEFAULT 0,
|
|
||||||
is_member INTEGER(1) NOT NULL DEFAULT 1,
|
|
||||||
balance INTEGER(8) NOT NULL DEFAULT 0,
|
|
||||||
lastchange INTEGER(8) NOT NULL DEFAULT 0,
|
|
||||||
receipt_pref INTEGER(1) NOT NULL DEFAULT 0,
|
|
||||||
created INTEGER(8) NOT NULL DEFAULT 0
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE products (
|
|
||||||
product_id INTEGER PRIMARY KEY,
|
|
||||||
name TEXT UNIQUE NOT NULL,
|
|
||||||
stock INTEGER(8) NOT NULL DEFAULT 0,
|
|
||||||
price_member INTEGER(8) NOT NULL,
|
|
||||||
price_non_member INTEGER(8) NOT NULL
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE transactions ( -- "superclass" of the following 3 tables
|
|
||||||
ta_id INTEGER PRIMARY KEY,
|
|
||||||
user_id INTEGER DEFAULT NULL,
|
|
||||||
value INTEGER(8) NOT NULL,
|
|
||||||
old_balance INTEGER(8) NOT NULL,
|
|
||||||
date INTEGER(8) DEFAULT (STRFTIME('%s', 'now')),
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(user_id)
|
|
||||||
ON DELETE SET NULL ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE consumptions ( -- transactions involving buying a product
|
|
||||||
ta_id INTEGER PRIMARY KEY,
|
|
||||||
product TEXT NOT NULL,
|
|
||||||
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE deposits ( -- transactions involving depositing cash
|
|
||||||
ta_id INTEGER PRIMARY KEY,
|
|
||||||
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE modifications ( -- transactions involving balance modification by an admin
|
|
||||||
ta_id INTEGER NOT NULL,
|
|
||||||
agent TEXT NOT NULL,
|
|
||||||
reason TEXT DEFAULT NULL,
|
|
||||||
PRIMARY KEY (ta_id),
|
|
||||||
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE receipts ( -- receipts sent to the users
|
|
||||||
receipt_id INTEGER PRIMARY KEY,
|
|
||||||
user_id INTEGER NOT NULL,
|
|
||||||
first_ta_id INTEGER DEFAULT NULL,
|
|
||||||
last_ta_id INTEGER DEFAULT NULL,
|
|
||||||
date INTEGER(8) DEFAULT (STRFTIME('%s', 'now')),
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(user_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE,
|
|
||||||
FOREIGN KEY (first_ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE SET NULL ON UPDATE CASCADE,
|
|
||||||
FOREIGN KEY (last_ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE SET NULL ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''']
|
|
||||||
|
|
||||||
SCHEMAS[5] = [
|
|
||||||
'''
|
|
||||||
CREATE TABLE users (
|
|
||||||
user_id INTEGER PRIMARY KEY,
|
|
||||||
username TEXT UNIQUE NOT NULL,
|
|
||||||
email TEXT DEFAULT NULL,
|
|
||||||
password TEXT NOT NULL,
|
|
||||||
touchkey TEXT DEFAULT NULL,
|
|
||||||
is_admin INTEGER(1) NOT NULL DEFAULT 0,
|
|
||||||
is_member INTEGER(1) NOT NULL DEFAULT 1,
|
|
||||||
balance INTEGER(8) NOT NULL DEFAULT 0,
|
|
||||||
lastchange INTEGER(8) NOT NULL DEFAULT 0,
|
|
||||||
receipt_pref INTEGER(1) NOT NULL DEFAULT 0,
|
|
||||||
created INTEGER(8) NOT NULL DEFAULT 0
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE products (
|
|
||||||
product_id INTEGER PRIMARY KEY,
|
|
||||||
name TEXT UNIQUE NOT NULL,
|
|
||||||
stock INTEGER(8) DEFAULT 0,
|
|
||||||
stockable INTEGER(1) DEFAULT 1,
|
|
||||||
price_member INTEGER(8) NOT NULL,
|
|
||||||
price_non_member INTEGER(8) NOT NULL
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE transactions ( -- "superclass" of the following 3 tables
|
|
||||||
ta_id INTEGER PRIMARY KEY,
|
|
||||||
user_id INTEGER DEFAULT NULL,
|
|
||||||
value INTEGER(8) NOT NULL,
|
|
||||||
old_balance INTEGER(8) NOT NULL,
|
|
||||||
date INTEGER(8) DEFAULT (STRFTIME('%s', 'now')),
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(user_id)
|
|
||||||
ON DELETE SET NULL ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE consumptions ( -- transactions involving buying a product
|
|
||||||
ta_id INTEGER PRIMARY KEY,
|
|
||||||
product TEXT NOT NULL,
|
|
||||||
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE deposits ( -- transactions involving depositing cash
|
|
||||||
ta_id INTEGER PRIMARY KEY,
|
|
||||||
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE modifications ( -- transactions involving balance modification by an admin
|
|
||||||
ta_id INTEGER NOT NULL,
|
|
||||||
agent TEXT NOT NULL,
|
|
||||||
reason TEXT DEFAULT NULL,
|
|
||||||
PRIMARY KEY (ta_id),
|
|
||||||
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE receipts ( -- receipts sent to the users
|
|
||||||
receipt_id INTEGER PRIMARY KEY,
|
|
||||||
user_id INTEGER NOT NULL,
|
|
||||||
first_ta_id INTEGER DEFAULT NULL,
|
|
||||||
last_ta_id INTEGER DEFAULT NULL,
|
|
||||||
date INTEGER(8) DEFAULT (STRFTIME('%s', 'now')),
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(user_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE,
|
|
||||||
FOREIGN KEY (first_ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE SET NULL ON UPDATE CASCADE,
|
|
||||||
FOREIGN KEY (last_ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE SET NULL ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''']
|
|
||||||
|
|
||||||
|
|
||||||
SCHEMAS[6] = [
|
|
||||||
'''
|
|
||||||
CREATE TABLE users (
|
|
||||||
user_id INTEGER PRIMARY KEY,
|
|
||||||
username TEXT UNIQUE NOT NULL,
|
|
||||||
email TEXT DEFAULT NULL,
|
|
||||||
password TEXT NOT NULL,
|
|
||||||
touchkey TEXT DEFAULT NULL,
|
|
||||||
is_admin INTEGER(1) NOT NULL DEFAULT 0,
|
|
||||||
is_member INTEGER(1) NOT NULL DEFAULT 1,
|
|
||||||
balance INTEGER(8) NOT NULL DEFAULT 0,
|
|
||||||
lastchange INTEGER(8) NOT NULL DEFAULT 0,
|
|
||||||
receipt_pref INTEGER(1) NOT NULL DEFAULT 0,
|
|
||||||
created INTEGER(8) NOT NULL DEFAULT 0
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE products (
|
|
||||||
product_id INTEGER PRIMARY KEY,
|
|
||||||
name TEXT UNIQUE NOT NULL,
|
|
||||||
stock INTEGER(8) DEFAULT 0,
|
|
||||||
stockable INTEGER(1) DEFAULT 1,
|
|
||||||
price_member INTEGER(8) NOT NULL,
|
|
||||||
price_non_member INTEGER(8) NOT NULL,
|
|
||||||
custom_price INTEGER(1) DEFAULT 0
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE transactions ( -- "superclass" of the following 3 tables
|
|
||||||
ta_id INTEGER PRIMARY KEY,
|
|
||||||
user_id INTEGER DEFAULT NULL,
|
|
||||||
value INTEGER(8) NOT NULL,
|
|
||||||
old_balance INTEGER(8) NOT NULL,
|
|
||||||
date INTEGER(8) DEFAULT (STRFTIME('%s', 'now')),
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(user_id)
|
|
||||||
ON DELETE SET NULL ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE consumptions ( -- transactions involving buying a product
|
|
||||||
ta_id INTEGER PRIMARY KEY,
|
|
||||||
product TEXT NOT NULL,
|
|
||||||
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE deposits ( -- transactions involving depositing cash
|
|
||||||
ta_id INTEGER PRIMARY KEY,
|
|
||||||
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE modifications ( -- transactions involving balance modification by an admin
|
|
||||||
ta_id INTEGER NOT NULL,
|
|
||||||
agent TEXT NOT NULL,
|
|
||||||
reason TEXT DEFAULT NULL,
|
|
||||||
PRIMARY KEY (ta_id),
|
|
||||||
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE receipts ( -- receipts sent to the users
|
|
||||||
receipt_id INTEGER PRIMARY KEY,
|
|
||||||
user_id INTEGER NOT NULL,
|
|
||||||
first_ta_id INTEGER DEFAULT NULL,
|
|
||||||
last_ta_id INTEGER DEFAULT NULL,
|
|
||||||
date INTEGER(8) DEFAULT (STRFTIME('%s', 'now')),
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(user_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE,
|
|
||||||
FOREIGN KEY (first_ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE SET NULL ON UPDATE CASCADE,
|
|
||||||
FOREIGN KEY (last_ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE SET NULL ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''']
|
|
||||||
|
|
||||||
|
|
||||||
SCHEMAS[7] = [
|
|
||||||
'''
|
|
||||||
CREATE TABLE users (
|
|
||||||
user_id INTEGER PRIMARY KEY,
|
|
||||||
username TEXT UNIQUE NOT NULL,
|
|
||||||
email TEXT DEFAULT NULL,
|
|
||||||
password TEXT NOT NULL,
|
|
||||||
touchkey TEXT DEFAULT NULL,
|
|
||||||
is_admin INTEGER(1) NOT NULL DEFAULT 0,
|
|
||||||
is_member INTEGER(1) NOT NULL DEFAULT 1,
|
|
||||||
balance INTEGER(8) NOT NULL DEFAULT 0,
|
|
||||||
lastchange INTEGER(8) NOT NULL DEFAULT 0,
|
|
||||||
receipt_pref INTEGER(1) NOT NULL DEFAULT 0,
|
|
||||||
created INTEGER(8) NOT NULL DEFAULT 0,
|
|
||||||
logout_after_purchase INTEGER(1) DEFAULT 0
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE products (
|
|
||||||
product_id INTEGER PRIMARY KEY,
|
|
||||||
name TEXT UNIQUE NOT NULL,
|
|
||||||
stock INTEGER(8) DEFAULT 0,
|
|
||||||
stockable INTEGER(1) DEFAULT 1,
|
|
||||||
price_member INTEGER(8) NOT NULL,
|
|
||||||
price_non_member INTEGER(8) NOT NULL,
|
|
||||||
custom_price INTEGER(1) DEFAULT 0
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE transactions ( -- "superclass" of the following 3 tables
|
|
||||||
ta_id INTEGER PRIMARY KEY,
|
|
||||||
user_id INTEGER DEFAULT NULL,
|
|
||||||
value INTEGER(8) NOT NULL,
|
|
||||||
old_balance INTEGER(8) NOT NULL,
|
|
||||||
date INTEGER(8) DEFAULT (STRFTIME('%s', 'now')),
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(user_id)
|
|
||||||
ON DELETE SET NULL ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE consumptions ( -- transactions involving buying a product
|
|
||||||
ta_id INTEGER PRIMARY KEY,
|
|
||||||
product TEXT NOT NULL,
|
|
||||||
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE deposits ( -- transactions involving depositing cash
|
|
||||||
ta_id INTEGER PRIMARY KEY,
|
|
||||||
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE modifications ( -- transactions involving balance modification by an admin
|
|
||||||
ta_id INTEGER NOT NULL,
|
|
||||||
agent TEXT NOT NULL,
|
|
||||||
reason TEXT DEFAULT NULL,
|
|
||||||
PRIMARY KEY (ta_id),
|
|
||||||
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE receipts ( -- receipts sent to the users
|
|
||||||
receipt_id INTEGER PRIMARY KEY,
|
|
||||||
user_id INTEGER NOT NULL,
|
|
||||||
first_ta_id INTEGER DEFAULT NULL,
|
|
||||||
last_ta_id INTEGER DEFAULT NULL,
|
|
||||||
date INTEGER(8) DEFAULT (STRFTIME('%s', 'now')),
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(user_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE,
|
|
||||||
FOREIGN KEY (first_ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE SET NULL ON UPDATE CASCADE,
|
|
||||||
FOREIGN KEY (last_ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE SET NULL ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''']
|
|
||||||
|
|
||||||
|
|
||||||
SCHEMAS[8] = [
|
|
||||||
'''
|
|
||||||
CREATE TABLE users (
|
|
||||||
user_id INTEGER PRIMARY KEY,
|
|
||||||
username TEXT UNIQUE NOT NULL,
|
|
||||||
email TEXT DEFAULT NULL,
|
|
||||||
password TEXT NOT NULL,
|
|
||||||
touchkey TEXT DEFAULT NULL,
|
|
||||||
is_admin INTEGER(1) NOT NULL DEFAULT 0,
|
|
||||||
is_member INTEGER(1) NOT NULL DEFAULT 1,
|
|
||||||
balance INTEGER(8) NOT NULL DEFAULT 0,
|
|
||||||
lastchange INTEGER(8) NOT NULL DEFAULT 0,
|
|
||||||
receipt_pref INTEGER(1) NOT NULL DEFAULT 0,
|
|
||||||
created INTEGER(8) NOT NULL DEFAULT 0,
|
|
||||||
logout_after_purchase INTEGER(1) DEFAULT 0
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE products (
|
|
||||||
product_id INTEGER PRIMARY KEY,
|
|
||||||
name TEXT UNIQUE NOT NULL,
|
|
||||||
stock INTEGER(8) DEFAULT 0,
|
|
||||||
stockable INTEGER(1) DEFAULT 1,
|
|
||||||
price_member INTEGER(8) NOT NULL,
|
|
||||||
price_non_member INTEGER(8) NOT NULL,
|
|
||||||
custom_price INTEGER(1) DEFAULT 0,
|
|
||||||
ean TEXT UNIQUE DEFAULT NULL
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE transactions ( -- "superclass" of the following 3 tables
|
|
||||||
ta_id INTEGER PRIMARY KEY,
|
|
||||||
user_id INTEGER DEFAULT NULL,
|
|
||||||
value INTEGER(8) NOT NULL,
|
|
||||||
old_balance INTEGER(8) NOT NULL,
|
|
||||||
date INTEGER(8) DEFAULT (STRFTIME('%s', 'now')),
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(user_id)
|
|
||||||
ON DELETE SET NULL ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE consumptions ( -- transactions involving buying a product
|
|
||||||
ta_id INTEGER PRIMARY KEY,
|
|
||||||
product TEXT NOT NULL,
|
|
||||||
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE deposits ( -- transactions involving depositing cash
|
|
||||||
ta_id INTEGER PRIMARY KEY,
|
|
||||||
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE modifications ( -- transactions involving balance modification by an admin
|
|
||||||
ta_id INTEGER NOT NULL,
|
|
||||||
agent TEXT NOT NULL,
|
|
||||||
reason TEXT DEFAULT NULL,
|
|
||||||
PRIMARY KEY (ta_id),
|
|
||||||
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE receipts ( -- receipts sent to the users
|
|
||||||
receipt_id INTEGER PRIMARY KEY,
|
|
||||||
user_id INTEGER NOT NULL,
|
|
||||||
first_ta_id INTEGER DEFAULT NULL,
|
|
||||||
last_ta_id INTEGER DEFAULT NULL,
|
|
||||||
date INTEGER(8) DEFAULT (STRFTIME('%s', 'now')),
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(user_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE,
|
|
||||||
FOREIGN KEY (first_ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE SET NULL ON UPDATE CASCADE,
|
|
||||||
FOREIGN KEY (last_ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE SET NULL ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''']
|
|
||||||
|
|
||||||
|
|
||||||
SCHEMAS[9] = [
|
|
||||||
'''
|
|
||||||
CREATE TABLE users (
|
|
||||||
user_id INTEGER PRIMARY KEY,
|
|
||||||
username TEXT UNIQUE NOT NULL,
|
|
||||||
email TEXT DEFAULT NULL,
|
|
||||||
password TEXT NOT NULL,
|
|
||||||
touchkey TEXT DEFAULT NULL,
|
|
||||||
is_admin INTEGER(1) NOT NULL DEFAULT 0,
|
|
||||||
is_member INTEGER(1) NOT NULL DEFAULT 1,
|
|
||||||
balance INTEGER(8) NOT NULL DEFAULT 0,
|
|
||||||
lastchange INTEGER(8) NOT NULL DEFAULT 0,
|
|
||||||
receipt_pref INTEGER(1) NOT NULL DEFAULT 0,
|
|
||||||
created INTEGER(8) NOT NULL DEFAULT 0,
|
|
||||||
logout_after_purchase INTEGER(1) DEFAULT 0
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE products (
|
|
||||||
product_id INTEGER PRIMARY KEY,
|
|
||||||
name TEXT UNIQUE NOT NULL,
|
|
||||||
stock INTEGER(8) DEFAULT 0,
|
|
||||||
stockable INTEGER(1) DEFAULT 1,
|
|
||||||
price_member INTEGER(8) NOT NULL,
|
|
||||||
price_non_member INTEGER(8) NOT NULL,
|
|
||||||
custom_price INTEGER(1) DEFAULT 0,
|
|
||||||
ean TEXT UNIQUE DEFAULT NULL
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE transactions ( -- "superclass" of the following 3 tables
|
|
||||||
ta_id INTEGER PRIMARY KEY,
|
|
||||||
user_id INTEGER DEFAULT NULL,
|
|
||||||
value INTEGER(8) NOT NULL,
|
|
||||||
old_balance INTEGER(8) NOT NULL,
|
|
||||||
date INTEGER(8) DEFAULT (STRFTIME('%s', 'now')),
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(user_id)
|
|
||||||
ON DELETE SET NULL ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE consumptions ( -- transactions involving buying a product
|
|
||||||
ta_id INTEGER PRIMARY KEY,
|
|
||||||
product TEXT NOT NULL,
|
|
||||||
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE deposits ( -- transactions involving depositing cash
|
|
||||||
ta_id INTEGER PRIMARY KEY,
|
|
||||||
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE modifications ( -- transactions involving balance modification by an admin
|
|
||||||
ta_id INTEGER NOT NULL,
|
|
||||||
agent TEXT NOT NULL,
|
|
||||||
reason TEXT DEFAULT NULL,
|
|
||||||
PRIMARY KEY (ta_id),
|
|
||||||
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE receipts ( -- receipts sent to the users
|
|
||||||
receipt_id INTEGER PRIMARY KEY,
|
|
||||||
user_id INTEGER NOT NULL,
|
|
||||||
first_ta_id INTEGER DEFAULT NULL,
|
|
||||||
last_ta_id INTEGER DEFAULT NULL,
|
|
||||||
date INTEGER(8) DEFAULT (STRFTIME('%s', 'now')),
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(user_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE,
|
|
||||||
FOREIGN KEY (first_ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE SET NULL ON UPDATE CASCADE,
|
|
||||||
FOREIGN KEY (last_ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE SET NULL ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE tokens ( -- authentication tokens such as barcodes
|
|
||||||
token_id INTEGER PRIMARY KEY,
|
|
||||||
user_id INTEGER NOT NULL,
|
|
||||||
token TEXT UNIQUE NOT NULL,
|
|
||||||
name TEXT UNIQUE NOT NULL,
|
|
||||||
date INTEGER(8) DEFAULT (STRFTIME('%s', 'now')),
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(user_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''']
|
|
||||||
|
|
||||||
|
|
||||||
SCHEMAS[10] = [
|
|
||||||
'''
|
|
||||||
CREATE TABLE users (
|
|
||||||
user_id INTEGER PRIMARY KEY,
|
|
||||||
username TEXT UNIQUE NOT NULL COLLATE NOCASE,
|
|
||||||
email TEXT DEFAULT NULL,
|
|
||||||
password TEXT NOT NULL,
|
|
||||||
touchkey TEXT DEFAULT NULL,
|
|
||||||
is_admin INTEGER(1) NOT NULL DEFAULT 0,
|
|
||||||
is_member INTEGER(1) NOT NULL DEFAULT 1,
|
|
||||||
balance INTEGER(8) NOT NULL DEFAULT 0,
|
|
||||||
lastchange INTEGER(8) NOT NULL DEFAULT 0,
|
|
||||||
receipt_pref INTEGER(1) NOT NULL DEFAULT 0,
|
|
||||||
created INTEGER(8) NOT NULL DEFAULT 0,
|
|
||||||
logout_after_purchase INTEGER(1) DEFAULT 0
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE products (
|
|
||||||
product_id INTEGER PRIMARY KEY,
|
|
||||||
name TEXT UNIQUE NOT NULL,
|
|
||||||
stock INTEGER(8) DEFAULT 0,
|
|
||||||
stockable INTEGER(1) DEFAULT 1,
|
|
||||||
price_member INTEGER(8) NOT NULL,
|
|
||||||
price_non_member INTEGER(8) NOT NULL,
|
|
||||||
custom_price INTEGER(1) DEFAULT 0,
|
|
||||||
ean TEXT UNIQUE DEFAULT NULL
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE transactions ( -- "superclass" of the following 3 tables
|
|
||||||
ta_id INTEGER PRIMARY KEY,
|
|
||||||
user_id INTEGER DEFAULT NULL,
|
|
||||||
value INTEGER(8) NOT NULL,
|
|
||||||
old_balance INTEGER(8) NOT NULL,
|
|
||||||
date INTEGER(8) DEFAULT (STRFTIME('%s', 'now')),
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(user_id)
|
|
||||||
ON DELETE SET NULL ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE consumptions ( -- transactions involving buying a product
|
|
||||||
ta_id INTEGER PRIMARY KEY,
|
|
||||||
product TEXT NOT NULL,
|
|
||||||
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE deposits ( -- transactions involving depositing cash
|
|
||||||
ta_id INTEGER PRIMARY KEY,
|
|
||||||
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE modifications ( -- transactions involving balance modification by an admin
|
|
||||||
ta_id INTEGER NOT NULL,
|
|
||||||
agent TEXT NOT NULL,
|
|
||||||
reason TEXT DEFAULT NULL,
|
|
||||||
PRIMARY KEY (ta_id),
|
|
||||||
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE receipts ( -- receipts sent to the users
|
|
||||||
receipt_id INTEGER PRIMARY KEY,
|
|
||||||
user_id INTEGER NOT NULL,
|
|
||||||
first_ta_id INTEGER DEFAULT NULL,
|
|
||||||
last_ta_id INTEGER DEFAULT NULL,
|
|
||||||
date INTEGER(8) DEFAULT (STRFTIME('%s', 'now')),
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(user_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE,
|
|
||||||
FOREIGN KEY (first_ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE SET NULL ON UPDATE CASCADE,
|
|
||||||
FOREIGN KEY (last_ta_id) REFERENCES transactions(ta_id)
|
|
||||||
ON DELETE SET NULL ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''',
|
|
||||||
'''
|
|
||||||
CREATE TABLE tokens ( -- authentication tokens such as barcodes
|
|
||||||
token_id INTEGER PRIMARY KEY,
|
|
||||||
user_id INTEGER NOT NULL,
|
|
||||||
token TEXT UNIQUE NOT NULL,
|
|
||||||
name TEXT UNIQUE NOT NULL,
|
|
||||||
date INTEGER(8) DEFAULT (STRFTIME('%s', 'now')),
|
|
||||||
FOREIGN KEY (user_id) REFERENCES users(user_id)
|
|
||||||
ON DELETE CASCADE ON UPDATE CASCADE
|
|
||||||
);
|
|
||||||
''']
|
|
|
@ -1,10 +1,10 @@
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
from unittest.mock import PropertyMock, patch
|
||||||
|
|
||||||
import sqlite3
|
import sqlite3
|
||||||
|
|
||||||
from matemat.db import DatabaseWrapper
|
from matemat.db import DatabaseWrapper
|
||||||
from matemat.db.schemas import SCHEMAS
|
|
||||||
|
|
||||||
|
|
||||||
class TestMigrations(unittest.TestCase):
|
class TestMigrations(unittest.TestCase):
|
||||||
|
@ -15,204 +15,13 @@ class TestMigrations(unittest.TestCase):
|
||||||
|
|
||||||
def _initialize_db(self, schema_version: int):
|
def _initialize_db(self, schema_version: int):
|
||||||
self.db._sqlite_db = sqlite3.connect(':memory:')
|
self.db._sqlite_db = sqlite3.connect(':memory:')
|
||||||
cursor: sqlite3.Cursor = self.db._sqlite_db.cursor()
|
self.db._setup()
|
||||||
cursor.execute('BEGIN EXCLUSIVE')
|
|
||||||
for cmd in SCHEMAS[schema_version]:
|
|
||||||
cursor.execute(cmd)
|
|
||||||
cursor.execute('COMMIT')
|
|
||||||
|
|
||||||
def test_downgrade_fail(self):
|
def test_downgrade_fail(self):
|
||||||
# Test that downgrades are forbidden
|
# Test that downgrades are forbidden
|
||||||
self.db.SCHEMA_VERSION = 1
|
|
||||||
self.db._sqlite_db = sqlite3.connect(':memory:')
|
self.db._sqlite_db = sqlite3.connect(':memory:')
|
||||||
self.db._sqlite_db.execute('PRAGMA user_version = 2')
|
self.db._sqlite_db.execute('PRAGMA user_version = 2')
|
||||||
|
with patch('matemat.db.DatabaseWrapper.schema_version', new_callable=PropertyMock(return_value=1)):
|
||||||
with self.assertRaises(RuntimeError):
|
with self.assertRaises(RuntimeError):
|
||||||
with self.db:
|
with self.db:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def test_upgrade_1_to_2(self):
|
|
||||||
# Setup test db with example entries covering - hopefully - all cases
|
|
||||||
self._initialize_db(1)
|
|
||||||
cursor: sqlite3.Cursor = self.db._sqlite_db.cursor()
|
|
||||||
cursor.execute('''
|
|
||||||
INSERT INTO users VALUES
|
|
||||||
(1, 'testadmin', 'a@b.c', '$2a$10$herebehashes', NULL, 1, 1, 1337, 0),
|
|
||||||
(2, 'testuser', NULL, '$2a$10$herebehashes', '$2a$10$herebehashes', 0, 1, 4242, 0),
|
|
||||||
(3, 'alien', NULL, '$2a$10$herebehashes', '$2a$10$herebehashes', 0, 0, 1234, 0)
|
|
||||||
''')
|
|
||||||
cursor.execute('''
|
|
||||||
INSERT INTO products VALUES
|
|
||||||
(1, 'Club Mate', 42, 200, 250),
|
|
||||||
(2, 'Flora Power Mate (1/4l)', 10, 100, 150)
|
|
||||||
''')
|
|
||||||
cursor.execute('''
|
|
||||||
INSERT INTO consumption VALUES
|
|
||||||
(1, 1, 5), (1, 2, 3), (2, 2, 10), (3, 1, 3), (3, 2, 4)
|
|
||||||
''')
|
|
||||||
cursor.execute('PRAGMA user_version = 1')
|
|
||||||
|
|
||||||
# Kick off the migration
|
|
||||||
schema_version = self.db.SCHEMA_VERSION
|
|
||||||
self.db.SCHEMA_VERSION = 2
|
|
||||||
self.db._setup()
|
|
||||||
self.db.SCHEMA_VERSION = schema_version
|
|
||||||
|
|
||||||
# Test whether the new tables were created
|
|
||||||
cursor.execute('PRAGMA table_info(transactions)')
|
|
||||||
self.assertNotEqual(0, len(cursor.fetchall()))
|
|
||||||
cursor.execute('PRAGMA table_info(consumptions)')
|
|
||||||
self.assertNotEqual(0, len(cursor.fetchall()))
|
|
||||||
cursor.execute('PRAGMA table_info(deposits)')
|
|
||||||
self.assertNotEqual(0, len(cursor.fetchall()))
|
|
||||||
cursor.execute('PRAGMA table_info(modifications)')
|
|
||||||
self.assertNotEqual(0, len(cursor.fetchall()))
|
|
||||||
# Test whether the old consumption table was dropped
|
|
||||||
cursor.execute('PRAGMA table_info(consumption)')
|
|
||||||
self.assertEqual(0, len(cursor.fetchall()))
|
|
||||||
|
|
||||||
# Test number of entries in the new tables
|
|
||||||
cursor.execute('SELECT COUNT(ta_id) FROM transactions')
|
|
||||||
self.assertEqual(25, cursor.fetchone()[0])
|
|
||||||
cursor.execute('SELECT COUNT(ta_id) FROM consumptions')
|
|
||||||
self.assertEqual(25, cursor.fetchone()[0])
|
|
||||||
cursor.execute('SELECT COUNT(ta_id) FROM deposits')
|
|
||||||
self.assertEqual(0, cursor.fetchone()[0])
|
|
||||||
cursor.execute('SELECT COUNT(ta_id) FROM modifications')
|
|
||||||
self.assertEqual(0, cursor.fetchone()[0])
|
|
||||||
|
|
||||||
# The (user_id=2 x product_id=1) combination should never appear
|
|
||||||
cursor.execute('''
|
|
||||||
SELECT COUNT(t.ta_id)
|
|
||||||
FROM transactions AS t
|
|
||||||
LEFT JOIN consumptions AS c
|
|
||||||
ON t.ta_id = c.ta_id
|
|
||||||
WHERE t.user_id = 2 AND c.product_id = 1''')
|
|
||||||
self.assertEqual(0, cursor.fetchone()[0])
|
|
||||||
|
|
||||||
# Test that one entry per consumption was created, and their values match the negative price
|
|
||||||
cursor.execute('''
|
|
||||||
SELECT COUNT(t.ta_id)
|
|
||||||
FROM transactions AS t
|
|
||||||
LEFT JOIN consumptions AS c
|
|
||||||
ON t.ta_id = c.ta_id
|
|
||||||
WHERE t.user_id = 1 AND c.product_id = 1 AND t.value = -200''')
|
|
||||||
self.assertEqual(5, cursor.fetchone()[0])
|
|
||||||
cursor.execute('''
|
|
||||||
SELECT COUNT(t.ta_id)
|
|
||||||
FROM transactions AS t
|
|
||||||
LEFT JOIN consumptions AS c
|
|
||||||
ON t.ta_id = c.ta_id
|
|
||||||
WHERE t.user_id = 1 AND c.product_id = 2 AND t.value = -100''')
|
|
||||||
self.assertEqual(3, cursor.fetchone()[0])
|
|
||||||
cursor.execute('''
|
|
||||||
SELECT COUNT(t.ta_id)
|
|
||||||
FROM transactions AS t
|
|
||||||
LEFT JOIN consumptions AS c
|
|
||||||
ON t.ta_id = c.ta_id
|
|
||||||
WHERE t.user_id = 2 AND c.product_id = 2 AND t.value = -100''')
|
|
||||||
self.assertEqual(10, cursor.fetchone()[0])
|
|
||||||
cursor.execute('''
|
|
||||||
SELECT COUNT(t.ta_id)
|
|
||||||
FROM transactions AS t
|
|
||||||
LEFT JOIN consumptions AS c
|
|
||||||
ON t.ta_id = c.ta_id
|
|
||||||
WHERE t.user_id = 3 AND c.product_id = 1 AND t.value = -250''')
|
|
||||||
self.assertEqual(3, cursor.fetchone()[0])
|
|
||||||
cursor.execute('''
|
|
||||||
SELECT COUNT(t.ta_id)
|
|
||||||
FROM transactions AS t
|
|
||||||
LEFT JOIN consumptions AS c
|
|
||||||
ON t.ta_id = c.ta_id
|
|
||||||
WHERE t.user_id = 3 AND c.product_id = 2 AND t.value = -150''')
|
|
||||||
self.assertEqual(4, cursor.fetchone()[0])
|
|
||||||
|
|
||||||
def test_upgrade_2_to_3(self):
|
|
||||||
# Setup test db with example entries covering - hopefully - all cases
|
|
||||||
self._initialize_db(2)
|
|
||||||
cursor: sqlite3.Cursor = self.db._sqlite_db.cursor()
|
|
||||||
cursor.execute('''
|
|
||||||
INSERT INTO users VALUES
|
|
||||||
(1, 'testadmin', 'a@b.c', '$2a$10$herebehashes', NULL, 1, 1, 1337, 0),
|
|
||||||
(2, 'testuser', NULL, '$2a$10$herebehashes', '$2a$10$herebehashes', 0, 1, 4242, 0),
|
|
||||||
(3, 'alien', NULL, '$2a$10$herebehashes', '$2a$10$herebehashes', 0, 0, 1234, 0),
|
|
||||||
(4, 'neverused', NULL, '$2a$10$herebehashes', '$2a$10$herebehashes', 0, 0, 1234, 1234)
|
|
||||||
''')
|
|
||||||
cursor.execute('''
|
|
||||||
INSERT INTO products VALUES
|
|
||||||
(1, 'Club Mate', 42, 200, 250),
|
|
||||||
(2, 'Flora Power Mate', 10, 100, 150)
|
|
||||||
''')
|
|
||||||
cursor.execute('''
|
|
||||||
INSERT INTO transactions VALUES
|
|
||||||
(1, 1, 4200, 0, 1000), -- deposit
|
|
||||||
(2, 2, 1337, 0, 1001), -- modification
|
|
||||||
(3, 3, 1337, 0, 1002), -- modification with deleted agent
|
|
||||||
(4, 2, -200, 1337, 1003), -- consumption
|
|
||||||
(5, 3, -200, 1337, 1004) -- consumption with deleted product
|
|
||||||
''')
|
|
||||||
cursor.execute('''INSERT INTO deposits VALUES (1)''')
|
|
||||||
cursor.execute('''
|
|
||||||
INSERT INTO modifications VALUES
|
|
||||||
(2, 1, 'Account migration'),
|
|
||||||
(3, 42, 'You can''t find out who i am... MUAHAHAHA!!!')''')
|
|
||||||
cursor.execute('''INSERT INTO consumptions VALUES (4, 2), (5, 42)''')
|
|
||||||
cursor.execute('''PRAGMA user_version = 2''')
|
|
||||||
|
|
||||||
# Kick off the migration
|
|
||||||
schema_version = self.db.SCHEMA_VERSION
|
|
||||||
self.db.SCHEMA_VERSION = 3
|
|
||||||
self.db._setup()
|
|
||||||
self.db.SCHEMA_VERSION = schema_version
|
|
||||||
|
|
||||||
# Make sure the receipts table was created
|
|
||||||
cursor.execute('''SELECT COUNT(receipt_id) FROM receipts''')
|
|
||||||
self.assertEqual(0, cursor.fetchone()[0])
|
|
||||||
|
|
||||||
# Make sure users.created was populated with the expected values
|
|
||||||
cursor.execute('''SELECT u.created FROM users AS u ORDER BY u.user_id ASC''')
|
|
||||||
self.assertEqual([(940,), (941,), (942,), (1174,)], cursor.fetchall())
|
|
||||||
|
|
||||||
# Make sure the modifications table was changed to contain the username, or a fallback
|
|
||||||
cursor.execute('''SELECT agent FROM modifications WHERE ta_id = 2''')
|
|
||||||
self.assertEqual('testadmin', cursor.fetchone()[0])
|
|
||||||
cursor.execute('''SELECT agent FROM modifications WHERE ta_id = 3''')
|
|
||||||
self.assertEqual('<unknown>', cursor.fetchone()[0])
|
|
||||||
|
|
||||||
# Make sure the consumptions table was changed to contain the product name, or a fallback
|
|
||||||
cursor.execute('''SELECT product FROM consumptions WHERE ta_id = 4''')
|
|
||||||
self.assertEqual('Flora Power Mate', cursor.fetchone()[0])
|
|
||||||
cursor.execute('''SELECT product FROM consumptions WHERE ta_id = 5''')
|
|
||||||
self.assertEqual('<unknown>', cursor.fetchone()[0])
|
|
||||||
|
|
||||||
def test_upgrade_3_to_4(self):
|
|
||||||
# Setup test db with example entries to test schema change
|
|
||||||
self._initialize_db(3)
|
|
||||||
cursor: sqlite3.Cursor = self.db._sqlite_db.cursor()
|
|
||||||
cursor.execute('''
|
|
||||||
INSERT INTO users VALUES
|
|
||||||
(1, 'testadmin', 'a@b.c', '$2a$10$herebehashes', NULL, 1, 1, 1337, 0, 0, 0)
|
|
||||||
''')
|
|
||||||
cursor.execute('''
|
|
||||||
INSERT INTO products VALUES
|
|
||||||
(1, 'Club Mate', 42, 200, 250)
|
|
||||||
''')
|
|
||||||
cursor.execute('''
|
|
||||||
INSERT INTO transactions VALUES (1, 1, 4200, 0, 1000)
|
|
||||||
''')
|
|
||||||
cursor.execute('''
|
|
||||||
INSERT INTO receipts VALUES (1, 1, 1, 1, 1337)
|
|
||||||
''')
|
|
||||||
cursor.execute('PRAGMA user_version = 3')
|
|
||||||
|
|
||||||
# Kick off the migration
|
|
||||||
schema_version = self.db.SCHEMA_VERSION
|
|
||||||
self.db.SCHEMA_VERSION = 4
|
|
||||||
self.db._setup()
|
|
||||||
self.db.SCHEMA_VERSION = schema_version
|
|
||||||
|
|
||||||
# Make sure entries from the receipts table are preserved
|
|
||||||
cursor.execute('''SELECT COUNT(receipt_id) FROM receipts''')
|
|
||||||
self.assertEqual(1, cursor.fetchone()[0])
|
|
||||||
|
|
||||||
# Make sure transaction IDs can be set to NULL
|
|
||||||
cursor.execute('UPDATE receipts SET first_ta_id = NULL, last_ta_id = NULL')
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ class DatabaseTest(unittest.TestCase):
|
||||||
Test creation of database schema in an empty database
|
Test creation of database schema in an empty database
|
||||||
"""
|
"""
|
||||||
with self.db as db:
|
with self.db as db:
|
||||||
self.assertEqual(DatabaseWrapper.SCHEMA_VERSION, db._user_version)
|
self.assertEqual(db.schema_version, db._user_version)
|
||||||
|
|
||||||
def test_in_transaction(self) -> None:
|
def test_in_transaction(self) -> None:
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
|
|
||||||
from typing import Any, Optional
|
from typing import Any, Optional
|
||||||
|
|
||||||
|
import sqlite3
|
||||||
|
|
||||||
from matemat.exceptions import DatabaseConsistencyError
|
from matemat.exceptions import DatabaseConsistencyError
|
||||||
from matemat.db.schemas import SCHEMAS
|
import matemat.db.migrations
|
||||||
from matemat.db.migrations import *
|
|
||||||
|
|
||||||
|
|
||||||
class DatabaseTransaction(object):
|
class DatabaseTransaction(object):
|
||||||
|
@ -40,8 +41,6 @@ class DatabaseTransaction(object):
|
||||||
|
|
||||||
class DatabaseWrapper(object):
|
class DatabaseWrapper(object):
|
||||||
|
|
||||||
SCHEMA_VERSION = 10
|
|
||||||
|
|
||||||
def __init__(self, filename: str) -> None:
|
def __init__(self, filename: str) -> None:
|
||||||
self._filename: str = filename
|
self._filename: str = filename
|
||||||
self._sqlite_db: Optional[sqlite3.Connection] = None
|
self._sqlite_db: Optional[sqlite3.Connection] = None
|
||||||
|
@ -61,16 +60,11 @@ class DatabaseWrapper(object):
|
||||||
def _setup(self) -> None:
|
def _setup(self) -> None:
|
||||||
# Create or update schemas if necessary
|
# Create or update schemas if necessary
|
||||||
version: int = self._user_version
|
version: int = self._user_version
|
||||||
if version < 1:
|
if version < self.schema_version:
|
||||||
# Don't use executescript, as it issues a COMMIT first
|
self._upgrade(from_version=version, to_version=self.schema_version)
|
||||||
with self.transaction() as c:
|
self._user_version = self.schema_version
|
||||||
for command in SCHEMAS[self.SCHEMA_VERSION]:
|
elif version > self.schema_version:
|
||||||
c.execute(command)
|
|
||||||
elif version < self.SCHEMA_VERSION:
|
|
||||||
self._upgrade(from_version=version, to_version=self.SCHEMA_VERSION)
|
|
||||||
elif version > self.SCHEMA_VERSION:
|
|
||||||
raise RuntimeError('Database schema is newer than supported by this version of Matemat.')
|
raise RuntimeError('Database schema is newer than supported by this version of Matemat.')
|
||||||
self._user_version = self.SCHEMA_VERSION
|
|
||||||
|
|
||||||
# Enable foreign key enforcement
|
# Enable foreign key enforcement
|
||||||
cursor = self._sqlite_db.cursor()
|
cursor = self._sqlite_db.cursor()
|
||||||
|
@ -79,35 +73,20 @@ class DatabaseWrapper(object):
|
||||||
def _upgrade(self, from_version: int, to_version: int) -> None:
|
def _upgrade(self, from_version: int, to_version: int) -> None:
|
||||||
if from_version >= to_version:
|
if from_version >= to_version:
|
||||||
return
|
return
|
||||||
|
# Create backup before migration
|
||||||
if self._filename != ':memory:':
|
if self._filename != ':memory:':
|
||||||
bakfile = f'{self._filename}_{from_version}_{to_version}.bak'
|
bakfile = f'{self._filename}_{from_version}_{to_version}.bak'
|
||||||
bak = sqlite3.connect(bakfile)
|
bak = sqlite3.connect(bakfile)
|
||||||
with bak:
|
with bak:
|
||||||
self._sqlite_db.backup(bak, pages=1)
|
self._sqlite_db.backup(bak, pages=1)
|
||||||
bak.close()
|
bak.close()
|
||||||
|
# Iterate through migrations, executing them one by one
|
||||||
with self.transaction() as c:
|
with self.transaction() as c:
|
||||||
c.execute('PRAGMA foreign_keys=OFF')
|
c.execute('PRAGMA foreign_keys=OFF')
|
||||||
c.execute('PRAGMA legacy_alter_table=ON')
|
c.execute('PRAGMA legacy_alter_table=ON')
|
||||||
if from_version <= 1 and to_version >= 2:
|
for i in range(from_version+1, to_version+1):
|
||||||
migrate_schema_1_to_2(c)
|
migration = getattr(matemat.db.migrations, f'migrate_schema_{i}')
|
||||||
if from_version <= 2 and to_version >= 3:
|
migration(c)
|
||||||
migrate_schema_2_to_3(c)
|
|
||||||
if from_version <= 3 and to_version >= 4:
|
|
||||||
migrate_schema_3_to_4(c)
|
|
||||||
if from_version <= 4 and to_version >= 5:
|
|
||||||
migrate_schema_4_to_5(c)
|
|
||||||
if from_version <= 5 and to_version >= 6:
|
|
||||||
migrate_schema_5_to_6(c)
|
|
||||||
if from_version <= 6 and to_version >= 7:
|
|
||||||
migrate_schema_6_to_7(c)
|
|
||||||
if from_version <= 7 and to_version >= 8:
|
|
||||||
migrate_schema_7_to_8(c)
|
|
||||||
if from_version <= 7 and to_version >= 8:
|
|
||||||
migrate_schema_7_to_8(c)
|
|
||||||
if from_version <= 8 and to_version >= 9:
|
|
||||||
migrate_schema_8_to_9(c)
|
|
||||||
if from_version <= 9 and to_version >= 10:
|
|
||||||
migrate_schema_9_to_10(c)
|
|
||||||
c.execute('PRAGMA foreign_key_check')
|
c.execute('PRAGMA foreign_key_check')
|
||||||
c.execute('PRAGMA foreign_keys=ON')
|
c.execute('PRAGMA foreign_keys=ON')
|
||||||
|
|
||||||
|
@ -146,3 +125,13 @@ class DatabaseWrapper(object):
|
||||||
raise RuntimeError(f'Database connection to {self._filename} is not established.')
|
raise RuntimeError(f'Database connection to {self._filename} is not established.')
|
||||||
cursor = self._sqlite_db.cursor()
|
cursor = self._sqlite_db.cursor()
|
||||||
cursor.execute(f'PRAGMA user_version = {version}')
|
cursor.execute(f'PRAGMA user_version = {version}')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def schema_version(self) -> int:
|
||||||
|
max_migration = 0
|
||||||
|
for name in dir(matemat.db.migrations):
|
||||||
|
if not name.startswith('migrate_schema_'):
|
||||||
|
continue
|
||||||
|
migration = int(name.split('_')[2])
|
||||||
|
max_migration = max(max_migration, migration)
|
||||||
|
return max_migration
|
||||||
|
|
Loading…
Reference in a new issue