PostgreSQL INSERT+CREATE TABLE
This commit is contained in:
parent
81995b06b8
commit
c4e9f0fffb
@ -22,6 +22,7 @@ class CreateApiKey extends Request {
|
|||||||
|
|
||||||
$this->success = $sql->insert("ApiKey", array("user_id", "api_key", "valid_until"))
|
$this->success = $sql->insert("ApiKey", array("user_id", "api_key", "valid_until"))
|
||||||
->addRow($this->user->getId(), $apiKey, $validUntil)
|
->addRow($this->user->getId(), $apiKey, $validUntil)
|
||||||
|
->returning("uid")
|
||||||
->execute();
|
->execute();
|
||||||
|
|
||||||
$this->lastError = $sql->getLastError();
|
$this->lastError = $sql->getLastError();
|
||||||
|
@ -25,8 +25,7 @@ class CreateDatabase {
|
|||||||
|
|
||||||
$queries[] = $sql->insert("Language", array("uid", "code", "name"))
|
$queries[] = $sql->insert("Language", array("uid", "code", "name"))
|
||||||
->addRow(1, "en_US", 'American English')
|
->addRow(1, "en_US", 'American English')
|
||||||
->addRow(2, "de_DE", 'Deutsch Standard')
|
->addRow(2, "de_DE", 'Deutsch Standard');
|
||||||
->onDuplicateKeyStrategy(new UpdateStrategy(array("name" => new Column("name"))));
|
|
||||||
|
|
||||||
$queries[] = $sql->createTable("User")
|
$queries[] = $sql->createTable("User")
|
||||||
->addSerial("uid")
|
->addSerial("uid")
|
||||||
@ -56,7 +55,7 @@ class CreateDatabase {
|
|||||||
$queries[] = $sql->createTable("UserToken")
|
$queries[] = $sql->createTable("UserToken")
|
||||||
->addInt("user_id")
|
->addInt("user_id")
|
||||||
->addString("token", 36)
|
->addString("token", 36)
|
||||||
->addEnum("type", array("password_reset", "confirmation"))
|
->addEnum("token_type", array("password_reset", "confirmation"))
|
||||||
->addDateTime("valid_until")
|
->addDateTime("valid_until")
|
||||||
->foreignKey("user_id", "User", "uid", new CascadeStrategy());
|
->foreignKey("user_id", "User", "uid", new CascadeStrategy());
|
||||||
|
|
||||||
@ -68,8 +67,7 @@ class CreateDatabase {
|
|||||||
|
|
||||||
$queries[] = $sql->insert("Group", array("uid", "name"))
|
$queries[] = $sql->insert("Group", array("uid", "name"))
|
||||||
->addRow(1, "Default")
|
->addRow(1, "Default")
|
||||||
->addRow(2, "Administrator")
|
->addRow(2, "Administrator");
|
||||||
->onDuplicateKeyStrategy(new UpdateStrategy(array("name" => new Column("name"))));
|
|
||||||
|
|
||||||
$queries[] = $sql->createTable("UserGroup")
|
$queries[] = $sql->createTable("UserGroup")
|
||||||
->addInt("user_id")
|
->addInt("user_id")
|
||||||
|
@ -139,12 +139,6 @@ namespace Documents\Install {
|
|||||||
$success = false;
|
$success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!function_exists('mysqli_connect')) {
|
|
||||||
$link = $this->createExternalLink("https://secure.php.net/manual/en/mysqli.setup.php");
|
|
||||||
$failedRequirements[] = "mysqli is not enabled yet. See: $link";
|
|
||||||
$success = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!$success) {
|
if(!$success) {
|
||||||
$msg = "The following requirements failed the check:<br>" .
|
$msg = "The following requirements failed the check:<br>" .
|
||||||
$this->createUnorderedList($failedRequirements);
|
$this->createUnorderedList($failedRequirements);
|
||||||
@ -196,7 +190,7 @@ namespace Documents\Install {
|
|||||||
$missingInputs[] = "Type";
|
$missingInputs[] = "Type";
|
||||||
}
|
}
|
||||||
|
|
||||||
$supportedTypes = array("mysql"); # , "oracle", "postgres");
|
$supportedTypes = array("mysql", "postgres"); # , "oracle", "postgres");
|
||||||
if(!$success) {
|
if(!$success) {
|
||||||
$msg = "Please fill out the following inputs:<br>" .
|
$msg = "Please fill out the following inputs:<br>" .
|
||||||
$this->createUnorderedList($missingInputs);
|
$this->createUnorderedList($missingInputs);
|
||||||
@ -216,14 +210,21 @@ namespace Documents\Install {
|
|||||||
if(!($sql instanceof \Driver\SQL\SQL)) {
|
if(!($sql instanceof \Driver\SQL\SQL)) {
|
||||||
$msg = "Error connecting to database: " . str($sql);
|
$msg = "Error connecting to database: " . str($sql);
|
||||||
} else if(!$sql->isConnected()) {
|
} else if(!$sql->isConnected()) {
|
||||||
$msg = "Error connecting to database:<br>" . $sql->getLastError();
|
if (!$sql->checkRequirements()) {
|
||||||
|
$driverName = $sql->getDriverName();
|
||||||
|
$installLink = "https://www.php.net/manual/en/$driverName.setup.php";
|
||||||
|
$link = $this->createExternalLink($installLink);
|
||||||
|
$msg = "$driverName is not enabled yet. See: $link";
|
||||||
|
} else {
|
||||||
|
$msg = "Error connecting to database:<br>" . $sql->getLastError();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
$msg = "";
|
$msg = "";
|
||||||
$success = true;
|
$success = true;
|
||||||
$queries = \Configuration\CreateDatabase::createQueries($sql);
|
$queries = \Configuration\CreateDatabase::createQueries($sql);
|
||||||
foreach($queries as $query) {
|
foreach($queries as $query) {
|
||||||
if (!$query->execute()) {
|
if (!($res = $query->execute())) {
|
||||||
$msg = "Error creating tables: " . $sql->getLastError();
|
$msg = "Error creating tables: " . $sql->getLastError();
|
||||||
$success = false;
|
$success = false;
|
||||||
break;
|
break;
|
||||||
|
@ -25,7 +25,16 @@ use \Driver\SQL\Constraint\ForeignKey;
|
|||||||
class MySQL extends SQL {
|
class MySQL extends SQL {
|
||||||
|
|
||||||
public function __construct($connectionData) {
|
public function __construct($connectionData) {
|
||||||
parent::__construct("mysql", $connectionData);
|
parent::__construct($connectionData);
|
||||||
|
$this->installLink = ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function checkRequirements() {
|
||||||
|
return function_exists('mysqli_connect');
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract function getDriverName() {
|
||||||
|
return 'mysqli';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function connect() {
|
public function connect() {
|
||||||
@ -48,7 +57,7 @@ class MySQL extends SQL {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mysqli_set_charset($this->connection, $this->connectionData->getProperty('encoding'));
|
mysqli_set_charset($this->connection, $this->connectionData->getProperty('encoding', 'UTF-8'));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +67,6 @@ class MySQL extends SQL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mysqli_close($this->connection);
|
mysqli_close($this->connection);
|
||||||
$this->connection = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getLastError() {
|
public function getLastError() {
|
||||||
@ -216,8 +224,7 @@ class MySQL extends SQL {
|
|||||||
$columnName = $value->getName();
|
$columnName = $value->getName();
|
||||||
$updateValues[] = "`$key`=`$columnName`";
|
$updateValues[] = "`$key`=`$columnName`";
|
||||||
} else {
|
} else {
|
||||||
$updateValues[] = "`$key`=?";
|
$updateValues[] = "`$key`=" . $this->addValue($value, $parameters);
|
||||||
$parameters[] = $value;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,33 +326,6 @@ class MySQL extends SQL {
|
|||||||
return $this->execute($query, $params);
|
return $this->execute($query, $params);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildCondition($condition, &$params) {
|
|
||||||
if ($condition instanceof \Driver\SQL\Condition\CondOr) {
|
|
||||||
$conditions = array();
|
|
||||||
foreach($condition->getConditions() as $cond) {
|
|
||||||
$conditions[] = $this->buildCondition($cond, $params);
|
|
||||||
}
|
|
||||||
return "(" . implode(" OR ", $conditions) . ")";
|
|
||||||
} else if ($condition instanceof \Driver\SQL\Condition\Compare) {
|
|
||||||
$column = $condition->getColumn();
|
|
||||||
$value = $condition->getValue();
|
|
||||||
$operator = $condition->getOperator();
|
|
||||||
return $column . $operator . $this->addValue($value, $params);
|
|
||||||
} else if ($condition instanceof \Driver\SQL\Condition\CondBool) {
|
|
||||||
return $condition->getValue();
|
|
||||||
} else if (is_array($condition)) {
|
|
||||||
if (count($condition) == 1) {
|
|
||||||
return $this->buildCondition($condition[0], $params);
|
|
||||||
} else {
|
|
||||||
$conditions = array();
|
|
||||||
foreach($condition as $cond) {
|
|
||||||
$conditions[] = $this->buildCondition($cond, $params);
|
|
||||||
}
|
|
||||||
return implode(" AND ", $conditions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getColumnDefinition($column) {
|
public function getColumnDefinition($column) {
|
||||||
$columnName = $column->getName();
|
$columnName = $column->getName();
|
||||||
|
|
||||||
@ -380,7 +360,11 @@ class MySQL extends SQL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$notNull = $column->notNull() ? " NOT NULL" : "";
|
$notNull = $column->notNull() ? " NOT NULL" : "";
|
||||||
$defaultValue = (!is_null($column->getDefaultValue()) || !$column->notNull()) ? " DEFAULT " . $this->getValueDefinition($column->getDefaultValue()) : "";
|
$defaultValue = "";
|
||||||
|
if (!is_null($column->getDefaultValue()) || !$column->notNull()) {
|
||||||
|
$defaultValue = " DEFAULT " . $this->getValueDefinition($column->getDefaultValue());
|
||||||
|
}
|
||||||
|
|
||||||
return "`$columnName` $type$notNull$defaultValue";
|
return "`$columnName` $type$notNull$defaultValue";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -410,7 +394,6 @@ class MySQL extends SQL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check this please..
|
// TODO: check this please..
|
||||||
// TODO: Constants??
|
|
||||||
public function getValueDefinition($value) {
|
public function getValueDefinition($value) {
|
||||||
if (is_numeric($value) || is_bool($value)) {
|
if (is_numeric($value) || is_bool($value)) {
|
||||||
return $value;
|
return $value;
|
||||||
@ -424,6 +407,15 @@ class MySQL extends SQL {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function addValue($val, &$params) {
|
||||||
|
if ($val instanceof Keyword) {
|
||||||
|
return $val->getValue();
|
||||||
|
} else {
|
||||||
|
$params[] = $val;
|
||||||
|
return "?";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function currentTimestamp() {
|
public function currentTimestamp() {
|
||||||
return "NOW()";
|
return "NOW()";
|
||||||
}
|
}
|
||||||
|
352
core/Driver/SQL/PostgreSQL.class.php
Normal file
352
core/Driver/SQL/PostgreSQL.class.php
Normal file
@ -0,0 +1,352 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Driver\SQL;
|
||||||
|
|
||||||
|
use \Api\Parameter\Parameter;
|
||||||
|
|
||||||
|
use \Driver\SQL\Column\Column;
|
||||||
|
use \Driver\SQL\Column\IntColumn;
|
||||||
|
use \Driver\SQL\Column\SerialColumn;
|
||||||
|
use \Driver\SQL\Column\StringColumn;
|
||||||
|
use \Driver\SQL\Column\EnumColumn;
|
||||||
|
use \Driver\SQL\Column\DateTimeColumn;
|
||||||
|
use Driver\SQL\Column\BoolColumn;
|
||||||
|
use Driver\SQL\Column\JsonColumn;
|
||||||
|
|
||||||
|
use \Driver\SQL\Strategy\CascadeStrategy;
|
||||||
|
use \Driver\SQL\Strategy\SetDefaultStrategy;
|
||||||
|
use \Driver\SQL\Strategy\SetNullStrategy;
|
||||||
|
use \Driver\SQL\Strategy\UpdateStrategy;
|
||||||
|
|
||||||
|
use \Driver\SQL\Constraint\Unique;
|
||||||
|
use \Driver\SQL\Constraint\PrimaryKey;
|
||||||
|
use \Driver\SQL\Constraint\ForeignKey;
|
||||||
|
|
||||||
|
class PostgreSQL extends SQL {
|
||||||
|
|
||||||
|
public function __construct($connectionData) {
|
||||||
|
parent::__construct($connectionData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function checkRequirements() {
|
||||||
|
return function_exists('pg_connect');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDriverName() {
|
||||||
|
return 'pgsql';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLastError() {
|
||||||
|
$lastError = parent::getLastError();
|
||||||
|
if (empty($lastError)) {
|
||||||
|
$lastError = pg_last_error($this->connection) . " " . pg_last_error($this->connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $lastError;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connection Managment
|
||||||
|
public function connect() {
|
||||||
|
if(!is_null($this->connection)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$config = array(
|
||||||
|
"host" => $this->connectionData->getHost(),
|
||||||
|
"port" => $this->connectionData->getPort(),
|
||||||
|
"dbname" => $this->connectionData->getProperty('database', 'public'),
|
||||||
|
"user" => $this->connectionData->getLogin(),
|
||||||
|
"password" => $this->connectionData->getPassword()
|
||||||
|
);
|
||||||
|
|
||||||
|
$connectionString = array();
|
||||||
|
foreach($config as $key => $val) {
|
||||||
|
if (!empty($val)) {
|
||||||
|
$connectionString[] = "$key=$val";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->connection = @pg_connect(implode(" ", $connectionString));
|
||||||
|
if (!$this->connection) {
|
||||||
|
$this->lastError = "Failed to connect to Database";
|
||||||
|
$this->connection = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pg_set_client_encoding($this->connection, $this->connectionData->getProperty('encoding', 'UTF-8'));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function disconnect() {
|
||||||
|
if(is_null($this->connection))
|
||||||
|
return;
|
||||||
|
|
||||||
|
pg_close($this->connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute($query, $values = NULL, $returnValues = false) {
|
||||||
|
|
||||||
|
$this->lastError = "";
|
||||||
|
$stmt_name = uniqid();
|
||||||
|
$pgParams = array();
|
||||||
|
|
||||||
|
if (!is_null($values)) {
|
||||||
|
foreach($values as $value) {
|
||||||
|
$paramType = Parameter::parseType($value);
|
||||||
|
switch($paramType) {
|
||||||
|
case Parameter::TYPE_DATE:
|
||||||
|
$value = $value->format("Y-m-d");
|
||||||
|
break;
|
||||||
|
case Parameter::TYPE_TIME:
|
||||||
|
$value = $value->format("H:i:s");
|
||||||
|
break;
|
||||||
|
case Parameter::TYPE_DATE_TIME:
|
||||||
|
$value = $value->format("Y-m-d H:i:s");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pgParams[] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt = @pg_prepare($this->connection, $stmt_name, $query);
|
||||||
|
if ($stmt === FALSE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = @pg_execute($this->connection, $stmt_name, $pgParams);
|
||||||
|
if ($result === FALSE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($returnValues) {
|
||||||
|
$rows = pg_fetch_all($result);
|
||||||
|
if ($rows === FALSE) {
|
||||||
|
if (empty(trim($this->getLastError()))) {
|
||||||
|
$rows = array();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $rows;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Querybuilder
|
||||||
|
public function executeCreateTable($createTable) {
|
||||||
|
$tableName = $createTable->getTableName();
|
||||||
|
$ifNotExists = $createTable->ifNotExists() ? " IF NOT EXISTS": "";
|
||||||
|
|
||||||
|
$entries = array();
|
||||||
|
foreach($createTable->getColumns() as $column) {
|
||||||
|
$entries[] = ($tmp = $this->getColumnDefinition($column));
|
||||||
|
if (is_null($tmp)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($createTable->getConstraints() as $constraint) {
|
||||||
|
$entries[] = ($tmp = $this->getConstraintDefinition($constraint));
|
||||||
|
if (is_null($tmp)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$entries = implode(",", $entries);
|
||||||
|
$query = "CREATE TABLE$ifNotExists \"$tableName\" ($entries)";
|
||||||
|
return $this->execute($query);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function executeInsert($insert) {
|
||||||
|
|
||||||
|
$tableName = $insert->getTableName();
|
||||||
|
$columns = $insert->getColumns();
|
||||||
|
$rows = $insert->getRows();
|
||||||
|
$onDuplicateKey = $insert->onDuplicateKey() ?? "";
|
||||||
|
|
||||||
|
if (empty($rows)) {
|
||||||
|
$this->lastError = "No rows to insert given.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_null($columns) || empty($columns)) {
|
||||||
|
$columns = "";
|
||||||
|
$numColumns = count($rows[0]);
|
||||||
|
} else {
|
||||||
|
$numColumns = count($columns);
|
||||||
|
$columns = " (\"" . implode("\", \"", $columns) . "\")";
|
||||||
|
}
|
||||||
|
|
||||||
|
$numRows = count($rows);
|
||||||
|
$parameters = array();
|
||||||
|
|
||||||
|
$values = array();
|
||||||
|
foreach($rows as $row) {
|
||||||
|
$rowPlaceHolder = array();
|
||||||
|
foreach($row as $val) {
|
||||||
|
$rowPlaceHolder[] = $this->addValue($val, $parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
$values[] = "(" . implode(",", $rowPlaceHolder) . ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
$values = implode(",", $values);
|
||||||
|
|
||||||
|
if ($onDuplicateKey) {
|
||||||
|
if ($onDuplicateKey instanceof UpdateStrategy) {
|
||||||
|
$updateValues = array();
|
||||||
|
foreach($onDuplicateKey->getValues() as $key => $value) {
|
||||||
|
if ($value instanceof Column) {
|
||||||
|
$columnName = $value->getName();
|
||||||
|
$updateValues[] = "\"$key\"=\"$columnName\"";
|
||||||
|
} else {
|
||||||
|
$updateValues[] = "\"$key\"=" . $this->addValue($value, $parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$onDuplicateKey = " ON CONFLICT DO UPDATE SET " . implode(",", $updateValues);
|
||||||
|
} else {
|
||||||
|
$strategy = get_class($onDuplicateKey);
|
||||||
|
$this->lastError = "ON DUPLICATE Strategy $strategy is not supported yet.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$returningCol = $insert->getReturning();
|
||||||
|
$returning = $returningCol ? " RETURNING \"$returningCol\"" : "";
|
||||||
|
|
||||||
|
$query = "INSERT INTO \"$tableName\"$columns VALUES$values$onDuplicateKey$returning";
|
||||||
|
$res = $this->execute($query, $parameters, !empty($returning));
|
||||||
|
$success = ($res !== FALSE);
|
||||||
|
|
||||||
|
if($success && !empty($returning)) {
|
||||||
|
$this->lastInsertId = $res[0][$returningCol];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $success;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
public function executeSelect($query) { }
|
||||||
|
public function executeDelete($query) { }
|
||||||
|
public function executeTruncate($query) { }
|
||||||
|
public function executeUpdate($query) { }
|
||||||
|
|
||||||
|
// UGLY but.. what should i do?
|
||||||
|
private function createEnum($enumColumn) {
|
||||||
|
$typeName = $enumColumn->getName();
|
||||||
|
if(!endsWith($typeName, "_type")) {
|
||||||
|
$typeName = "${typeName}_type";
|
||||||
|
}
|
||||||
|
|
||||||
|
$values = array();
|
||||||
|
foreach($enumColumn->getValues() as $value) {
|
||||||
|
$values[] = $this->getValueDefinition($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
$values = implode(",", $values);
|
||||||
|
$query =
|
||||||
|
"DO $$ BEGIN
|
||||||
|
CREATE TYPE \"$typeName\" AS ENUM ($values);
|
||||||
|
EXCEPTION
|
||||||
|
WHEN duplicate_object THEN null;
|
||||||
|
END $$;";
|
||||||
|
|
||||||
|
$this->execute($query);
|
||||||
|
return $typeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getColumnDefinition($column) {
|
||||||
|
$columnName = $column->getName();
|
||||||
|
|
||||||
|
if ($column instanceof StringColumn) {
|
||||||
|
$maxSize = $column->getMaxSize();
|
||||||
|
if ($maxSize) {
|
||||||
|
$type = "VARCHAR($maxSize)";
|
||||||
|
} else {
|
||||||
|
$type = "TEXT";
|
||||||
|
}
|
||||||
|
} else if($column instanceof SerialColumn) {
|
||||||
|
$type = "SERIAL";
|
||||||
|
} else if($column instanceof IntColumn) {
|
||||||
|
$type = "INTEGER";
|
||||||
|
} else if($column instanceof DateTimeColumn) {
|
||||||
|
$type = "TIMESTAMP";
|
||||||
|
} else if($column instanceof EnumColumn) {
|
||||||
|
$type = $this->createEnum($column);
|
||||||
|
} else if($column instanceof BoolColumn) {
|
||||||
|
$type = "BOOLEAN";
|
||||||
|
} else if($column instanceof JsonColumn) {
|
||||||
|
$type = "JSON";
|
||||||
|
} else {
|
||||||
|
$this->lastError = "Unsupported Column Type: " . get_class($column);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
$notNull = $column->notNull() ? " NOT NULL" : "";
|
||||||
|
$defaultValue = "";
|
||||||
|
if (!is_null($column->getDefaultValue()) || !$column->notNull()) {
|
||||||
|
$defaultValue = " DEFAULT " . $this->getValueDefinition($column->getDefaultValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
return "\"$columnName\" $type$notNull$defaultValue";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getConstraintDefinition($constraint) {
|
||||||
|
$columnName = $constraint->getColumnName();
|
||||||
|
if ($constraint instanceof PrimaryKey) {
|
||||||
|
if (is_array($columnName)) $columnName = implode('","', $columnName);
|
||||||
|
return "PRIMARY KEY (\"$columnName\")";
|
||||||
|
} else if ($constraint instanceof Unique) {
|
||||||
|
if (is_array($columnName)) $columnName = implode('","', $columnName);
|
||||||
|
return "UNIQUE (\"$columnName\")";
|
||||||
|
} else if ($constraint instanceof ForeignKey) {
|
||||||
|
$refTable = $constraint->getReferencedTable();
|
||||||
|
$refColumn = $constraint->getReferencedColumn();
|
||||||
|
$strategy = $constraint->onDelete();
|
||||||
|
$code = "FOREIGN KEY (\"$columnName\") REFERENCES \"$refTable\" (\"$refColumn\")";
|
||||||
|
if ($strategy instanceof SetDefaultStrategy) {
|
||||||
|
$code .= " ON DELETE SET DEFAULT";
|
||||||
|
} else if($strategy instanceof SetNullStrategy) {
|
||||||
|
$code .= " ON DELETE SET NULL";
|
||||||
|
} else if($strategy instanceof CascadeStrategy) {
|
||||||
|
$code .= " ON DELETE CASCADE";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getValueDefinition($value) {
|
||||||
|
if (is_numeric($value)) {
|
||||||
|
return $value;
|
||||||
|
} else if(is_bool($value)) {
|
||||||
|
return $value ? "TRUE" : "FALSE";
|
||||||
|
} else if(is_null($value)) {
|
||||||
|
return "NULL";
|
||||||
|
} else if($value instanceof Keyword) {
|
||||||
|
return $value->getValue();
|
||||||
|
} else {
|
||||||
|
$str = str_replace("'", "''", $value);
|
||||||
|
return "'$str'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function addValue($val, &$params) {
|
||||||
|
if ($val instanceof Keyword) {
|
||||||
|
return $val->getValue();
|
||||||
|
} else {
|
||||||
|
$params[] = $val;
|
||||||
|
return '$' . count($params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Special Keywords and functions
|
||||||
|
public function currentTimestamp() {
|
||||||
|
return "CURRENT_TIMESTAMP";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
@ -39,8 +39,8 @@ class CreateTable extends Query {
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addDateTime($name, $nullable=false, $defaultNow=false) {
|
public function addDateTime($name, $nullable=false, $defaultValue=NULL) {
|
||||||
$this->columns[$name] = new DateTimeColumn($name, $nullable, $defaultNow);
|
$this->columns[$name] = new DateTimeColumn($name, $nullable, $defaultValue);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ class Insert extends Query {
|
|||||||
private $columns;
|
private $columns;
|
||||||
private $rows;
|
private $rows;
|
||||||
private $onDuplicateKey;
|
private $onDuplicateKey;
|
||||||
|
private $returning;
|
||||||
|
|
||||||
public function __construct($sql, $name, $columns=array()) {
|
public function __construct($sql, $name, $columns=array()) {
|
||||||
parent::__construct($sql);
|
parent::__construct($sql);
|
||||||
@ -15,6 +16,7 @@ class Insert extends Query {
|
|||||||
$this->columns = $columns;
|
$this->columns = $columns;
|
||||||
$this->rows = array();
|
$this->rows = array();
|
||||||
$this->onDuplicateKey = NULL;
|
$this->onDuplicateKey = NULL;
|
||||||
|
$this->returning = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addRow(...$values) {
|
public function addRow(...$values) {
|
||||||
@ -27,6 +29,11 @@ class Insert extends Query {
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function returning($column) {
|
||||||
|
$this->returning = $column;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function execute() {
|
public function execute() {
|
||||||
return $this->sql->executeInsert($this);
|
return $this->sql->executeInsert($this);
|
||||||
}
|
}
|
||||||
@ -35,6 +42,7 @@ class Insert extends Query {
|
|||||||
public function getColumns() { return $this->columns; }
|
public function getColumns() { return $this->columns; }
|
||||||
public function getRows() { return $this->rows; }
|
public function getRows() { return $this->rows; }
|
||||||
public function onDuplicateKey() { return $this->onDuplicateKey; }
|
public function onDuplicateKey() { return $this->onDuplicateKey; }
|
||||||
|
public function getReturning() { return $this->returning; }
|
||||||
};
|
};
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
@ -8,19 +8,14 @@ abstract class SQL {
|
|||||||
protected $connection;
|
protected $connection;
|
||||||
protected $connectionData;
|
protected $connectionData;
|
||||||
protected $lastInsertId;
|
protected $lastInsertId;
|
||||||
private $type;
|
|
||||||
|
|
||||||
public function __construct($type, $connectionData) {
|
public function __construct($connectionData) {
|
||||||
$this->type = $type;
|
|
||||||
$this->connection = NULL;
|
$this->connection = NULL;
|
||||||
$this->lastError = 'Not connected';
|
$this->lastError = 'Not connected';
|
||||||
$this->connectionData = $connectionData;
|
$this->connectionData = $connectionData;
|
||||||
$this->lastInsertId = 0;
|
$this->lastInsertId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract function connect();
|
|
||||||
public abstract function disconnect();
|
|
||||||
|
|
||||||
public function isConnected() {
|
public function isConnected() {
|
||||||
return !is_null($this->connection);
|
return !is_null($this->connection);
|
||||||
}
|
}
|
||||||
@ -29,17 +24,6 @@ abstract class SQL {
|
|||||||
return trim($this->lastError);
|
return trim($this->lastError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// public function executeQuery($query) {
|
|
||||||
// if(!$this->isConnected()) {
|
|
||||||
// $this->lastError = "Database is not connected yet.";
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return $query->execute($this);
|
|
||||||
// // var_dump($generatedQuery);
|
|
||||||
// // return $this->execute($generatedQuery);
|
|
||||||
// }
|
|
||||||
|
|
||||||
public function createTable($tableName) {
|
public function createTable($tableName) {
|
||||||
return new Query\CreateTable($this, $tableName);
|
return new Query\CreateTable($this, $tableName);
|
||||||
}
|
}
|
||||||
@ -64,6 +48,18 @@ abstract class SQL {
|
|||||||
return new Query\Update($this, $table);
|
return new Query\Update($this, $table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ####################
|
||||||
|
// ### ABSTRACT METHODS
|
||||||
|
// ####################
|
||||||
|
|
||||||
|
// Misc
|
||||||
|
public abstract function checkRequirements();
|
||||||
|
public abstract function getDriverName();
|
||||||
|
|
||||||
|
// Connection Managment
|
||||||
|
public abstract function connect();
|
||||||
|
public abstract function disconnect();
|
||||||
|
|
||||||
// Querybuilder
|
// Querybuilder
|
||||||
public abstract function executeCreateTable($query);
|
public abstract function executeCreateTable($query);
|
||||||
public abstract function executeInsert($query);
|
public abstract function executeInsert($query);
|
||||||
@ -71,114 +67,74 @@ abstract class SQL {
|
|||||||
public abstract function executeDelete($query);
|
public abstract function executeDelete($query);
|
||||||
public abstract function executeTruncate($query);
|
public abstract function executeTruncate($query);
|
||||||
public abstract function executeUpdate($query);
|
public abstract function executeUpdate($query);
|
||||||
|
|
||||||
//
|
|
||||||
public abstract function currentTimestamp();
|
|
||||||
|
|
||||||
protected abstract function getColumnDefinition($column);
|
protected abstract function getColumnDefinition($column);
|
||||||
protected abstract function getConstraintDefinition($constraint);
|
protected abstract function getConstraintDefinition($constraint);
|
||||||
protected abstract function getValueDefinition($val);
|
protected abstract function getValueDefinition($val);
|
||||||
protected abstract function buildCondition($conditions, &$params);
|
protected abstract function addValue($val, &$params);
|
||||||
|
|
||||||
// Execute
|
// Special Keywords and functions
|
||||||
|
public abstract function currentTimestamp();
|
||||||
|
|
||||||
|
// Statements
|
||||||
protected abstract function execute($query, $values=NULL, $returnValues=false);
|
protected abstract function execute($query, $values=NULL, $returnValues=false);
|
||||||
|
|
||||||
|
protected function buildCondition($condition, &$params) {
|
||||||
|
if ($condition instanceof \Driver\SQL\Condition\CondOr) {
|
||||||
|
$conditions = array();
|
||||||
|
foreach($condition->getConditions() as $cond) {
|
||||||
|
$conditions[] = $this->buildCondition($cond, $params);
|
||||||
|
}
|
||||||
|
return "(" . implode(" OR ", $conditions) . ")";
|
||||||
|
} else if ($condition instanceof \Driver\SQL\Condition\Compare) {
|
||||||
|
$column = $condition->getColumn();
|
||||||
|
$value = $condition->getValue();
|
||||||
|
$operator = $condition->getOperator();
|
||||||
|
return $column . $operator . $this->addValue($value, $params);
|
||||||
|
} else if ($condition instanceof \Driver\SQL\Condition\CondBool) {
|
||||||
|
return $condition->getValue();
|
||||||
|
} else if (is_array($condition)) {
|
||||||
|
if (count($condition) == 1) {
|
||||||
|
return $this->buildCondition($condition[0], $params);
|
||||||
|
} else {
|
||||||
|
$conditions = array();
|
||||||
|
foreach($condition as $cond) {
|
||||||
|
$conditions[] = $this->buildCondition($cond, $params);
|
||||||
|
}
|
||||||
|
return implode(" AND ", $conditions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function setLastError($str) {
|
public function setLastError($str) {
|
||||||
$this->lastError = $str;
|
$this->lastError = $str;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function addValue($val, &$params) {
|
|
||||||
if ($val instanceof Keyword) {
|
|
||||||
return $val->getValue();
|
|
||||||
} else {
|
|
||||||
$params[] = $val;
|
|
||||||
return "?";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*public function getLastErrorNumber() {
|
|
||||||
return mysqli_errno($this->connection);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
public function getLastInsertId() {
|
public function getLastInsertId() {
|
||||||
return $this->lastInsertId;
|
return $this->lastInsertId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function close() {
|
public function close() {
|
||||||
if(!is_null($this->connection)) {
|
$this->disconnect();
|
||||||
$this->connection->close();
|
$this->connection = NULL;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*public function getAffectedRows() {
|
|
||||||
return $this->connection->affected_rows;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
public function execute($query) {
|
|
||||||
if(!$this->isConnected()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!mysqli_query($this->connection, $query)) {
|
|
||||||
$this->lastError = mysqli_error($this->connection);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function executeMulti($queries) {
|
|
||||||
if(!$this->isConnected()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!$this->connection->multi_query($queries)) {
|
|
||||||
$this->lastError = mysqli_error($this->connection);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (($success = $this->connection->next_result())) {
|
|
||||||
if (!$this->connection->more_results()) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!$success) {
|
|
||||||
$this->lastError = mysqli_error($this->connection);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function query($query) {
|
|
||||||
if(!$this->isConnected()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$res = mysqli_query($this->connection, $query);
|
|
||||||
if(!$res) {
|
|
||||||
$this->lastError = mysqli_error($this->connection);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $res;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static function createConnection($connectionData) {
|
public static function createConnection($connectionData) {
|
||||||
$type = $connectionData->getProperty("type");
|
$type = $connectionData->getProperty("type");
|
||||||
if ($type === "mysql") {
|
if ($type === "mysql") {
|
||||||
$sql = new MySQL($connectionData);
|
$sql = new MySQL($connectionData);
|
||||||
/*} else if ($type === "postgres") {
|
} else if ($type === "postgres") {
|
||||||
// $sql = new PostgreSQL($connectionData);
|
$sql = new PostgreSQL($connectionData);
|
||||||
} else if ($type === "oracle") {
|
/*} else if ($type === "oracle") {
|
||||||
// $sql = new OracleSQL($connectionData);
|
// $sql = new OracleSQL($connectionData);
|
||||||
*/
|
*/
|
||||||
} else {
|
} else {
|
||||||
return "Unknown database type";
|
return "Unknown database type";
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql->connect();
|
if ($sql->checkRequirements()) {
|
||||||
|
$sql->connect();
|
||||||
|
}
|
||||||
|
|
||||||
return $sql;
|
return $sql;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,11 +22,8 @@ class ConnectionData {
|
|||||||
return $this->properties;
|
return $this->properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getProperty($key) {
|
public function getProperty($key, $defaultValue='') {
|
||||||
if(isset($this->properties[$key]))
|
return $this->properties[$key] ?? $defaultValue;
|
||||||
return $this->properties[$key];
|
|
||||||
else
|
|
||||||
return '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setProperty($key, $val) {
|
public function setProperty($key, $val) {
|
||||||
|
@ -101,6 +101,7 @@ class Session extends ApiObject {
|
|||||||
$this->browser,
|
$this->browser,
|
||||||
json_encode($_SESSION),
|
json_encode($_SESSION),
|
||||||
$stayLoggedIn)
|
$stayLoggedIn)
|
||||||
|
->returning("uid")
|
||||||
->execute();
|
->execute();
|
||||||
|
|
||||||
if($success) {
|
if($success) {
|
||||||
|
@ -78,13 +78,15 @@ $(document).ready(function() {
|
|||||||
var textBefore = $("#btnSubmit").text();
|
var textBefore = $("#btnSubmit").text();
|
||||||
$("#btnSubmit").prop("disabled", true);
|
$("#btnSubmit").prop("disabled", true);
|
||||||
$("#btnSubmit").html("Submitting… <i class=\"fas fa-spinner fa-spin\">");
|
$("#btnSubmit").html("Submitting… <i class=\"fas fa-spinner fa-spin\">");
|
||||||
$("#installForm input").each(function() {
|
$("#installForm .form-control").each(function() {
|
||||||
var type = $(this).attr("type");
|
var type = $(this).attr("type") ?? $(this).prop("tagName").toLowerCase();
|
||||||
var name = $(this).attr("name");
|
var name = $(this).attr("name");
|
||||||
if(type === "text") {
|
if(type === "text") {
|
||||||
params[name] = $(this).val().trim();
|
params[name] = $(this).val().trim();
|
||||||
} else if(type === "password" || type === "number") {
|
} else if(type === "password" || type === "number") {
|
||||||
params[name] = $(this).val();
|
params[name] = $(this).val();
|
||||||
|
} else if(type === "select") {
|
||||||
|
params[name] = $(this).find(":selected").val();
|
||||||
}
|
}
|
||||||
}).promise().done(function() {
|
}).promise().done(function() {
|
||||||
sendRequest(params, function(success) {
|
sendRequest(params, function(success) {
|
||||||
@ -128,4 +130,24 @@ $(document).ready(function() {
|
|||||||
retry();
|
retry();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// DATABASE PORT
|
||||||
|
var prevPort = $("#port").val();
|
||||||
|
var prevDbms = $("#type option:selected").val();
|
||||||
|
function updateDefaultPort() {
|
||||||
|
var defaultPorts = {
|
||||||
|
"mysql": 3306,
|
||||||
|
"postgres": 5432,
|
||||||
|
"oracle": 1521
|
||||||
|
};
|
||||||
|
|
||||||
|
var curDbms = $("#type option:selected").val();
|
||||||
|
if(defaultPorts[prevDbms] == prevPort) {
|
||||||
|
$("#port").val(defaultPorts[curDbms]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateDefaultPort();
|
||||||
|
$("#type").change(function() {
|
||||||
|
updateDefaultPort();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user