mirror of
https://github.com/YosysHQ/sby.git
synced 2025-08-11 07:40:54 +00:00
Test status db schema
`--status` reports if the schema doesn't match. `--statusreset` is able to perform a hard reset, dropping all the existing tables and calling `_setup()`.
This commit is contained in:
parent
ad9382d46c
commit
10040ce859
2 changed files with 66 additions and 50 deletions
|
@ -85,12 +85,14 @@ if status_show or status_reset:
|
||||||
|
|
||||||
status_db = SbyStatusDb(status_path, task=None)
|
status_db = SbyStatusDb(status_path, task=None)
|
||||||
|
|
||||||
if status_show:
|
|
||||||
status_db.print_status_summary()
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
if status_reset:
|
if status_reset:
|
||||||
status_db.reset()
|
status_db.reset()
|
||||||
|
elif status_db.test_schema():
|
||||||
|
print(f"ERROR: Status database does not match expected formatted. Use --statusreset to reset.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if status_show:
|
||||||
|
status_db.print_status_summary()
|
||||||
|
|
||||||
status_db.db.close()
|
status_db.db.close()
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
|
@ -4,6 +4,7 @@ import sqlite3
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import json
|
import json
|
||||||
|
import re
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
@ -13,6 +14,45 @@ from sby_design import SbyProperty, pretty_path
|
||||||
|
|
||||||
Fn = TypeVar("Fn", bound=Callable[..., Any])
|
Fn = TypeVar("Fn", bound=Callable[..., Any])
|
||||||
|
|
||||||
|
SQLSCRIPT = """\
|
||||||
|
CREATE TABLE task (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
workdir TEXT,
|
||||||
|
mode TEXT,
|
||||||
|
created REAL
|
||||||
|
);
|
||||||
|
CREATE TABLE task_status (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
task INTEGER,
|
||||||
|
status TEXT,
|
||||||
|
data TEXT,
|
||||||
|
created REAL,
|
||||||
|
FOREIGN KEY(task) REFERENCES task(id)
|
||||||
|
);
|
||||||
|
CREATE TABLE task_property (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
task INTEGER,
|
||||||
|
src TEXT,
|
||||||
|
name TEXT,
|
||||||
|
created REAL,
|
||||||
|
FOREIGN KEY(task) REFERENCES task(id)
|
||||||
|
);
|
||||||
|
CREATE TABLE task_property_status (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
task_property INTEGER,
|
||||||
|
status TEXT,
|
||||||
|
data TEXT,
|
||||||
|
created REAL,
|
||||||
|
FOREIGN KEY(task_property) REFERENCES task_property(id)
|
||||||
|
);
|
||||||
|
CREATE TABLE task_property_data (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
task_property INTEGER,
|
||||||
|
kind TEXT,
|
||||||
|
data TEXT,
|
||||||
|
created REAL,
|
||||||
|
FOREIGN KEY(task_property) REFERENCES task_property(id)
|
||||||
|
);"""
|
||||||
|
|
||||||
def transaction(method: Fn) -> Fn:
|
def transaction(method: Fn) -> Fn:
|
||||||
@wraps(method)
|
@wraps(method)
|
||||||
|
@ -79,50 +119,17 @@ class SbyStatusDb:
|
||||||
|
|
||||||
@transaction
|
@transaction
|
||||||
def _setup(self):
|
def _setup(self):
|
||||||
script = """
|
for statement in SQLSCRIPT.split(";\n"):
|
||||||
CREATE TABLE task (
|
|
||||||
id INTEGER PRIMARY KEY,
|
|
||||||
workdir TEXT,
|
|
||||||
mode TEXT,
|
|
||||||
created REAL
|
|
||||||
);
|
|
||||||
CREATE TABLE task_status (
|
|
||||||
id INTEGER PRIMARY KEY,
|
|
||||||
task INTEGER,
|
|
||||||
status TEXT,
|
|
||||||
data TEXT,
|
|
||||||
created REAL,
|
|
||||||
FOREIGN KEY(task) REFERENCES task(id)
|
|
||||||
);
|
|
||||||
CREATE TABLE task_property (
|
|
||||||
id INTEGER PRIMARY KEY,
|
|
||||||
task INTEGER,
|
|
||||||
src TEXT,
|
|
||||||
name TEXT,
|
|
||||||
created REAL,
|
|
||||||
FOREIGN KEY(task) REFERENCES task(id)
|
|
||||||
);
|
|
||||||
CREATE TABLE task_property_status (
|
|
||||||
id INTEGER PRIMARY KEY,
|
|
||||||
task_property INTEGER,
|
|
||||||
status TEXT,
|
|
||||||
data TEXT,
|
|
||||||
created REAL,
|
|
||||||
FOREIGN KEY(task_property) REFERENCES task_property(id)
|
|
||||||
);
|
|
||||||
CREATE TABLE task_property_data (
|
|
||||||
id INTEGER PRIMARY KEY,
|
|
||||||
task_property INTEGER,
|
|
||||||
kind TEXT,
|
|
||||||
data TEXT,
|
|
||||||
created REAL,
|
|
||||||
FOREIGN KEY(task_property) REFERENCES task_property(id)
|
|
||||||
);
|
|
||||||
"""
|
|
||||||
for statement in script.split(";\n"):
|
|
||||||
statement = statement.strip()
|
statement = statement.strip()
|
||||||
if statement:
|
if statement:
|
||||||
self.db.execute(statement)
|
self.db.execute(statement)
|
||||||
|
self.db.execute("""PRAGMA foreign_keys = ON;""")
|
||||||
|
|
||||||
|
def test_schema(self) -> bool:
|
||||||
|
schema = self.db.execute("SELECT sql FROM sqlite_master;").fetchall()
|
||||||
|
schema_script = '\n'.join(str(sql[0] + ';') for sql in schema)
|
||||||
|
self._tables = re.findall(r"CREATE TABLE (\w+) \(", schema_script)
|
||||||
|
return schema_script != SQLSCRIPT
|
||||||
|
|
||||||
@transaction
|
@transaction
|
||||||
def create_task(self, workdir: str, mode: str) -> int:
|
def create_task(self, workdir: str, mode: str) -> int:
|
||||||
|
@ -284,11 +291,18 @@ class SbyStatusDb:
|
||||||
|
|
||||||
@transaction
|
@transaction
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.db.execute("""DELETE FROM task_property_status""")
|
hard_reset = self.test_schema()
|
||||||
self.db.execute("""DELETE FROM task_property_data""")
|
# table names can't be parameters, so we need to use f-strings
|
||||||
self.db.execute("""DELETE FROM task_property""")
|
# but it is safe to use here because it comes from the regex "\w+"
|
||||||
self.db.execute("""DELETE FROM task_status""")
|
for table in self._tables:
|
||||||
self.db.execute("""DELETE FROM task""")
|
if hard_reset:
|
||||||
|
self.log_debug(f"dropping {table}")
|
||||||
|
self.db.execute(f"DROP TABLE {table}")
|
||||||
|
else:
|
||||||
|
self.log_debug(f"clearing {table}")
|
||||||
|
self.db.execute(f"DELETE FROM {table}")
|
||||||
|
if hard_reset:
|
||||||
|
self._setup()
|
||||||
|
|
||||||
def print_status_summary(self):
|
def print_status_summary(self):
|
||||||
tasks, task_properties, task_property_statuses = self.all_status_data()
|
tasks, task_properties, task_property_statuses = self.all_status_data()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue