Skip to content

Commit

Permalink
Add Pgsql backend
Browse files Browse the repository at this point in the history
Co-authored-by: Kim Lidström <dxtr@users.noreply.github.com>
  • Loading branch information
leso-kn and dxtr committed Jul 17, 2023
1 parent aa7e340 commit 9654b3c
Show file tree
Hide file tree
Showing 7 changed files with 380 additions and 7 deletions.
4 changes: 2 additions & 2 deletions Core/Frameworks/Baikal/Model/Calendar.php
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ function isDefault() {

function hasInstances() {
$rSql = $GLOBALS["DB"]->exec_SELECTquery(
"count(*)",
"count(*) as count",
"calendarinstances",
"calendarid" . "='" . $this->aData["calendarid"] . "'"
);
Expand All @@ -252,7 +252,7 @@ function hasInstances() {
} else {
reset($aRs);

return $aRs["count(*)"] > 1;
return $aRs["count"] > 1;
}
}

Expand Down
4 changes: 2 additions & 2 deletions Core/Frameworks/Baikal/Model/Calendar/Calendar.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class Calendar extends \Flake\Core\Model\Db {

function hasInstances() {
$rSql = $GLOBALS["DB"]->exec_SELECTquery(
"count(*)",
"count(*) as count",
"calendarinstances",
"calendarid" . "='" . $this->aData["id"] . "'"
);
Expand All @@ -48,7 +48,7 @@ function hasInstances() {
} else {
reset($aRs);

return $aRs["count(*)"] > 1;
return $aRs["count"] > 1;
}
}

Expand Down
33 changes: 33 additions & 0 deletions Core/Frameworks/Baikal/Model/Config/Database.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ class Database extends \Baikal\Model\Config {
"mysql_username" => "",
"mysql_password" => "",
"encryption_key" => "",
"pgsql" => false,
"pgsql_host" => "",
"pgsql_dbname" => "",
"pgsql_username" => "",
"pgsql_password" => "",
];

function __construct() {
Expand Down Expand Up @@ -82,6 +87,34 @@ function formMorphologyForThisModelInstance() {
"label" => "MySQL password",
]));

$oMorpho->add(new \Formal\Element\Checkbox(array(
"prop" => "pgsql",
"label" => "Use PostgreSQL",
"help" => "If checked, Baïkal will use PostgreSQL",
"refreshonchange" => true,
)));

$oMorpho->add(new \Formal\Element\Text(array(
"prop" => "pgsql_host",
"label" => "PostgreSQL host",
"help" => "Host ip or name, including <strong>':portnumber'</strong> if port is not the default one (?)"
)));

$oMorpho->add(new \Formal\Element\Text(array(
"prop" => "pgsql_dbname",
"label" => "PostgreSQL database name",
)));

$oMorpho->add(new \Formal\Element\Text(array(
"prop" => "pgsql_username",
"label" => "PostgreSQL username",
)));

$oMorpho->add(new \Formal\Element\Password(array(
"prop" => "pgsql_password",
"label" => "PostgreSQL password",
)));

return $oMorpho;
}

Expand Down
104 changes: 101 additions & 3 deletions Core/Frameworks/BaikalAdmin/Controller/Install/Database.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ function execute() {

$this->oForm = $this->oModel->formForThisModelInstance([
"close" => false,
"hook.validation" => [$this, "validateConnection"],
"hook.morphology" => [$this, "hideMySQLFieldWhenNeeded"],
"hook.validation" => [$this, "validateSQLConnection"],
"hook.morphology" => [$this, "hideSQLFieldWhenNeeded"],
]);

if ($this->oForm->submitted()) {
Expand Down Expand Up @@ -99,7 +99,7 @@ function render() {
return $oView->render();
}

function validateConnection($oForm, $oMorpho) {
function validateMySQLConnection($oForm, $oMorpho) {
if ($oForm->refreshed()) {
return true;
}
Expand Down Expand Up @@ -226,4 +226,102 @@ function hideMySQLFieldWhenNeeded(\Formal\Form $oForm, \Formal\Form\Morphology $
$oMorpho->remove("mysql_password");
}
}

function validatePgSQLConnection($oForm, $oMorpho) {
$bPgSqlEnabled = $oMorpho->element("pgsql")->value();

if ($bPgSqlEnabled) {
$sHost = $oMorpho->element("pgsql_host")->value();
$sDbname = $oMorpho->element("pgsql_dbname")->value();
$sUsername = $oMorpho->element("pgsql_username")->value();
$sPassword = $oMorpho->element("pgsql_password")->value();

try {
$oDb = new \Flake\Core\Database\Pgsql(
$sHost,
$sDbname,
$sUsername,
$sPassword
);

if(($aMissingTables = \Baikal\Core\Tools::isDBStructurallyComplete($oDb)) !== true) {

# Checking if all tables are missing
$aRequiredTables = \Baikal\Core\Tools::getRequiredTablesList();
if(count($aRequiredTables) !== count($aMissingTables)) {
$sMessage = "<br /><p><strong>Database is not structurally complete.</strong></p>";
$sMessage .= "<p>Missing tables are: <strong>" . implode("</strong>, <strong>", $aMissingTables) . "</strong></p>";
$sMessage .= "<p>You will find the SQL definition of Baïkal tables in this file: <strong>Core/Resources/Db/PgSQL/db.sql</strong></p>";
$sMessage .= "<br /><p>Nothing has been saved. <strong>Please, add these tables to the database before pursuing Baïkal initialization.</strong></p>";

$oForm->declareError(
$oMorpho->element("pgsql"),
$sMessage
);
} else {
# All tables are missing
# We add these tables ourselves to the database, to initialize Baïkal
$sSqlDefinition = file_get_contents(PROJECT_PATH_CORERESOURCES . "Db/PgSQL/db.sql");
$oDb->getPDO()->exec($sSqlDefinition);
}
}
return TRUE;
} catch (\Exception $e) {
$oForm->declareError(
$oMorpho->element("pgsql"),
"Baïkal was not able to establish a connexion to the PostgreSQL database as configured.<br />PostgreSQL says: " . $e->getMessage()
);

$oForm->declareError(
$oMorpho->element("pgsql_host")
);

$oForm->declareError(
$oMorpho->element("pgsql_dbname")
);

$oForm->declareError(
$oMorpho->element("pgsql_username")
);

$oForm->declareError(
$oMorpho->element("pgsql_password")
);
}
}
}

public function validateSQLConnection($oForm, $oMorpho) {
if ($oMorpho->element("mysql")->value()) {
$this->validateMySQLConnection($oForm, $oMorpho);
} else if ($oMorpho->element("pgsql")->value()) {
$this->validatePgSQLConnection($oForm, $oMorpho);
}
}

public function hideSqlFieldWhenNeeded(\Formal\Form $oForm, \Formal\Form\Morphology $oMorpho) {
if ($oMorpho->element("mysql")->value()) {
$this->hideMySQLFieldWhenNeeded($oForm, $oMorpho);
} else if ($oMorpho->element("pgsql")->value()) {
$this->hidePgSQLFieldWhenNeeded($oForm, $oMorpho);
}
}

public function hidePgSQLFieldWhenNeeded(\Formal\Form $oForm, \Formal\Form\Morphology $oMorpho) {
if($oForm->submitted()) {
$bPgSQL = (intval($oForm->postValue("pgsql")) === 1);
} else {
$bPgSQL = pgsql;
}

if($bPgSQL === true) {
$oMorpho->remove("sqlite_file");
$this->hideMySQLFieldWhenNeeded($oForm, $oMorpho);
} else {
$oMorpho->remove("pgsql_host");
$oMorpho->remove("pgsql_dbname");
$oMorpho->remove("pgsql_username");
$oMorpho->remove("pgsql_password");
}
}
}
67 changes: 67 additions & 0 deletions Core/Frameworks/Flake/Core/Database/Pgsql.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php
#################################################################
# Copyright notice
#
# (c) 2013 Kim Lidström <kim@dxtr.im>
# All rights reserved
#
# http://flake.codr.fr
#
# This script is part of the Flake project. The Flake
# project is free software; you can redistribute it
# and/or modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# The GNU General Public License can be found at
# http://www.gnu.org/copyleft/gpl.html.
#
# This script is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# This copyright notice MUST APPEAR in all copies of the script!
#################################################################

namespace Flake\Core\Database;

class Pgsql extends \Flake\Core\Database {

protected $oDb = FALSE; // current DB link
protected $debugOutput = FALSE;
protected $store_lastBuiltQuery = TRUE;
protected $debug_lastBuiltQuery = "";
protected $sHost = "";
protected $sDbName = "";
protected $sUsername = "";
protected $sPassword = "";

public function __construct($sHost, $sDbName, $sUsername, $sPassword) {
$this->sHost = $sHost;
$this->sDbName = $sDbName;
$this->sUsername = $sUsername;
$this->sPassword = $sPassword;

$this->oDb = new \PDO(
'pgsql:host=' . $this->sHost . ';dbname=' . $this->sDbName,
$this->sUsername,
$this->sPassword
);
}

public function tables() {
$aTables = array();

$sSql = "SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname = 'public'";
$oStmt = $this->query($sSql);

while(($aRs = $oStmt->fetch()) !== FALSE) {
$aTables[] = array_shift($aRs);
}

asort($aTables);
reset($aTables);
return $aTables;
}
}
33 changes: 33 additions & 0 deletions Core/Frameworks/Flake/Framework.php
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,8 @@ protected static function initDb() {
}
if ($config['database']['mysql'] === true) {
self::initDbMysql($config);
} elseif ($config['database']['pgsql'] === true) {
self::initDbPgsql($config);
} else {
self::initDbSqlite($config);
}
Expand Down Expand Up @@ -325,6 +327,37 @@ protected static function initDbMysql(array $config) {
return true;
}

protected static function initDbPgsql(array $config) {
if (!$config['database']['pgsql_host']) {
die("<h3>The constant PROJECT_DB_PGSQL_HOST, containing the PostgreSQL host name, is not set.<br />You should set it in config/baikal.yaml</h3>");
}

if (!$config['database']['pgsql_dbname']) {
die("<h3>The constant PROJECT_DB_PGSQL_DBNAME, containing the PostgreSQL database name, is not set.<br />You should set it in config/baikal.yaml</h3>");
}

if (!$config['database']['pgsql_username']) {
die("<h3>The constant PROJECT_DB_PGSQL_USERNAME, containing the PostgreSQL database username, is not set.<br />You should set it in config/baikal.yaml</h3>");
}

if ($config['database']['pgsql_password'] === null) {
die("<h3>The constant PROJECT_DB_PGSQL_PASSWORD, containing the PostgreSQL database password, is not set.<br />You should set it in config/baikal.yaml</h3>");
}

try {
$GLOBALS["DB"] = new \Flake\Core\Database\Pgsql(
$config['database']['pgsql_host'],
$config['database']['pgsql_dbname'],
$config['database']['pgsql_username'],
$config['database']['pgsql_password']
);

$GLOBALS["DB"]->query("SET NAMES 'UTF8'");
} catch(\Exception $e) {
die("<h3>Baïkal was not able to establish a connection to the configured PostgreSQL database (as configured in config/baikal.yaml).</h3>");
}
}

static function isDBInitialized() {
return isset($GLOBALS["DB"]) && \Flake\Util\Tools::is_a($GLOBALS["DB"], "\Flake\Core\Database");
}
Expand Down
Loading

0 comments on commit 9654b3c

Please sign in to comment.