创建基本的表结构
This commit is contained in:
81
konabot/common/permsys/migrates/__init__.py
Normal file
81
konabot/common/permsys/migrates/__init__.py
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
from dataclasses import dataclass
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import aiosqlite
|
||||||
|
from loguru import logger
|
||||||
|
|
||||||
|
from konabot.common.database import DatabaseManager
|
||||||
|
from konabot.common.path import DATA_PATH
|
||||||
|
|
||||||
|
|
||||||
|
PATH_THISFOLDER = Path(__file__).parent
|
||||||
|
|
||||||
|
SQL_CHECK_EXISTS = (PATH_THISFOLDER / "./check_migrate_version_exists.sql").read_text()
|
||||||
|
SQL_CREATE_TABLE = (PATH_THISFOLDER / "./create_migrate_version_table.sql").read_text()
|
||||||
|
SQL_GET_MIGRATE_VERSION = (PATH_THISFOLDER / "get_migrate_version.sql").read_text()
|
||||||
|
SQL_UPDATE_VERSION = (PATH_THISFOLDER / "./update_migrate_version.sql").read_text()
|
||||||
|
|
||||||
|
db = DatabaseManager(DATA_PATH / "perm.sqlite3")
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Migration:
|
||||||
|
upgrade: str | Path
|
||||||
|
downgrade: str | Path
|
||||||
|
|
||||||
|
def get_upgrade_script(self) -> str:
|
||||||
|
if isinstance(self.upgrade, Path):
|
||||||
|
return self.upgrade.read_text()
|
||||||
|
return self.upgrade
|
||||||
|
|
||||||
|
def get_downgrade_script(self) -> str:
|
||||||
|
if isinstance(self.upgrade, Path):
|
||||||
|
return self.upgrade.read_text()
|
||||||
|
return self.upgrade
|
||||||
|
|
||||||
|
|
||||||
|
migrations = [
|
||||||
|
Migration(
|
||||||
|
PATH_THISFOLDER / "./mu1_create_permsys_table.sql",
|
||||||
|
PATH_THISFOLDER / "./md1_remove_permsys_table.sql",
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
TARGET_VERSION = len(migrations)
|
||||||
|
|
||||||
|
|
||||||
|
async def get_current_version(conn: aiosqlite.Connection) -> int:
|
||||||
|
cursor = await conn.execute(SQL_CHECK_EXISTS)
|
||||||
|
count = await cursor.fetchone()
|
||||||
|
assert count is not None
|
||||||
|
if count[0] < 1:
|
||||||
|
logger.info("权限系统数据表不存在,现在创建表")
|
||||||
|
await conn.executescript(SQL_CREATE_TABLE)
|
||||||
|
await conn.commit()
|
||||||
|
return -1
|
||||||
|
cursor = await conn.execute(SQL_GET_MIGRATE_VERSION)
|
||||||
|
row = await cursor.fetchone()
|
||||||
|
if row is None:
|
||||||
|
return -1
|
||||||
|
return row[0]
|
||||||
|
|
||||||
|
|
||||||
|
async def execute_migration(
|
||||||
|
conn: aiosqlite.Connection,
|
||||||
|
version: int = TARGET_VERSION,
|
||||||
|
migrations: list[Migration] = migrations,
|
||||||
|
):
|
||||||
|
now_version = await get_current_version(conn)
|
||||||
|
while now_version < version:
|
||||||
|
migration = migrations[now_version]
|
||||||
|
await conn.executescript(migration.get_upgrade_script())
|
||||||
|
now_version += 1
|
||||||
|
await conn.execute(SQL_UPDATE_VERSION, (now_version,))
|
||||||
|
await conn.commit()
|
||||||
|
while now_version > version:
|
||||||
|
migration = migrations[now_version - 1]
|
||||||
|
await conn.executescript(migration.get_downgrade_script())
|
||||||
|
now_version -= 1
|
||||||
|
await conn.execute(SQL_UPDATE_VERSION, (now_version,))
|
||||||
|
await conn.commit()
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
SELECT
|
||||||
|
COUNT(*)
|
||||||
|
FROM
|
||||||
|
sqlite_master
|
||||||
|
WHERE
|
||||||
|
type = 'table'
|
||||||
|
AND name = 'migrate_version'
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
CREATE TABLE migrate_version(version INT PRIMARY KEY);
|
||||||
|
INSERT INTO migrate_version(version)
|
||||||
|
VALUES(0);
|
||||||
4
konabot/common/permsys/migrates/get_migrate_version.sql
Normal file
4
konabot/common/permsys/migrates/get_migrate_version.sql
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
SELECT
|
||||||
|
version
|
||||||
|
FROM
|
||||||
|
migrate_version;
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
DROP TABLE IF EXISTS perm_entity;
|
||||||
|
DROP TABLE IF EXISTS perm_info;
|
||||||
25
konabot/common/permsys/migrates/mu1_create_permsys_table.sql
Normal file
25
konabot/common/permsys/migrates/mu1_create_permsys_table.sql
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
CREATE TABLE perm_entity(
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
platform TEXT NOT NULL,
|
||||||
|
entity_type TEXT NOT NULL,
|
||||||
|
external_id TEXT NOT NULL,
|
||||||
|
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE perm_info(
|
||||||
|
entity_id INTEGER NOT NULL,
|
||||||
|
config_key TEXT NOT NULL,
|
||||||
|
value BOOLEAN NOT NULL,
|
||||||
|
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TRIGGER perm_entity_update AFTER UPDATE
|
||||||
|
ON perm_entity BEGIN
|
||||||
|
UPDATE perm_entity SET updated_at=CURRENT_TIMESTAMP WHERE id=old.id;
|
||||||
|
END;
|
||||||
|
CREATE TRIGGER perm_info_update AFTER UPDATE
|
||||||
|
ON perm_info BEGIN
|
||||||
|
UPDATE perm_info SET updated_at=CURRENT_TIMESTAMP WHERE id=old.id;
|
||||||
|
END;
|
||||||
|
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
UPDATE migrate_version
|
||||||
|
SET version = ?;
|
||||||
32
tests/test_permsys.py
Normal file
32
tests/test_permsys.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
from contextlib import asynccontextmanager
|
||||||
|
from pathlib import Path
|
||||||
|
from tempfile import TemporaryDirectory
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from konabot.common.database import DatabaseManager
|
||||||
|
from konabot.common.permsys.migrates import execute_migration, get_current_version
|
||||||
|
|
||||||
|
|
||||||
|
@asynccontextmanager
|
||||||
|
async def tempdb():
|
||||||
|
with TemporaryDirectory() as _tempdir:
|
||||||
|
tempdir = Path(_tempdir)
|
||||||
|
db = DatabaseManager(tempdir / "perm.sqlite3")
|
||||||
|
yield db
|
||||||
|
await db.close_all_connections()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_get_db_version():
|
||||||
|
async with tempdb() as db:
|
||||||
|
async with db.get_conn() as conn:
|
||||||
|
v = await get_current_version(conn)
|
||||||
|
assert v == -1
|
||||||
|
v = await get_current_version(conn)
|
||||||
|
assert v == 0
|
||||||
|
await execute_migration(conn, version=1)
|
||||||
|
v = await get_current_version(conn)
|
||||||
|
assert v == 1
|
||||||
|
await execute_migration(conn, version=0)
|
||||||
|
v = await get_current_version(conn)
|
||||||
|
assert v == 0
|
||||||
Reference in New Issue
Block a user