f3 = $f3; $db = $this->getDbConnection(\Utils\Variables::getDB()); $this->f3->set('API_DATABASE', $db); $this->db = $db; \DB\SQL\Mapper::__construct($db, $this->DB_TABLE_NAME, $this->DB_TABLE_FIELDS, $this->DB_TABLE_TTL); $this->db = $db; $this->createIfNotExists(); } private function getDbConnection(string $url): ?\DB\SQL { $urlComponents = parse_url($url); $host = $urlComponents['host']; $port = $urlComponents['port']; $user = $urlComponents['user']; $pass = $urlComponents['pass']; $db = ltrim($urlComponents['path'], '/'); $dsn = sprintf('pgsql:host=%s;port=%s;dbname=%s', $host, $port, $db); $options = [ \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, ]; try { return new \DB\SQL($dsn, $user, $pass, $options); } catch (\Exception $e) { throw new \Exception('Failed to establish database connection: ' . $e->getMessage()); } } public function checkDb(string $service, array $updatesList) { try { $this->db->begin(); foreach ($updatesList as $migration) { if (!$migration::isApplied($this)) { $migration::apply($this->db); $this->add($migration::$version, $service); } } $this->db->commit(); } catch (\Exception $e) { $this->db->rollback(); error_log($e->getMessage()); throw $e; } } public function isApplied(string $version, string $name): bool { $params = [ ':version' => $version, ':service' => $name, ]; $query = 'SELECT 1 FROM dshb_updates WHERE version = :version and service = :service LIMIT 1'; $results = $this->execQuery($query, $params); return (bool) count($results); } public function add(string $version, string $name): void { $params = [ ':version' => $version, ':service' => $name, ]; $query = 'INSERT INTO dshb_updates (service, version) VALUES (:service, :version)'; $this->execQuery($query, $params); } private function createIfNotExists(): void { $query = 'SELECT 1 FROM information_schema.tables WHERE table_name = \'dshb_updates\''; if (count($this->execQuery($query, null))) { return; } $queries = [ ('CREATE SEQUENCE IF NOT EXISTS dshb_updates_id_seq AS BIGINT START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1'), ('CREATE TABLE IF NOT EXISTS dshb_updates ( id bigint NOT NULL DEFAULT nextval(\'dshb_updates_id_seq\'::regclass), service varchar(30), version varchar(30), created timestamp without time zone DEFAULT now() NOT NULL )'), 'ALTER SEQUENCE dshb_updates_id_seq OWNED BY dshb_updates.id', 'ALTER TABLE ONLY dshb_updates ADD CONSTRAINT dshb_updates_service_version_key UNIQUE (service, version)', 'ALTER TABLE ONLY dshb_updates ADD CONSTRAINT dshb_updates_id_pkey PRIMARY KEY (id)', ]; foreach ($queries as $query) { $this->execQuery($query, null); } } }