userver: en/testsuite/databases/pgsql/testsuite_db.py Source File
Loading...
Searching...
No Matches
testsuite_db.py
1from testsuite import utils
2
3from . import connection, pool
4
5CREATE_DATABASE_TEMPLATE = """
6CREATE DATABASE "{}" WITH TEMPLATE = template0
7ENCODING='UTF8' LC_COLLATE='C' LC_CTYPE='C'
8"""
9
10DATABASE_EXISTS_TEMPLATE = 'SELECT 1 FROM pg_database WHERE datname=%s'
11
12CREATE_TABLE_SQL = """
13CREATE TABLE IF NOT EXISTS applied_schemas (
14 db_name TEXT PRIMARY KEY,
15 schema_hash TEXT
16);
17"""
18
19UPDATE_DB_HASH_TEMPLATE = """
20INSERT INTO applied_schemas (db_name, schema_hash)
21VALUES (%(dbname)s, %(hash)s)
22ON CONFLICT (db_name) DO UPDATE SET
23 schema_hash = %(hash)s
24WHERE applied_schemas.db_name = %(dbname)s
25"""
26SELECT_DB_HASH_TEMPLATE = 'SELECT db_name, schema_hash FROM applied_schemas'
27TESTSUITE_DB_NAME = 'testsuite'
28
29
31 def __init__(
32 self,
33 pool: pool.AutocommitConnectionPool,
34 base_conninfo: connection.PgConnectionInfo,
35 ):
36 self._pool = pool
37 self._conninfo = base_conninfo.replace(dbname=TESTSUITE_DB_NAME)
38
39 self._create_db()
41
42 def get_hash(self, dbname: str) -> str | None:
43 """Get hash of schema applied to a database"""
44 return self._hash_by_dbname.get(dbname, None)
45
46 def set_hash(self, dbname: str, schema_hash: str):
47 """Store in testsuite database and remember locally a hash of schema
48 applied to a database
49 """
50 self._hash_by_dbname[dbname] = schema_hash
51
52 with self._pool.get_connection() as conn:
53 with conn.cursor() as cursor:
54 cursor.execute(
55 UPDATE_DB_HASH_TEMPLATE,
56 {'dbname': dbname, 'hash': schema_hash},
57 )
58
59 @utils.cached_property
60 def _hash_by_dbname(self) -> dict[str, str]:
61 with self._pool.get_connection() as conn:
62 with conn.cursor() as cursor:
63 cursor.execute(SELECT_DB_HASH_TEMPLATE)
64 return {entry[0]: entry[1] for entry in cursor}
65
66 def _create_schema_table(self) -> None:
67 with self._pool.get_connection() as conn:
68 with conn.cursor() as cursor:
69 cursor.execute(CREATE_TABLE_SQL)
70
71 def _create_db(self) -> None:
72 with self._pool.get_connection() as conn:
73 with conn.cursor() as cursor:
74 cursor.execute(DATABASE_EXISTS_TEMPLATE, (TESTSUITE_DB_NAME,))
75 db_exists = any(cursor)
76 if db_exists:
77 return
78 cursor.execute(
79 CREATE_DATABASE_TEMPLATE.format(TESTSUITE_DB_NAME)
80 )