git-importer/lib/db.py

234 lines
7.7 KiB
Python
Raw Normal View History

import logging
2022-10-17 16:31:48 +02:00
import psycopg2
from psycopg2.extras import LoggingConnection
2022-10-17 20:39:03 +02:00
from lib.config import config
2022-10-17 16:31:48 +02:00
class DB:
2022-10-17 20:52:05 +02:00
def __init__(self, section="production"):
self.config_section = section
2022-10-17 16:31:48 +02:00
self.connect()
2022-10-17 20:39:03 +02:00
self.create_tables()
2022-10-17 16:31:48 +02:00
def connect(self):
try:
# read the connection parameters
2022-10-17 20:52:05 +02:00
params = config(section=self.config_section)
2022-10-17 16:31:48 +02:00
# connect to the PostgreSQL server
self.conn = psycopg2.connect(connection_factory=LoggingConnection, **params)
logger = logging.getLogger(__name__)
self.conn.initialize(logger)
2022-10-17 16:31:48 +02:00
except (Exception, psycopg2.DatabaseError) as error:
print(error)
raise error
def schema_version(self):
# create a cursor
2022-10-26 11:58:01 +02:00
with self.conn.cursor() as cur:
2022-10-17 16:31:48 +02:00
2022-10-26 11:58:01 +02:00
# execute a statement
try:
cur.execute("SELECT MAX(version) from scheme")
except psycopg2.errors.UndefinedTable as error:
cur.close()
self.close()
self.connect()
return 0
2022-10-17 16:31:48 +02:00
2022-10-26 11:58:01 +02:00
db_version = cur.fetchone()
2022-10-17 16:31:48 +02:00
return db_version[0]
def close(self):
if self.conn is not None:
self.conn.close()
self.conn = None
def create_tables(self):
"""Create the tables if not existing - assumes connected"""
schemes = dict()
schemes[1] = (
2022-10-17 16:31:48 +02:00
"""
CREATE TABLE scheme (
id SERIAL PRIMARY KEY,
version SMALLINT NOT NULL
2022-10-18 12:17:43 +02:00
)
""",
2022-10-17 16:31:48 +02:00
"INSERT INTO scheme (version) VALUES(1)",
"""DROP TABLE IF EXISTS revisions """,
2022-10-17 16:31:48 +02:00
""" CREATE TABLE revisions (
id SERIAL PRIMARY KEY,
project VARCHAR(255) NOT NULL,
package VARCHAR(255) NOT NULL,
2022-10-18 12:17:43 +02:00
rev INTEGER NOT NULL,
unexpanded_srcmd5 VARCHAR(255) NOT NULL,
commit_time timestamp NOT NULL,
userid VARCHAR(255) NOT NULL,
2022-10-17 20:39:03 +02:00
comment TEXT,
requestid INTEGER
2022-10-17 16:31:48 +02:00
)
2022-10-18 12:17:43 +02:00
""",
"""
CREATE UNIQUE INDEX ppr ON revisions (project, package, rev);
2022-10-18 13:13:52 +02:00
""",
2022-10-17 16:31:48 +02:00
)
schemes[2] = (
"""DROP TABLE IF EXISTS links""",
"""
CREATE TABLE links (
id SERIAL PRIMARY KEY,
2022-10-18 19:29:25 +02:00
revision_id INTEGER NOT NULL,
project VARCHAR(255) NOT NULL,
package VARCHAR(255) NOT NULL
)
""",
2022-10-18 19:29:25 +02:00
"UPDATE scheme SET version=2",
)
schemes[3] = (
"""
ALTER TABLE revisions ADD broken boolean NOT NULL DEFAULT(FALSE)
""",
"UPDATE scheme SET version=3",
)
schemes[4] = (
"""
2022-10-18 19:29:25 +02:00
ALTER TABLE revisions ADD expanded_srcmd5 VARCHAR(255)
""",
"UPDATE scheme SET version=4",
)
schemes[5] = (
"""DROP TABLE IF EXISTS files""",
2022-10-18 19:29:25 +02:00
"""
CREATE TABLE files (
id SERIAL PRIMARY KEY,
revision_id INTEGER NOT NULL,
name VARCHAR(255) NOT NULL,
md5 VARCHAR(255) NOT NULL,
size INTEGER NOT NULL,
mtime INTEGER NOT NULL
)
""",
2022-10-18 19:29:25 +02:00
"UPDATE scheme SET version=5",
)
schemes[6] = (
"""DROP TABLE IF EXISTS requests""",
"""
CREATE TABLE requests (
id SERIAL PRIMARY KEY,
number INTEGER NOT NULL,
revision_id INTEGER NOT NULL,
creator VARCHAR(255) NOT NULL,
type VARCHAR(10) NOT NULL,
state VARCHAR(10) NOT NULL,
source_package VARCHAR(255),
source_project VARCHAR(255)
)
""",
"UPDATE scheme SET version=6",
)
schemes[7] = (
"ALTER TABLE requests DROP COLUMN revision_id",
"UPDATE scheme SET version=7",
)
schemes[8] = (
"ALTER TABLE requests ADD COLUMN source_rev VARCHAR(40)",
"UPDATE scheme SET version=8",
)
schemes[9] = (
"ALTER TABLE revisions ADD COLUMN request_number INTEGER",
"UPDATE revisions SET request_number=requestid",
"ALTER TABLE revisions DROP COLUMN requestid",
"UPDATE scheme SET version=9",
)
schemes[10] = (
"ALTER TABLE revisions ADD COLUMN request_id INTEGER",
"""ALTER TABLE revisions
ADD CONSTRAINT request_id_foreign_key
FOREIGN KEY (request_id)
REFERENCES requests (id)""",
"UPDATE scheme SET version=10",
)
2022-10-20 07:00:26 +02:00
schemes[11] = (
"create index request_number_idx on revisions (request_number)",
2022-10-20 07:00:26 +02:00
"UPDATE scheme SET version=11",
)
schemes[12] = (
"create index request_number_idx2 on requests(number)",
"UPDATE scheme SET version=12",
)
2022-10-21 15:16:34 +02:00
schemes[13] = (
"""DROP TABLE IF EXISTS linked_revs""",
2022-10-21 15:16:34 +02:00
"""
CREATE TABLE users (
id SERIAL PRIMARY KEY,
userid VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL,
realname VARCHAR(255) NOT NULL
)
""",
"UPDATE scheme SET version=13",
),
schemes[14] = (
"""
CREATE TABLE linked_revs (
id SERIAL PRIMARY KEY,
revision_id INTEGER NOT NULL,
linked_id INTEGER NOT NULL
)
""",
"UPDATE scheme SET version=14",
2022-10-21 15:16:34 +02:00
)
schemes[14] = (
"ALTER TABLE revisions ALTER COLUMN rev TYPE real USING rev::real",
"UPDATE scheme SET version=14",
)
schemes[15] = (
"""DROP TABLE IF EXISTS fake_revs""",
"""
CREATE TABLE fake_revs (
id SERIAL PRIMARY KEY,
revision_id INTEGER NOT NULL,
linked_id INTEGER NOT NULL
)
""",
"create index revs_linked on fake_revs (revision_id,linked_id)",
"UPDATE scheme SET version=15",
)
schemes[16] = (
"ALTER TABLE revisions ADD COLUMN files_hash VARCHAR(40)",
"UPDATE scheme SET version=16",
)
schemes[17] = (
"ALTER TABLE linked_revs ADD COLUMN considered BOOLEAN DEFAULT FALSE",
"UPDATE scheme SET version=17",
)
schema_version = self.schema_version()
if (schema_version + 1) not in schemes:
2022-10-17 16:31:48 +02:00
return
try:
2022-10-26 11:58:01 +02:00
with self.conn.cursor() as cur:
# create table one by one
for version, commands in schemes.items():
if version <= schema_version:
continue
for command in commands:
cur.execute(command)
2022-10-17 16:31:48 +02:00
# commit the changes
self.conn.commit()
except (Exception, psycopg2.DatabaseError) as error:
print(error)
self.close()
raise error
2022-10-18 12:17:43 +02:00
def cursor(self):
return self.conn.cursor()
2022-10-17 16:31:48 +02:00
if __name__ == "__main__":
db = DB()
db.create_tables()