import psycopg as pg from psycopg.rows import dict_row from .connection import g_conn_dict as conn # no undo/redo _project_open_count: dict[str, int] = {} _server_databases = ['template0', 'template1', 'postgres', 'project'] def list_project() -> list[str]: ps = [] with pg.connect(conninfo="dbname=postgres host=127.0.0.1", autocommit=True) as conn: with conn.cursor(row_factory=dict_row) as cur: for p in cur.execute(f"select datname from pg_database where datname <> 'postgres' and datname <> 'template0' and datname <> 'template1' and datname <> 'project'"): ps.append(p['datname']) return ps def have_project(name: str) -> bool: with pg.connect(conninfo="dbname=postgres host=127.0.0.1", autocommit=True) as conn: with conn.cursor() as cur: cur.execute(f"select * from pg_database where datname = '{name}'") return cur.rowcount > 0 def copy_project(source: str, new: str) -> None: with pg.connect(conninfo="dbname=postgres host=127.0.0.1", autocommit=True) as conn: with conn.cursor() as cur: cur.execute(f"create database {new} with template = {source}") def create_project(name: str) -> None: return copy_project('project', name) def delete_project(name: str) -> None: with pg.connect(conninfo="dbname=postgres host=127.0.0.1", autocommit=True) as conn: with conn.cursor() as cur: cur.execute(f"drop database {name}") def clean_project(excluded: list[str] = []) -> None: projects = list_project() with pg.connect(conninfo="dbname=postgres host=127.0.0.1", autocommit=True) as conn: with conn.cursor(row_factory=dict_row) as cur: row = cur.execute(f"select current_database()").fetchone() if row != None: current_db = row['current_database'] if current_db in projects: projects.remove(current_db) for project in projects: if project in _server_databases or project in excluded: continue cur.execute(f"select pg_terminate_backend(pid) from pg_stat_activity where datname = '{project}'") cur.execute(f"drop database {project}") def open_project(name: str) -> None: if name not in _project_open_count: conn[name] = pg.connect(conninfo=f"dbname={name} host=127.0.0.1", autocommit=True) _project_open_count[name] = 0 _project_open_count[name] += 1 def is_project_open(name: str) -> bool: return name in conn def get_project_open_count(name: str) -> int: if is_project_open(name): return _project_open_count[name] return 0 def close_project(name: str) -> None: if name in _project_open_count: _project_open_count[name] -= 1 if _project_open_count[name] == 0: conn[name].close() del conn[name] del _project_open_count[name]