new pisilinux web sites

This commit is contained in:
Erkan IŞIK
2026-07-01 16:44:17 +03:00
commit b58488b586
21740 changed files with 2066209 additions and 0 deletions
@@ -0,0 +1,246 @@
<?php namespace ZN\Database;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Datatype;
trait CallableTalkingQueries
{
/**
* Magic call
*
* @param string $method
* @param array $parameters
*
* @return mixed
*/
public function __call($method, $parameters)
{
$method = strtolower($originMethodName = $method);
$split = Datatype::splitUpperCase($originMethodName);
# Is Function Elements
if( in_array($method, $this->functionElements) )
{
$functionMethod = $method; // @codeCoverageIgnore
}
else
{
$functionMethod = $this->functionElements[$method] ?? NULL;
}
# Is Vartype Elements
if( in_array($method, $this->vartypeElements) )
{
$vartypeMethod = $method;
}
else
{
$vartypeMethod = $this->vartypeElements[$method] ?? NULL;
}
# Math Functions
if( $functionMethod !== NULL )
{
return $this->callMathMethod($functionMethod, $parameters); // @codeCoverageIgnore
}
# Variable Types
elseif( $vartypeMethod !== NULL )
{
return $this->db->variableTypes($vartypeMethod, ...$parameters);
}
# Statements
# 5.7.4[edited]
elseif( in_array($method, $this->statementElements) )
{
# 5.7.4[added]
if( $method === 'constraint' )
{
$parameters[1] = false;
}
return $this->db->statements($method, ...$parameters);
}
# Join
elseif( ($split[1] ?? NULL) === 'Join')
{
return $this->callJoinTalkingQuery($split, $parameters);
}
# Order By - Group By
elseif( $split[0] === 'order' || $split[0] === 'group')
{
return $this->callOrderGroupByTalkingQuery($split);
}
# Where - Having
elseif( $split[0] === 'where' || $split[0] === 'having' )
{
return $this->callWhereHavingTalkingQuery($split, $parameters);
}
# Insert - Update - Delete
elseif( in_array($split[1] ?? NULL, ['Delete', 'Update', 'Insert']) )
{
return $this->callCrudTalkingQuery($split, $parameters);
}
else
{
return $this->callResultMethodsTalkingQuery($originMethodName, $split, $parameters);
}
}
/**
* Protected call join talkin query
*/
protected function callJoinTalkingQuery($split, $parameters)
{
$type = $split[0] ?? 'left';
$table1 = $split[2] ?? '';
$column1 = strtolower($table1 . '.' . $split[3]);
$table2 = $split[4] ?? '';
$column2 = strtolower($table2 . '.' . $split[5]);
$met = $type . $split[1];
return $this->$met($column1, $column2, $parameters[0] ?? '=');
}
/**
* Protected call order group by talking query
*/
protected function callOrderGroupByTalkingQuery($split)
{
$column = strtolower($split[2] ?? '');
$type = $split[0] === 'order' ? $split[3] ?? 'asc' : '';
$met = $split[0] . 'By';
return $this->$met($column, $type);
}
/**
* Protected call crud talking query
*/
protected function callCrudTalkingQuery($split, $parameters)
{
$table = $split[0];
$method = $split[1];
if( is_string($parameters[0]) )
{
$prefix = $parameters[0] . ':';
$data = [];
}
else
{
$prefix = '';
$data = $parameters[0];
}
# [5.6.5] In case of using 3rd section, it is accepted as a condition.
if( isset($split[2]) )
{
# For delete: tableDeleteColumn($value)
if( $method === 'Delete' && isset($parameters[0]) )
{
$prefix = '';
$this->where($split[2], $parameters[0]);
}
# For update: tableUpdateColumn($data, $value)
elseif( $method === 'Update' && isset($parameters[1]) )
{
$this->where($split[2], $parameters[1]);
}
}
return $this->$method($prefix . $table, $data);
}
/**
* Protected call where having talking query
*/
protected function callWhereHavingTalkingQuery($split, $parameters)
{
$met = $split[0];
$column = strtolower($split[1] ?? '');
$condition = $split[2] ?? '';
$operator = isset($parameters[1]) ? ' ' . $parameters[1] : '';
return $this->$met($column . $operator, $parameters[0], $condition);
}
/**
* updated[5.7.0.1]
* Protected call result methods talking query
*/
protected function callResultMethodsTalkingQuery($method, $split, $parameters)
{
$func = $split[1] ?? NULL;
$result = NULL;
# Row & Result
if( $func === 'Row' || $func === 'Result' )
{
$method = $split[0];
$result = strtolower($func);
}
$whereClause = $parameters[0] ?? ($result === 'row' ? 0 : 'object');
# Value
if( $select = ($split[2] ?? NULL) )
{
if( isset($parameters[0]) )
{
$this->where(strtolower($split[2] ?? ''), $parameters[0]);
$whereClause = 0;
}
else
{
$result = 'value';
$this->select($select);
$whereClause = true;
}
}
$return = $this->get($method);
# Return ->get()
if( ! isset($result) )
{
return $return;
}
# Return ->row(0) || result('object')
return $return->$result($whereClause);
}
/**
* Protected call math method
*
* @codeCoverageIgnore
*/
protected function callMathMethod($functionMethod, $parameters)
{
$math = $this->setMathFunction($functionMethod, $parameters);
if( $math->return === true )
{
return $math->args;
}
else
{
$this->selectFunctions[] = $math->args;
return $this;
}
}
}
+793
View File
@@ -0,0 +1,793 @@
<?php namespace ZN\Database;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Base;
use ZN\Config;
use ZN\Support;
use ZN\Helpers\Logger;
use ZN\DataTypes\Arrays;
use ZN\Database\Exception\InvalidArgumentException;
class Connection
{
/**
* Keeps database drivers
*
* @var array
*/
protected $drivers =
[
'odbc' => 'ODBC',
'mysqli' => 'MySQLi',
'oracle' => 'Oracle',
'postgres' => 'Postgres',
'sqlite' => 'SQLite',
'sqlserver' => 'SQLServer'
];
/**
* Keeps database driver
*
* @var object
*/
protected $db;
/**
* Keeps database config
*
* @var array
*/
protected $config;
/**
* Keeps database default config
*
* @var array
*/
protected $defaultConfig;
/**
* Keeps table prefix
*
* @var string
*/
protected $prefix;
/**
* Keeps secure data
*
* @var array
*/
protected $secure = [];
/**
* Keeps aliases data
*
* @var array
*/
protected $aliases = [];
/**
* Select table name
*
* @var string
*/
protected $table;
/**
* Keeps table name
*
* @var string
*/
protected $tableName;
/**
* Get string query
*
* @var string
*/
protected $stringQuery;
/**
* Get string queries
*
* @var array
*/
protected $stringQueries;
/**
* Keeps select functions
*
* @var array
*/
protected $selectFunctions;
/**
* Keeps column
*
* @var array
*/
protected $column;
/**
* Keep database driver
*
* @var string
*/
protected $driver;
/**
* Keeps string query
*
* @var string
*/
protected $string;
/**
* Transaction queries
*
* @var bool
*/
protected $transaction;
/**
* Keeps transaction queries
*
* @var array
*/
protected $transactionQueries;
/**
* Magic construtor
*
* @param array $config
*
* @return void
*/
public function __construct(array $config = [])
{
$this->defaultConfig = Config::default('ZN\Database\DatabaseDefaultConfiguration')
::get('Database', 'database');
$this->config = array_merge($this->defaultConfig, $config);
$this->db = $this->runDriver();
$this->prefix = $this->config['prefix'];
Properties::$prefix = $this->prefix;
$this->db->connect($this->config);
}
/**
* Magic Debug Info
*/
public function __debugInfo()
{
return ['return' => $this->stringQuery ?: 'This is a general object, please call the sub method!'];
}
/**
* Restructure
*
* @param array $config
*
* @return void
*/
public function restruct(array $config = [])
{
$this->__construct($config);
}
/**
* Alias different connection
*
* @param mixed $connectName = NULL
*
* @return Connection
*/
public function new($connectName = NULL) : Connection
{
return $this->differentConnection($connectName);
}
/**
* Creates different connection
*
* @param mixed $connectName = NULL
*
* @return Connection
*/
public function differentConnection($connectName = NULL) : Connection
{
$getCalledClass = get_called_class();
if( empty($connectName) )
{
return new $getCalledClass;
}
$config = $this->defaultConfig;
$configDifferent = $config['differentConnection'];
if( is_string($connectName) && isset($configDifferent[$connectName]) )
{
$connection = $configDifferent[$connectName];
}
elseif( is_array($connectName) )
{
$connection = $connectName;
}
else
{
throw new InvalidArgumentException('Error', 'invalidInput', 'Mixed $connectName');
}
foreach( $config as $key => $val )
{
if( $key !== 'differentConnection' )
{
if( ! isset($connection[$key]) )
{
$connection[$key] = $val;
}
}
}
return new $getCalledClass($connection);
}
/**
* Get var types
*
* @param void
*
* @return array
*/
public function vartypes() : array
{
return $this->db->vartypes();
}
/**
* Sets table name
*
* @param string $table
*
* @return Connection
*
* @codeCoverageIgnore
*/
public function table(string $table) : Connection
{
$this->table = ' '.$this->prefix.$table.' ';
$this->tableName = $this->prefix.$table;
Properties::$table = $this->tableName;
return $this;
}
/**
* Sets column
*
* @param string $col
* @param mixed $val = NULL
*
* @return Connection
*/
public function column(string $col, $val = NULL) : Connection
{
$this->column[$col] = $val;
return $this;
}
/**
* Converts string query
*
* @param void
*
* @return Connection
*/
public function string() : Connection
{
$this->string = true;
return $this;
}
/**
* Get string query
*
* @param void
*
* @return string
*/
public function stringQuery() : string
{
if( ! empty($this->stringQuery) )
{
return $this->stringQuery;
}
return false;
}
/**
* Get string queries
*
* @param void
*
* @return array|false
*/
public function stringQueries()
{
if( ! empty($this->stringQueries) )
{
return $this->stringQueries;
}
return false;
}
/**
* Sets query security
*
* @param array $data
*
* @return Connection
*/
public function secure(array $data) : Connection
{
$this->secure = $data;
return $this;
}
/**
* Defines function
*
* @param string ...$args
*
* @return mixed
*/
public function func(...$args)
{
$array = $args;
array_shift($array);
$math = $this->setMathFunction(isset($args[0]) ? strtoupper($args[0] ?? '') : false, $array);
if( $math->return === true )
{
return $math->args;
}
else
{
$this->selectFunctions[] = $math->args;
return $this;
}
}
/**
* Get database query error
*
* @param void
*
* @return string
*/
public function error()
{
return $this->db->error();
}
/**
* Close database connection
*
* @param void
*
* @return bool
*/
public function close()
{
return $this->db->close();
}
/**
* Get database version
*
* @param void
*
* @return string
*/
public function version()
{
return $this->db->version();
}
/**
* protected escape string add nail
*
* @param mixed $value
* @param mixed $numeric = false
*
* @return string
*/
protected function escapeStringAddNail($value, $numeric = false)
{
if( $numeric === true && is_numeric($value) )
{
return $value;
}
return Base::presuffix($this->nailEncode($value), "'");
}
/**
* protected exp
*
* @param string $column = ''
* @param string $exp = 'exp'
*
* @return string
*/
protected function isExpressionExists($column = '', $exp = 'exp')
{
return stristr($column, $exp . ':');
}
/**
* @param string $column
* @param string $ext = 'exp'
*
* @return string
*/
protected function clearExpression($column, $exp = 'exp')
{
return str_ireplace($exp . ':', '', $column ?? '');
}
/**
* protected clear nail
*
* @param string
*
* @return string
*/
protected function clearNail($value)
{
return trim((string) $value, '\'');
}
/**
* protected convert type
*
* @param string &$column
* @param string &$value
*
* @param void
*/
protected function convertVartype(&$column = '', &$value = '')
{
$clearValue = $this->clearNail($value);
if( $this->isExpressionExists($column, $type = 'int') )
{
$value = (int) $clearValue;
}
elseif( $this->isExpressionExists($column, $type = 'float') )
{
$value = (float) $clearValue;
}
else
{
$type = 'exp';
}
$column = $this->clearExpression($column, $type);
}
/**
* protected query security
*
* @param string $query
* @param string $isString = false
*
* @return string
*/
protected function querySecurity($query, $isString = false)
{
if( ! empty($this->secure) )
{
$query = $this->applySecure($query);
}
if( ! empty($this->aliases) )
{
$query = $this->applyAliases($query);
}
$this->applyNullable($query);
if( $isString === false && ($this->config['queryLog'] ?? NULL) === true )
{
Logger::report('DatabaseQueries', $query, 'DatabaseQueries'); // @codeCoverageIgnore
}
$this->stringQueries[] = $this->stringQuery = $query;
return $query;
}
/**
* protected apply nullable
*/
protected function applyNullable(&$query)
{
$query = str_ireplace('\'null\'', 'null', $query ?? '');
}
/**
* protected apply secure
*/
protected function applySecure($query)
{
$query = $query ?? '';
$secure = $this->secure; $this->secure = []; $secureParams = [];
if( is_numeric(key($secure)) )
{
$strex = explode('?', $query);
$newstr = '';
if( ! empty($strex) ) for( $i = 0; $i < count($strex) - 1; $i++ )
{
$sec = $secure[$i] ?? NULL;
$newstr .= $strex[$i].$this->escapeStringAddNail($sec);
}
$query = $newstr . end($strex);
}
else
{
foreach( $secure as $k => $v )
{
$this->convertVartype($k, $v);
$secureParams[$k] = $this->escapeStringAddNail($v);
}
}
return str_replace(array_keys($secureParams), array_values($secureParams), $query);
}
/**
* protected apply aliases
*/
protected function applyAliases($query)
{
$aliases = $this->aliases; $this->aliases = [];
foreach( $aliases as $alias => $origin )
{
$query = preg_replace
(
[
'/(^|\s)' . $this->prefix . $alias . '($|\s)/i',
'/(^|\W)' . $this->prefix . $alias . '($|\W)/i'
],
[
'$1' . $this->prefix . $origin . ' ' . $alias . '$2',
'$1' . $alias . '$2'
],
$query
);
}
return $query;
}
/**
* Sets math functions
*
* @param string $type
* @param array $args
*
* @return object
*/
protected function setMathFunction($type, $args)
{
$type = strtoupper($type ?? '');
$getLast = Arrays\GetElement::last($args) ?? '';
$asparam = ' ';
if( $getLast === true )
{
array_pop($args);
$return = true;
$as = Arrays\GetElement::last($args) ?? '';
// @codeCoverageIgnoreStart
if( stripos(trim($as), 'as') === 0 )
{
$asparam .= $as;
array_pop($args);
}
// @codeCoverageIgnoreEnd
}
else
{
$return = false;
}
// @codeCoverageIgnoreStart
if( stripos(trim($getLast), 'as') === 0 )
{
$asparam .= $getLast;
array_pop($args);
}
// @codeCoverageIgnoreEnd
$args = $type.'('.rtrim(implode(',', $args), ',').')'.$asparam;
return (object)
[
'args' => $args,
'return' => $return
];
}
/**
* Run driver
*
* @param array $settings = []
*
* @return object
*/
protected function runDriver($settings = [])
{
$this->driver = preg_replace('/(\w+)(\:\w+)*/', '$1', $this->config['driver']);
return $this->getDriver(NULL, $settings);
}
/**
* protected get driver library
*
* @param string $suffix = 'Driver'
* @param array $settings = []
*
* @return object
*/
protected function getDriver($suffix = NULL, $settings = [])
{
Support::driver(array_keys($this->drivers), $this->driver);
$class = 'ZN\Database\\' . $this->drivers[$this->driver] . '\\DB' . $suffix;
return new $class($settings);
}
/**
* protected encode nail
*
* @param string $data
*
* @return string
*/
protected function nailEncode($data)
{
if( $data === NULL )
{
return 'NULL';
}
return str_replace(["'", "\&#39;", "\\&#39;"], "&#39;", $data);
}
/**
* protected run exec query
*
* @param string $query
* @param string $type = 'query'
*
* @return mixed
*/
protected function runQuery($query, $type = 'query')
{
// @codeCoverageIgnoreStart
if( $this->string === true )
{
$this->string = NULL;
return $query;
}
// @codeCoverageIgnoreEnd
if( $this->transaction === true )
{
$this->transactionQueries[] = $query;
return $this;
}
if( empty($query) )
{
$this->stringQuery = NULL;
return false;
}
$this->db->$type($this->querySecurity($query), $this->secure);
return ! (bool) $this->db->error();
}
/**
* protected run exec query
*
* @param string $query
*
* @return string
*/
protected function runExecQuery($query)
{
return $this->runQuery($query, 'exec');
}
/**
* Sets table name
*
* @param mixed $p = NULL
* @param string $name = 'table'
*
* @return string
*/
protected function addPrefixForTableAndColumn($p = NULL, $name = 'table')
{
if( $name === 'prefix' )
{
return $this->$name.$p;
}
if( $name === 'table' )
{
$p = $this->prefix.$p;
}
if( ! empty($this->$name) )
{
$data = $this->$name;
$this->$name = NULL;
return $data;
}
else
{
return $p;
}
}
/**
* Magic destructor
*
* @param void
*
* @return void
*/
public function __destruct()
{
$this->db->close();
}
}
File diff suppressed because it is too large Load Diff
+491
View File
@@ -0,0 +1,491 @@
<?php namespace ZN\Database;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Support;
use ZN\Datatype;
use ZN\Singleton;
#[\AllowDynamicProperties]
class DBForge extends Connection
{
/**
* @var array
*/
protected $extras;
/**
* Keeps Forge Driver
*
* @var object
*/
protected $forge;
/**
* Magic Call
*
* @param string $method
* @param array $parameters
*
* @param mixed
*/
public function __call($method, $parameters)
{
$split = Datatype::splitUpperCase($originMethodName = $method);
$table = $split[0];
$method = $split[1] ?? NULL;
switch($method)
{
case 'Create' : $method = 'createTable'; break;
case 'Drop' : $method = 'dropTable' ; break;
case 'Alter' : $method = 'alterTable' ; break;
case 'Rename' : $method = 'renameTable'; break;
case 'Truncate': $method = 'truncate' ; break;
default : Support::classMethod(get_called_class(), $originMethodName); // @codeCoverageIgnore
}
return $this->$method($table, ...$parameters);
}
/**
* Magic Constructor
*
* @param array $settings
*/
public function __construct($settings = [])
{
parent::__construct($settings);
$this->forge = $this->getDriver('Forge', $settings);
}
/**
* Create Table & Database Extras
*
* @param mixed $extras
*
* @return DBForge
*/
public function extras($extras) : DBForge
{
$this->extras = $this->forge->extras($extras);
return $this;
}
/**
* Create Database
*
* @param string $dbname
* @param string $extras
*
* @return bool
*/
public function createDatabase(string $dbname, $extras = NULL)
{
$query = $this->forge->createDatabase($dbname, $this->addPrefixForTableAndColumn($extras, 'extras'));
return $this->runExecQuery($query);
}
/**
* Drop Database
*
* @param string $dbname
*
* @return bool
*/
public function dropDatabase(string $dbname)
{
$query = $this->forge->dropDatabase($dbname);
return $this->runExecQuery($query);
}
/**
* Create Table
*
* @param string $tabşe
* @param array $columns
* @param string $extras
*
* @return bool
*/
public function createTable(?string $table = NULL, ?array $columns = NULL, $extras = NULL)
{
$query = $this->forge->createTable($this->addPrefixForTableAndColumn($table), $this->addPrefixForTableAndColumn($columns, 'column'), $this->addPrefixForTableAndColumn($extras, 'extras'));
return $this->runExecQuery($query);
}
/**
* Create Temporary Table
*
* @param string $tabşe
* @param array $columns
* @param string $extras
*
* @return bool
*
* @codeCoverageIgnore
*/
public function createTempTable(?string $table = NULL, ?array $columns = NULL, $extras = NULL)
{
$query = $this->forge->createTempTable($this->addPrefixForTableAndColumn($table), $this->addPrefixForTableAndColumn($columns, 'column'), $this->addPrefixForTableAndColumn($extras, 'extras'));
return $this->runExecQuery($query);
}
/**
* Drop Table
*
* @param string $table
*
* @return bool
*/
public function dropTable(?string $table = NULL)
{
$query = $this->forge->dropTable($this->addPrefixForTableAndColumn($table));
return $this->runExecQuery($query);
}
/**
* Alter Table
*
* @param string $table
* @param mixed $condition
*
* @return bool
*
* @codeCoverageIgnore
*/
public function alterTable(?string $table = NULL, ?array $condition = NULL)
{
$table = $this->addPrefixForTableAndColumn($table);
$key = key($condition);
return $this->$key($table, $condition[$key]);
}
/**
* Rename Table
*
* @param string $name
* @param string $newname
*
* @return bool
*/
public function renameTable(string $name, string $newName)
{
$query = $this->forge->renameTable($this->addPrefixForTableAndColumn($name, 'prefix'), $this->addPrefixForTableAndColumn($newName, 'prefix'));
return $this->runExecQuery($query);
}
/**
* Truncate
*
* @param string $table
*
* @return bool
*/
public function truncate(?string $table = NULL)
{
$query = $this->forge->truncate($this->addPrefixForTableAndColumn($table));
return $this->runExecQuery($query);
}
/**
* Add Column
*
* @param string $table
* @param array $columns
*
* @return bool
*/
public function addColumn(?string $table = NULL, ?array $columns = NULL)
{
$query = $this->forge->addColumn($this->addPrefixForTableAndColumn($table), $this->addPrefixForTableAndColumn($columns, 'column'));
return $this->runExecQuery($query);
}
/**
* Start Auto Increment
*
* 5.7.4[added]
*
* @param string $table
* @param int $start = 0
*
* @return bool
*
* @codeCoverageIgnore
*/
public function startAutoIncrement(string $table, int $start = 0)
{
$query = $this->forge->startAutoIncrement($this->addPrefixForTableAndColumn($table), $start);
return $this->runExecQuery($query);
}
/**
* Start Auto Increment
*
* 5.7.4[added]
*
* @param string $table
* @param int $start = 0
*
* @return bool
*
* @codeCoverageIgnore
*/
public function addAutoIncrement(string $table, string $column = 'id', ?int $start = NULL)
{
if( $start !== NULL )
{
$this->startAutoIncrement($table, $start);
}
return $this->modifyColumn($table, [$column => [($db = Singleton::class('ZN\Database\DB'))->int(), $db->autoIncrement()]]);
}
/**
* Add Primary Key
*
* 5.7.4[added]
*
* @param string $table
* @param string $columns
* @param string $constraint = NULL
*
* @return bool
*/
public function addPrimaryKey(string $table, string $columns, ?string $constraint = NULL)
{
$query = $this->forge->addPrimaryKey($this->addPrefixForTableAndColumn($table), $columns, $constraint);
return $this->runExecQuery($query);
}
/**
* Add Foreign Key
*
* 5.7.4[added]
*
* @param string $table
* @param string $columns
* @param string $reftable
* @param string $refcolumn
* @param string $constraint = NULL
*
* @return bool
*/
public function addForeignKey(string $table, string $columns, string $reftable, string $refcolumn, ?string $constraint = NULL)
{
$query = $this->forge->addForeignKey($this->addPrefixForTableAndColumn($table), $columns, $reftable, $refcolumn, $constraint);
return $this->runExecQuery($query);
}
/**
* Drop Primary Key
*
* 5.7.4[added]
*
* @param string $table
* @param string $constraint = NULL
*
* @return bool
*/
public function dropPrimaryKey(?string $table = NULL, ?string $constraint = NULL)
{
$query = $this->forge->dropPrimaryKey($this->addPrefixForTableAndColumn($table), $constraint);
return $this->runExecQuery($query);
}
/**
* Drop Foreign Key
*
* 5.7.4[added]
*
* @param string $table
* @param string $constraint = NULL
*
* @return bool
*/
public function dropForeignKey(?string $table = NULL, ?string $constraint = NULL)
{
$query = $this->forge->dropForeignKey($this->addPrefixForTableAndColumn($table), $constraint);
return $this->runExecQuery($query);
}
/**
* Create index
*
* 5.7.4[added]
*
* @param string $indexName
* @param string $table
* @param string $columns
*
* @return bool
*/
public function createIndex(string $indexName, string $table, string $columns)
{
$query = $this->forge->createIndex($indexName, $this->addPrefixForTableAndColumn($table), $columns);
return $this->runExecQuery($query);
}
/**
* Create Unique index
*
* 5.7.4[added]
*
* @param string $indexName
* @param string $table
* @param string $columns
*
* @return bool
*/
public function createUniqueIndex(string $indexName, string $table, string $columns)
{
$query = $this->forge->createUniqueIndex($indexName, $this->addPrefixForTableAndColumn($table), $columns);
return $this->runExecQuery($query);
}
/**
* Create Fulltext index
*
* 5.7.4[added]
*
* @param string $indexName
* @param string $table
* @param string $columns
*
* @return bool
*/
public function createFulltextIndex(string $indexName, string $table, string $columns)
{
$query = $this->forge->createFulltextIndex($indexName, $this->addPrefixForTableAndColumn($table), $columns);
return $this->runExecQuery($query);
}
/**
* Create Spatial index
*
* 5.7.4[added]
*
* @param string $indexName
* @param string $table
* @param string $columns
*
* @return bool
*/
public function createSpatialIndex(string $indexName, string $table, string $columns)
{
$query = $this->forge->createSpatialIndex($indexName, $this->addPrefixForTableAndColumn($table), $columns);
return $this->runExecQuery($query);
}
/**
* Drop index
*
* 5.7.4[added]
*
* @param string $indexName
* @param string $table
*
* @return string
*/
public function dropIndex(string $indexName, ?string $table = NULL)
{
$query = $this->forge->dropIndex($indexName, $this->addPrefixForTableAndColumn($table));
return $this->runExecQuery($query);
}
/**
* Drop Column
*
* @param string $table
* @param array $columns
*
* @return bool
*/
public function dropColumn(?string $table = NULL, $columns = NULL)
{
$columns = $this->addPrefixForTableAndColumn($columns, 'column');
if( ! is_array($columns) )
{
$query = $this->forge->dropColumn($this->addPrefixForTableAndColumn($table), $columns);
return $this->runExecQuery($query);
}
else
{
foreach( $columns as $key => $col )
{
if( ! is_numeric($key) )
{
$col = $key; // @codeCoverageIgnore
}
$query = $this->forge->dropColumn($this->addPrefixForTableAndColumn($table), $col);
$this->runExecQuery($query);
}
return ! (bool) $this->error();
}
}
/**
* MOdify Column
*
* @param string $table
* @param array $columns
*
* @return bool
*/
public function modifyColumn(?string $table = NULL, ?array $columns = NULL)
{
$query = $this->forge->modifyColumn($this->addPrefixForTableAndColumn($table), $this->addPrefixForTableAndColumn($columns, 'column'));
return $this->runExecQuery($query);
}
/**
* Rename Column
*
* @param string $table
* @param array $columns
*
* @return bool
*/
public function renameColumn(?string $table = NULL , ?array $columns = NULL)
{
$query = $this->forge->renameColumn($this->addPrefixForTableAndColumn($table), $this->addPrefixForTableAndColumn($columns, 'column'));
return $this->runExecQuery($query);
}
}
+118
View File
@@ -0,0 +1,118 @@
<?php namespace ZN\Database;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
#[\AllowDynamicProperties]
class DBTool extends Connection
{
/**
* Database Tool Driver
*
* @param object
*/
protected $tool;
/**
* Magic Constructor
*
* @param array $settings
*/
public function __construct($settings = [])
{
parent::__construct($settings);
$this->tool = $this->getDriver('Tool', $settings);
}
/**
* List Databases
*
* @return array
*/
public function listDatabases()
{
return $this->tool->listDatabases();
}
/**
* List Tables
*
* @return array
*/
public function listTables()
{
return $this->tool->listTables();
}
/**
* Status Tabkes
*
* @param mixed $table
*
* @return object
*/
public function statusTables($table = '*')
{
return $this->tool->statusTables($table);
}
/**
* Optimize Tabkes
*
* @param mixed $table
*
* @return string
*/
public function optimizeTables($table = '*')
{
return $this->tool->optimizeTables($table);
}
/**
* Repair Tables
*
* @param mixed $table
* @param string $query = 'REPAIR TABLE'
* @param string $message = 'repairTablesSuccess'
*
* @return string
*/
public function repairTables($table = '*')
{
return $this->tool->repairTables($table);
}
/**
* Backup Table
*
* @param mixed $tables
* @param string $fileName
* @param string $path
*
* @return string
*/
public function backup($tables = '*', ?string $fileName = NULL, string $path = STORAGE_DIR)
{
return $this->tool->backup($tables, $fileName, $path);
}
/**
* Import File
*
* @param string $file
*
* @return bool
*/
public function import(string $file)
{
return $this->tool->import($file);
}
}
@@ -0,0 +1,81 @@
<?php namespace ZN\Database;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
/**
* Default Configuration
*
* Enabled when the configuration file can not be accessed.
*/
class DatabaseDefaultConfiguration
{
/*
|--------------------------------------------------------------------------
| Database
|--------------------------------------------------------------------------
|
| Database connection settings are made.
|
| driver : The database platform to be used is set.
| Options: mysqli, pdo(Only MySQL), oracle, postgres, sqlite,
| sqlserver, odbc
| host : Database server address.
| database : Sets the database name.
| user : Sets the database user name.
| password : Sets the database user password.
| dns : DSN connection settings.
| Using Database: Oracle, ODBC, Postgres, PDO
| server : Sets the server.
| Using Database: ODBC, SQLServer
| port : Sets the port.
| Using Database: Postgres, SQLServer, PDO:MySQL
| ssl : SSL connection.
| Using Database: PDO, MySQLi
| cacheDriver: Sets the cache driver.
| Options: get, apcu, apc, memcache, wincache, file, redis
| queryLog : Sets the loging of queries.
| pconnect : Sets the persistent connection status.
| Using Database: Oracle, ODBC, Postgres, SQLite
| encode : It only uses the SQLServer driver.
| prefix : Defines a prefix for prefixed tables.
| charset : Character encoding of constructions.
| collation : Character group definition.
| Using Database: MySQLi, PDO:MySQL
| differentConnection: It creates different connections at the same time.
| Used with DB/Forge/Tool::differentConnection() method.
| ['x' => ['driver' => 'postgres', ...], ...]
|
*/
public $driver = 'mysqli';
public $host = 'localhost';
public $database = 'test';
public $user = 'root';
public $password = '';
public $dsn = '';
public $server = '';
public $port = '';
public $ssl =
[
'key' => NULL,
'cert' => NULL,
'ca' => NULL,
'capath' => NULL,
'cipher' => NULL
];
public $cacheDriver = 'file';
public $queryLog = false;
public $pconnect = false;
public $encode = false;
public $prefix = '';
public $charset = 'utf8';
public $collation = 'utf8_general_ci';
public $differentConnection = [];
}
@@ -0,0 +1,49 @@
<?php namespace ZN\Database;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
/**
* Default Configuration
*
* Enabled when the language file can not be accessed.
*/
class DatabaseDefaultLanguage
{
/*
|--------------------------------------------------------------------------
| Database
|--------------------------------------------------------------------------
|
| The language of the Database library.
|
*/
public $en =
[
'tableNotExistsError' => '`%` table is not exists!',
'updateError' => 'Update not performed!',
'connectError' => 'ERROR: Database connection error! Please check your connection settings.',
'duplicateCheckError' => '`%` Column or Columns could not be added because it has the same value as before!',
'optimizeTablesSuccess' => 'The optimization process was completed successfully.',
'backupTablesSuccess' => 'The backup process was completed successfully.',
'repairTablesSuccess' => 'The repair process was completed successfully.'
];
public $tr =
[
'tableNotExistsError' => '`%` tablosu bulunamadı!',
'updateError' => 'Güncelleme işlemi gerçekleştirilemedi!',
'connectError' => 'HATA: Veritabanı bağlantısı sağlanamadı! Lütfen bağlantı ayarlarınızı kontrol edin.',
'duplicateCheckError' => '`%` sütun veya sütunları daha önce aynı değere sahip olduğu için eklenemedi!',
'optimizeTablesSuccess' => 'Optimizasyon işlemi başarı ile tamamlandı.',
'backupTablesSuccess' => 'Yedekleme işlemi başarı ile tamamlandı.',
'repairTablesSuccess' => 'Onarma işlemi başarı ile tamamlandı.'
];
}
@@ -0,0 +1,27 @@
<?php namespace ZN\Database;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Lang;
use ZN\Singleton;
class DriverExtends
{
protected $differentConnection;
protected $settings;
protected $getLang;
public function __construct($settings = [])
{
$this->settings = $settings;
$this->differentConnection = Singleton::class('ZN\Database\DB')->differentConnection($settings);
$this->getLang = Lang::default('ZN\Database\DatabaseDefaultLanguage')::select('Database');
}
}
+458
View File
@@ -0,0 +1,458 @@
<?php namespace ZN\Database;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Singleton;
class DriverForge
{
/**
* Create Table & Database Extras
*
* @param mixed $extras
*
* @return mixed
*
* @codeCoverageIgnore
*/
public function extras($extras)
{
return $extras;
}
/**
* Create Database
*
* @param string $dbname
* @param string $extras
*
* @return string
*/
public function createDatabase($dbname, $extras)
{
return 'CREATE DATABASE ' . $dbname . $this->addExtrasForCreateProcess($extras);
}
/**
* Drop Database
*
* @param string $dbname
*
* @return string
*/
public function dropDatabase($dbname)
{
return 'DROP DATABASE ' . $dbname;
}
/**
* Create Table
*
* @param string $tabşe
* @param array $columns
* @param string $extras
*
* @return string
*/
public function createTable($table, $columns, $extras)
{
return 'CREATE TABLE ' . $this->createTableColumnsSyntax($table, $columns, $extras);
}
/**
* Create Temporary Table
*
* @param string $tabşe
* @param array $columns
* @param string $extras
*
* @return string
*
* @codeCoverageIgnore
*/
public function createTempTable($table, $columns, $extras)
{
return 'CREATE TEMPORARY TABLE ' . $this->createTableColumnsSyntax($table, $columns, $extras);
}
/**
* Protected create table columns syntax
*/
protected function createTableColumnsSyntax($table, $columns, $extras)
{
$column = '';
foreach( $columns as $key => $value )
{
$values = '';
if( is_array($value) ) foreach( $value as $val )
{
$values .= ' ' . rtrim($val);
}
else
{
$values = $value;
}
$this->commonConversion($key, $values);
$column .= $key . ' ' . rtrim($values) . ', ';
}
return $table . '(' .rtrim(trim($column), ', ') . ')' . $this->addExtrasForCreateProcess($extras);
}
/**
* Drop Table
*
* @param string $table
*
* @return string
*/
public function dropTable($table)
{
return 'DROP TABLE ' . $table;
}
/**
* Alter Table
*
* @param string $table
* @param mixed $condition
*/
public function alterTable($table, $condition){}
/**
* Rename Table
*
* @param string $name
* @param string $newname
*
* @return string
*/
public function renameTable($name, $newName)
{
return 'ALTER TABLE ' . $name . ' RENAME TO ' . $newName;
}
/**
* Truncate
*
* @param string $table
*
* @return string
*/
public function truncate($table)
{
return 'TRUNCATE TABLE ' . $table;
}
/**
* Add Column
*
* @param string $table
* @param array $columns
*
* @return string
*/
public function addColumn($table, $columns)
{
return 'ALTER TABLE ' . $table . ' ADD (' . $this->buildForgeColumnsQuery($columns) . ');';
}
/**
* Drop Column
*
* @param string $table
* @param array $columns
*
* @return string
*/
public function dropColumn($table, $column)
{
return 'ALTER TABLE ' . $table . ' DROP ' . $column . ';';
}
/**
* Start Auto Increment
*
* 5.7.4[added]
*
* @param string $table
* @param int $start = 0
*
* @return string
*
* @codeCoverageIgnore
*/
public function startAutoIncrement($table, $start = 0)
{
return 'ALTER TABLE ' . $table . ' ' . $this->db()->autoIncrement() . '=' . $start . ';';
}
/**
* Add Primary Key
*
* 5.7.4[added]
*
* @param string $table
* @param string $columns
* @param string $constraint = NULL
*
* @return string
*/
public function addPrimaryKey($table, $columns, $constraint = NULL)
{
return 'ALTER TABLE ' . $table . ' ADD ' . $this->addedConstraint($constraint) . $this->db()->primaryKey() . '(' . $columns . ');';
}
/**
* Add Foreign Key
*
* 5.7.4[added]
*
* @param string $table
* @param string $columns
* @param string $reftable
* @param string $refcolumn
* @param string $constraint = NULL
*
* @return string
*/
public function addForeignKey($table, $columns, $reftable, $refcolumn, $constraint = NULL)
{
return 'ALTER TABLE ' . $table . ' ADD ' . $this->addedConstraint($constraint) . $this->db()->foreignKey() . '(' . $columns . ') REFERENCES '.$reftable.'('.$refcolumn.');';
}
/**
* Create index
*
* 5.7.4[added]
*
* @param string $indexName
* @param string $table
* @param string $columns
*
* @return string
*/
public function createIndex($indexName, $table, $columns, $uniq = NULL)
{
return 'CREATE ' . $uniq . ' INDEX ' . $indexName . ' ON ' . $table . ' (' . $columns . ');';
}
/**
* Create Unique index
*
* 5.7.4[added]
*
* @param string $indexName
* @param string $table
* @param string $columns
*
* @return string
*/
public function createUniqueIndex($indexName, $table, $columns)
{
return $this->createIndex($indexName, $table, $columns, 'UNIQUE');
}
/**
* Create Fulltext index
*
* 5.7.4[added]
*
* @param string $indexName
* @param string $table
* @param string $columns
*
* @return string
*/
public function createFulltextIndex($indexName, $table, $columns)
{
return $this->createIndex($indexName, $table, $columns, 'FULLTEXT');
}
/**
* Create Spatial index
*
* 5.7.4[added]
*
* @param string $indexName
* @param string $table
* @param string $columns
*
* @return string
*/
public function createSpatialIndex($indexName, $table, $columns)
{
return $this->createIndex($indexName, $table, $columns, 'SPATIAL');
}
/**
* Drop index
*
* 5.7.4[added]
*
* @param string $indexName
* @param string $table
*
* @return string
*/
public function dropIndex($indexName, $table)
{
return 'ALTER TABLE ' . $table . ' DROP INDEX ' . $indexName . ';';
}
/**
* Drop Primary Key
*
* 5.7.4[added]
*
* @param string $table
* @param string $constraint = NULL
*
* @return string
*/
public function dropPrimaryKey($table, $constraint = NULL)
{
return 'ALTER TABLE ' . $table . ' DROP ' . $this->db()->constraint() . ' ' . $constraint . ';';
}
/**
* Drop Foreign Key
*
* 5.7.4[added]
*
* @param string $table
* @param string $constraint = NULL
*
* @return string
*/
public function dropForeignKey($table, $constraint = NULL)
{
return 'ALTER TABLE ' . $table . ' DROP ' . $this->db()->constraint() . $constraint . ';';
}
/**
* MOdify Column
*
* @param string $table
* @param array $columns
*
* @return string
*/
public function modifyColumn($table, $columns)
{
return 'ALTER TABLE ' . $table . ' MODIFY ' . $this->buildForgeColumnsQuery($columns) . ';';
}
/**
* Rename Column
*
* @param string $table
* @param array $columns
*
* @return string
*/
public function renameColumn($table, $columns)
{
return 'ALTER TABLE ' . $table . ' CHANGE COLUMN ' . $this->buildForgeColumnsQuery($columns) . ';';
}
/**
* Protected added constraint
*/
protected function addedConstraint($string = NULL)
{
if( $string !== NULL )
{
return $this->db()->constraint() . ' ' . $string . ' ';
}
return NULL;
}
/**
* Protected DB class
*
* @return ZN\Database\DB
*/
protected function db()
{
return Singleton::class('ZN\Database\DB');
}
/**
* Protected common conversion
*/
protected function commonConversion($key, &$value)
{
$value = preg_replace('/('.$this->db()->constraint().'.*?)*('.(rtrim($this->db()->foreignKey())).')/', ', $1 $2 ('.$key.')', $value);
}
/**
* protected Syntax
*/
protected function buildForgeColumnsSyntax($column, $sep = NULL)
{
return key($column) . ' ' . $sep . ' ' . (is_array($cols = current($column)) ? implode(' ', $cols) : $cols);
}
/**
* Protected Extract Column
*/
protected function buildForgeColumnsQuery($columns)
{
$con = '';
foreach( $columns as $column => $values )
{
$colvals = '';
if( is_array($values) )
{
foreach( $values as $val )
{
$colvals .= ' ' . $val;
}
}
else
{
$colvals .= ' ' . $values;
}
$con .= $column . $colvals . ',';
}
return rtrim($con, ',');
}
/**
* Protected Extras
*/
protected function addExtrasForCreateProcess($extras)
{
if( is_array($extras) )
{
$extraCodes = ' ' . implode(' ', $extras) . ';'; // @codeCoverageIgnore
}
elseif( is_string($extras) )
{
$extraCodes = ' ' . $extras . ';';
}
else
{
$extraCodes = '';
}
return $extraCodes;
}
}
@@ -0,0 +1,400 @@
<?php namespace ZN\Database;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Protection\Json;
abstract class DriverMappingAbstract
{
/**
* Variables
*
* @var mixed
*/
protected $config, $connect, $query;
/**
* Abstract Methods
*/
abstract public function connect($config);
abstract public function exec($query, $security);
abstract public function query($query, $security);
/**
* Standart Methods
*/
public function multiQuery($query, $security){}
public function transStart(){}
public function transRollback(){}
public function transCommit(){}
public function insertID(){}
public function columnData($column){}
public function numRows(){}
public function columns(){}
public function numFields(){}
public function realEscapeString($data){}
public function error(){}
public function fetchArray(){}
public function fetchAssoc(){}
public function fetchRow(){}
public function affectedRows(){}
public function version(){}
/**
* Protected Clean Limit
*
* @param string $data
*
* @return array
*/
public function cleanLimit($data)
{
return preg_replace('/limit\s+[0-9]+(\s*OFFSET\s*[0-9]+)*/xi', '', $data);
}
/**
* Protected Get Limit Values
*
* @param string $data
*
* @return array
*/
public function getLimitValues($data)
{
preg_match('/limit\s+(?<limit>[0-9]+)(\s*OFFSET\s*(?<start>[0-9]+))*/xi', $data ?? '', $match);
return $match;
}
/**
* Limit
*
* @param int $start = NULL
* @param int $limit = 0
*
* @return DB
*
* @codeCoverageIgnore
*/
public function limit($start = NULL, int $limit = 0)
{
return ' LIMIT '. ( ! empty($limit) ? $limit . ' OFFSET ' . $start. ' ' : $start );
}
/**
* protected get insert extras by drvier
*
* @codeCoverageIgnore
*/
public function getInsertExtrasByDriver()
{
return false;
}
/**
* Result
*
* @param string $type = 'object'
*
* @return object|array|string
*/
public function result($type = 'object', $jsonColumns = NULL, $usageRow = false)
{
if( empty($this->query) )
{
return [];
}
$rows = [];
while( $data = $this->fetchAssoc() )
{
if( $jsonColumns )
{
$data = $this->jsonDecode($jsonColumns, $data, $type, $usageRow);
}
if( $type === 'object' )
{
$data = (object) $data;
}
$rows[] = $data;
}
return $rows;
}
/**
* Result Array
*
* @return array
*
* @codeCoverageIgnore
*/
public function resultArray()
{
return $this->result('array');
}
/**
* Row
*
* @return object|false
*
* @codeCoverageIgnore
*/
public function row()
{
if( ! empty($this->query) )
{
$data = $this->fetchAssoc();
return (object) $data;
}
else
{
return false;
}
}
/**
* References
*
* @param string $table
* @param string $column
*/
public function references($table, $column)
{
return 'REFERENCES '.$table.'('.$column.')';
}
/**
* Foreign Key
*
* @param string $column
* @param string $references
*/
public function foreignKey($column = NULL, $references = NULL)
{
if( $references === NULL )
{
return $this->statements('foreignkey', $column);
}
// @codeCoverageIgnoreStart
elseif( $column === NULL )
{
return $this->statements('foreignkey');
}
return $this->statements('foreignkey') . ' ' . $this->references($column, $references);
// @codeCoverageIgnoreEnd
}
/**
* Full Text
*
* 5.7.4[added]
*
* @param string $column
* @param string $value
* @param string $type = NULL
*
* @return string
*/
public function fullText($column, $value, $type = NULL)
{
$against = '';
switch( $type )
{
case 'boolean' : $against = ' IN BOOLEAN MODE' ; break;
case 'booleanExpansion' : $against = ' IN BOOLEAN MODE WITH QUERY EXPANSION' ; break;
case 'language' : $against = ' IN NATURAL LANGUAGE MODE' ; break;
case 'expansion' : $against = ' WITH QUERY EXPANSION' ; break;
case 'languageExpansion': $against = ' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION'; break;
}
return 'MATCH(' . $column . ') AGAINST(' . $value . $against . ')';
}
/**
* Where Json
*
* @string $column
* @string $value
*/
public function whereJson($column, $value, $type = 'IS NOT NULL')
{
return 'JSON_SEARCH('.$column.', \'one\', '.$value.') ' . $type;
}
/**
* Where Not Json
*
* @string $column
* @string $value
*/
public function whereNotJson($column, $value)
{
return $this->whereJson($column, $value, 'IS NULL');
}
/**
* Vartypes
*
* @return string
*/
public function vartypes()
{
return $this->variableTypes;
}
/**
* Cvartype
*
* @param string $type = NULL
* @param int $len = NULL
* @param bool $output = true
*
* @return string
*/
private function cvartype($type = NULL, $len = NULL, $output = true)
{
if( empty($len) )
{
return " $type ";
}
elseif( $output === true )
{
return " $type($len) ";
}
else
{
return " $type $len ";
}
}
/**
* Operator
*
* @param string $operator = 'like'
*
* @return mixed
*/
public function operator($operator = 'like')
{
$operator = strtolower($operator);
return $this->operators[$operator] ?? false;
}
/**
* Statements
*
* @param string $state = NULL
* @param int $len = NULL
* @param bool $type = true
*
* @return string|false
*/
public function statements($state = NULL, $len = NULL, $type = true)
{
$state = strtolower($state ?? '');
if( $isstate = ($this->statements[$state] ?? NULL) )
{
if( strstr($isstate, '%') )
{
$vartype = str_replace('%', $len ?? '', $isstate); // @codeCoverageIgnore
return $this->cvartype($vartype); // @codeCoverageIgnore
}
return $this->cvartype($isstate, $len, $type);
}
else
{
return false; // @codeCoverageIgnore
}
}
/**
* Closes a previously opened database connection
*
* @return bool
*/
public function close()
{
if( ! empty($this->connect) )
{
$this->query = NULL;
$this->connect = NULL;
return true;
}
else
{
return false;
}
}
/**
* Variable Types
*
* @param string $vartype = NULL
* @param int $len = NULL
* @param bool $type = true
*
* @return string|false
*/
public function variableTypes($vartype = NULL, $len = NULL, $type = true)
{
$vartype = strtolower($vartype ?? '');
if( $isvartype = ($this->variableTypes[$vartype] ?? NULL) )
{
if( strpos($isvartype, ':') === 0 )
{
$len = NULL;
$isvartype = substr($isvartype, 1);
}
return $this->cvartype($isvartype, $len, $type);
}
return false; // @codeCoverageIgnore
}
/**
* protected json decode
*/
protected function jsonDecode($columns, $row, $type, $usageRow)
{
$columns = $columns === '*' ? array_keys(preg_grep('/^(\{|\[).*(\]|\})$/s', $row)) : $columns;
if( is_array($columns) )
{
foreach( $columns as $column )
{
$value = $row[$column] ?? '';
if( Json::check($value) )
{
$row[$column] = ( $type === 'object' || $usageRow === true ) ? Json::decodeObject($value) : Json::decodeArray($value);
}
}
return $row;
}
return $row; // @codeCoverageIgnore
}
}
+284
View File
@@ -0,0 +1,284 @@
<?php namespace ZN\Database;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use stdClass;
use ZN\Base;
class DriverTool extends DriverExtends
{
/**
* List Databases
*
* @return array
*/
public function listDatabases($query = 'SHOW DATABASES')
{
return $this->runListQuery($query);
}
/**
* List Tables
*
* @return array
*/
public function listTables($query = 'SHOW TABLES')
{
return $this->runListQuery($query);
}
/**
* Protected List
*/
protected function runListQuery($query)
{
$result = $this->differentConnection->query($query)->result();
if( empty($result) )
{
return [];
}
$newTables = [];
foreach( $result as $tables )
{
foreach( $tables as $tb => $table )
{
$newTables[] = $table;
}
}
return $newTables;
}
/**
* Status Tabkes
*
* @param mixed $table
*
* @return object
*/
public function statusTables($table)
{
$infos = new stdClass;
if( $table === '*' )
{
$listTables = $this->listTables();
foreach( $listTables as $table )
{
$infos->$table = $this->differentConnection->status($table)->row(); // @codeCoverageIgnore
}
}
elseif( is_array($table) )
{
foreach( $table as $tbl )
{
$infos->$tbl = $this->differentConnection->status($tbl)->row();
}
}
else
{
$infos = $this->differentConnection->status($table)->row();
}
return $infos;
}
/**
* Optimize Tabkes
*
* @param mixed $table
*
* @return string
*/
public function optimizeTables($table)
{
return $this->repairTables($table, 'OPTIMIZE TABLE', 'optimizeTablesSuccess');
}
/**
* Repair Tables
*
* @param mixed $table
* @param string $query = 'REPAIR TABLE'
* @param string $message = 'repairTablesSuccess'
*
* @return string
*/
public function repairTables($table, $query = 'REPAIR TABLE', $message = 'repairTablesSuccess')
{
$result = $this->differentConnection->query("SHOW TABLES")->result();
$status = NULL;
if( $table === '*' )
{
foreach( $result as $tables )
{
// @codeCoverageIgnoreStart
foreach( $tables as $db => $tableName )
{
$status = $this->differentConnection->query($query . ' ' . $tableName);
}
// @codeCoverageIgnoreEnd
}
}
else
{
$tables = is_array($table)
? $table
: explode(',',$table);
foreach( $tables as $tableName )
{
$status = $this->differentConnection->query($query . ' ' . Properties::$prefix . $tableName);
}
}
if( $status !== NULL )
{
return $this->getLang[$message];
}
return false;
}
/**
* Backup Table
*
* @param mixed $tables
* @param string $fileName
* @param string $path
*
* @return string
*/
public function backup($tables, $fileName, $path)
{
if( $path === STORAGE_DIR )
{
$path .= 'DatabaseBackup'; // @codeCoverageIgnore
}
$eol = EOL;
if( $tables === '*' )
{
$tables = [];
$resultArray = $this->differentConnection->query('SHOW TABLES')->resultArray();
foreach( $resultArray as $key => $val )
{
$tables[] = current($val); // @codeCoverageIgnore
}
}
else
{
$tables = ( is_array($tables) )
? $tables
: explode(',',$tables);
}
$return = '';
foreach( $tables as $table )
{
if( ! empty(Properties::$prefix) && ! strstr($table, Properties::$prefix) )
{
$table = Properties::$prefix.$table; // @codeCoverageIgnore
}
$return .= 'DROP TABLE IF EXISTS '.$table.';';
$fetchRow = $this->differentConnection->query('SHOW CREATE TABLE '.$table)->fetchRow();
if( ! $fetchRow )
{
continue;
}
// @codeCoverageIgnoreStart
$fetchResult = $this->differentConnection->query('SELECT * FROM '.$table)->result();
$return .= $eol.$eol.$fetchRow[1].";".$eol.$eol;
if( ! empty($fetchResult) ) foreach( $fetchResult as $row )
{
$return.= 'INSERT INTO '.$table.' VALUES(';
foreach( $row as $k => $v )
{
$v = preg_replace("/\n/","\\n", $v ?? '');
if( is_numeric($v) )
{
$return.= $v;
}
else if( empty($v) )
{
$return.= 'NULL';
}
else
{
$return.= '"' . addslashes(stripslashes($v)) .'"' ;
}
$return.= ', ';
}
$return = rtrim(trim($return), ', ');
$return .= ");".$eol;
}
$return .= $eol.$eol.$eol;
// @codeCoverageIgnoreEnd
}
if( ! trim($return) )
{
return false;
}
if( empty($fileName) )
{
$fileName = 'db-backup-'.time().'-'.(md5(implode(',',$tables))).'.sql';
}
if( ! is_dir($path) )
{
mkdir($path); // @codeCoverageIgnore
}
file_put_contents(Base::suffix($path) . $fileName, $return);
return $this->getLang['backupTablesSuccess'];
}
/**
* Import File
*
* @param string $file
*
* @return bool
*/
public function import(string $file)
{
if( is_file($file) )
{
return $this->differentConnection->multiQuery(file_get_contents($file));
}
return false;
}
}
@@ -0,0 +1,21 @@
<?php namespace ZN\Database\Exception;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Exception;
class ConnectionErrorException extends Exception
{
const lang =
[
'tr' => 'Veritabanı bağlantısı sağlanamadı! Lütfen bağlantı ayarlarınızı kontrol edin! [%]',
'en' => 'Database connection error! Please check your connection settings! [%]'
];
}
@@ -0,0 +1,17 @@
<?php namespace ZN\Database\Exception;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Exception;
class DatabaseErrorException extends Exception
{
}
@@ -0,0 +1,17 @@
<?php namespace ZN\Database\Exception;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Exception;
class DuplicateCheckException extends Exception
{
}
@@ -0,0 +1,21 @@
<?php namespace ZN\Database\Exception;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Exception;
class InvalidArgumentException extends Exception
{
const lang =
[
'tr' => '[%] yöntemini parametresiz kullanamazsınız!',
'en' => 'You cannot use the [%] method without parameters!'
];
}
@@ -0,0 +1,17 @@
<?php namespace ZN\Database\Exception;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Exception;
class NoSearchException extends Exception
{
}
@@ -0,0 +1,17 @@
<?php namespace ZN\Database\Exception;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Exception;
class NoTableException extends Exception
{
}
@@ -0,0 +1,21 @@
<?php namespace ZN\Database\Exception;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Exception;
class OrderByInvalidSecondArgumentException extends Exception
{
const lang =
[
'tr' => 'string $type parametresi "asc" veya "desc" değerlerini alabilir!',
'en' => 'string $type parameter can take "asc" or "desc" values!'
];
}
@@ -0,0 +1,25 @@
<?php namespace ZN\Database\Exception;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Exception;
class UnconditionalException extends Exception
{
const lang =
[
'placement' =>
[
'#' => '[DB::where(mixed $column, string $value [, string $condition = "and"])]'
],
'tr' => 'Koşulsuz silme işlemi gerçekleştiremezsiniz! Lütfen # ile koşul tanımlayın.',
'en' => 'You can not perform unconditional deletion! Please define the condition with #.'
];
}
+724
View File
@@ -0,0 +1,724 @@
<?php namespace ZN\Database;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Base;
use ZN\Config;
use ZN\Support;
use ZN\Datatype;
use ZN\Singleton;
class GrandModel
{
/**
* Table name
*
* @var string
*/
protected $grandTable = '';
/**
* Keep connection
*
* @var resource
*/
protected $connect;
/**
* Keep connection for DBTool library
*
* @var resource
*/
protected $connectTool;
/**
* Keep connection for DBForge library
*
* @var resource
*/
protected $connectForge;
/**
* Get list tables
*
* @var array
*/
protected $tables;
/**
* Process status
*
* @var string
*/
protected $status;
/**
* Get query result
*
* @var object
*/
protected $get;
/**
* Keep options
*
* @var array
*/
protected $options = [];
/**
* Table prefix
*
* @var string
*/
protected $prefix;
/**
* String query
*
* @var string
*/
protected $stringQuery;
/**
* Error
*
* @var string
*/
protected $error;
/**
* Magic constructor
*
* @codeCoverageIgnore
*/
public function __construct()
{
# Get database connections
$this->getDatabaseConnections();
# Get active table name
$this->setGrandTableName();
}
/**
* Magic call
*
* @param string $method
* @param array $parameters
*
* @param mixed
*/
public function __call($method, $parameters)
{
# If it is a valid transaction type.
if( $this->isCallColumnTransaction($method, $transaction) )
{
return $this->callColumnProcess($method, $parameters, $transaction);
}
else if( $this->isDatabaseCallMethod($method, $parameters) !== false )
{
return $this;
}
else
{
return $this->callColumnForge($method, $parameters);
}
}
/**
* Data insert
*
* @param mixed $data = NULL
*
* @return bool
*/
public function insert($data = NULL) : bool
{
$this->postGetExpression($table, $data);
return $this->returnQuery($this->connect->insert($table, $data));
}
/**
* Insert csv
*
* @param string $file
*
* @return bool
*/
public function insertCSV(string $file) : bool
{
return $this->connect->insertCSV($this->grandTable, $file);
}
/**
* Last insert id
*
* @param void
*
* @return int
*/
public function insertID() : int
{
return $this->connect->insertID();
}
/**
* Last hash id
*
* @param void
*
* @return int
*
* @codeCoverageIgnore
*/
public function hashId()
{
return $this->connect->hashId();
}
/**
* Is exists value into table
*
* @param string $column
* @param string $value
*
* @return bool
*/
public function isExists(string $column, string $value) : bool
{
return $this->connect->isExists($this->grandTable, $column, $value);
}
/**
* Update data
*
* @param mixed $data = NULL
* @param string $column = NULL
* @param string $value = NULL
*
* @return bool
*/
public function update($data = NULL, ?string $column = NULL, ?string $value = NULL) : bool
{
$this->postGetExpression($table, $data);
if( $column !== NULL )
{
$this->connect->where($column, $value);
}
return $this->returnQuery($this->connect->update($table, $data));
}
/**
* Delete data
*
* @param string $column = NULL
* @param string $value = NULL
*
* @return bool
*/
public function delete(?string $column = NULL, ?string $value = NULL) : bool
{
if( $column !== NULL )
{
$this->connect->where($column, $value);
}
return $this->returnQuery($this->connect->delete($this->grandTable));
}
/**
* Get table object. It is like using DB::get($table)
*
* @return object
*/
public function get()
{
return $this->connect->get($this->grandTable);
}
/**
* protected db get
*
* @param void
*
* @return object
*/
protected function getInstance()
{
return $this->get = $this->get();
}
/**
* Get columns
*
* @param void
*
* @return array
*/
public function columns() : array
{
return $this->returnQuery($this->getInstance()->columns());
}
/**
* Get total columns
*
* @param void
*
* @return int
*/
public function totalColumns() : int
{
return $this->returnQuery($this->getInstance()->totalColumns());
}
/**
* Get row
*
* @param mixed $printable = false - options[bool|index]
*
* @return object
*/
public function row($printable = false)
{
return $this->returnQuery($this->getInstance()->row($printable));
}
/**
* Get result
*
* @param string $type = 'object' - options[object|array|json]
*/
public function result(string $type = 'object')
{
return $this->returnQuery($this->getInstance()->result($type));
}
/**
* Increment columns value
*
* @param mixed $columns
* @param int $increment = 1
*
* @return bool
*/
public function increment($columns, int $increment = 1) : bool
{
return $this->returnQuery($this->connect->increment($this->grandTable, $columns, $increment));
}
/**
* Decrement columns value
*
* @param mixed $columns
* @param int $decrement = 1
*
* @return bool
*/
public function decrement($columns, int $decrement = 1) : bool
{
return $this->returnQuery($this->connect->decrement($this->grandTable, $columns, $decrement));
}
/**
* Status table
*
* @param string $type = 'row' - options[row|result]
*
* @return mixed
*/
public function status(string $type = 'row')
{
return $this->returnQuery($this->connect->status($this->grandTable)->$type());
}
/**
* Get total rows
*
* @param bool $status = false
*
* @return int
*/
public function totalRows(bool $status = false) : int
{
return $this->returnQuery($this->getCurrent()->totalRows($status));
}
/**
* Get pagination
*
* @param string $url = NULL
* @param array $settings = []
* @param bool $output = true
*
* @return mixed
*/
public function pagination(?string $url = NULL, array $settings = [], bool $output = true)
{
return $this->getCurrent()->pagination($url, $settings, $output);
}
/**
* Create table
*
* @param mixed $data
* @param mxeid $extra = NULL
*
* @return bool
*/
public function create($data = NULL, $extra = NULL) : bool
{
$this->status = 'create';
if( ! empty($this->options) )
{
$extra = $data;
$data = $this->options;
$this->options = [];
}
return $this->returnQuery($this->connectForge->createTable($this->grandTable, $data, $extra), 'forge');
}
/**
* Truncate table
*
* @param void
*
* @return bool
*/
public function truncate() : bool
{
return $this->returnQuery($this->connectForge->truncate($this->grandTable), 'forge');
}
/**
* Add column
*
* @param array $columns
*
* @return bool
*/
public function add() : bool
{
$columns = $this->options;
$this->options = [];
return $this->returnQuery($this->connectForge->addColumn($this->grandTable, $columns), 'forge');
}
/**
* Drop column
*
* @param array $column
*
* @return bool
*/
public function drop() : bool
{
$columns = $this->options;
$this->options = [];
return $this->returnQuery($this->connectForge->dropColumn($this->grandTable, array_keys($columns)), 'forge');
}
/**
* Modify column
*
* @param array $columns
*
* @return bool
*/
public function modify() : bool
{
$columns = $this->options;
$this->options = [];
return $this->returnQuery($this->connectForge->modifyColumn($this->grandTable, $columns), 'forge');
}
/**
* Rename column
*
* @param array $column
*
* @return bool
*/
public function rename() : bool
{
$columns = $this->options;
$this->options = [];
return $this->returnQuery($this->connectForge->renameColumn($this->grandTable, $columns), 'forge');
}
/**
* Optimize table
*
* @param void
*
* @return string
*/
public function optimize() : string
{
return $this->returnQuery($this->connectTool->optimizeTables($this->grandTable), 'tool');
}
/**
* Repair table
*
* @param void
*
* @return string
*/
public function repair() : string
{
return $this->returnQuery($this->connectTool->repairTables($this->grandTable), 'tool');
}
/**
* Backup table
*
* @param string $fileName = NULL
* @param string $path = STORAGE_DIR
*
* @return string
*/
public function backup(?string $fileName = NULL, string $path = STORAGE_DIR) : string
{
return $this->returnQuery($this->connectTool->backup($this->grandTable, $fileName, $path), 'tool');
}
/**
* Get error
*
* @param void
*
* @return mixed
*/
public function error()
{
$error = $this->error ?: false;
$this->error = NULL;
return $error;
}
/**
* Get string query
*
* @param void
*
* @return mixed
*/
public function stringQuery()
{
$query = $this->stringQuery ?: false;
$this->stringQuery = NULL;
return $query;
}
/**
* Protected get database connections
*/
protected function getDatabaseConnections()
{
$staticConnection = defined('static::connection') ? static::connection : NULL;
$this->connect = Singleton::class('ZN\Database\DB')->differentConnection($staticConnection);
$this->connectTool = Singleton::class('ZN\Database\DBTool')->differentConnection($staticConnection);
$this->connectForge = Singleton::class('ZN\Database\DBForge')->differentConnection($staticConnection);
$this->tables = $this->connectTool->listTables();
$this->prefix = $staticConnection['prefix'] ?? Config::database('database')['prefix'];
}
/**
* Protected set grand table name
*/
protected function setGrandTableName()
{
if( defined('static::table') )
{
$this->grandTable = static::table;
}
else
{
$this->grandTable = $this->getGrandTableName(); // @codeCoverageIgnore
}
}
/**
* Protected get grand table name
*/
protected function getGrandTableName()
{
return Base::removeSuffix
(
Base::removeSuffix
(
Base::removePrefix(Datatype::divide(get_called_class(), '\\', -1), INTERNAL_ACCESS),
'Grand'
),
'Vision'
);
}
/**
* protected post get expressions
*
* @param string &$table
* @param array &$data
*
* @return void
*/
protected function postGetExpression(&$table, &$data)
{
$table = $this->grandTable;
if( is_string($data) )
{
$table = $data . ':' . $table;
$data = [];
}
$data = $data ?: $this->options;
$this->options = [];
}
/**
* protected call column process - 5.6.2|5.7.6.6[update]
*
* @param string $method
* @param array $params
* @param string $type
*
* @return mixed
*/
protected function callColumnProcess($method, $params, $type)
{
$func = $type;
$col = substr($method, strlen($type));
if( $func === 'update' )
{
// @codeCoverageIgnoreStart
if( ! empty($this->options) )
{
$params[1] = $params[0] ?? NULL;
$params[0] = $this->options;
$this->options = [];
}
if( ! is_array($params[0] ?? NULL) || ! is_scalar($params[1] ?? []) )
{
throw new Exception\InvalidArgumentException(NULL, get_called_class() . '::update(array $data, scalar $value)');
}
// @codeCoverageIgnoreEnd
return $this->where($col, $params[1])->$func($params[0]);
}
if( ! is_scalar($params[0] ?? []) )
{
throw new Exception\InvalidArgumentException(NULL, get_called_class() . '::' . $method . '(scalar $value)'); // @codeCoverageIgnore
}
return $this->where($col, $params[0])->$func();
}
/**
* Protected call column forge
*/
protected function callColumnForge($method, $parameters)
{
# 5.3.7[added]
$param = $parameters[0] ?? NULL;
$this->options[$method] = $param;
return $this;
}
/**
* Protected is database call method
*/
protected function isDatabaseCallMethod($method, $parameters)
{
if( method_exists($this->connect, $method) )
{
return $this->connect->$method(...$parameters);
}
else if( method_exists($this->connectForge, $method) )
{
return $this->connectForge->$method(...$parameters); // @codeCoverageIgnore
}
else if( method_exists($this->connectTool, $method) )
{
return $this->connectTool->$method(...$parameters); // @codeCoverageIgnore
}
return false;
}
/**
* Protected is call column process
*/
protected function isCallColumnTransaction($method, &$selectTransaction)
{
if( preg_match('/^(row|result|update|delete)/', $method, $match) )
{
$selectTransaction = $match[1];
}
return $selectTransaction ?? NULL;
}
/**
* protected return query
*/
protected function returnQuery($process, $fix = '')
{
$this->stringQuery = $this->{'connect' . ucfirst($fix)}->stringQuery();
$this->error = $this->{'connect' . ucfirst($fix)}->error();
return $process;
}
/**
* Protected get current
*/
protected function getCurrent()
{
if( ! empty($this->get) )
{
$get = $this->get;
}
else
{
$get = $this->getInstance(); // @codeCoverageIgnore
}
return $get;
}
}
+780
View File
@@ -0,0 +1,780 @@
<?php namespace ZN\Database;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Config;
use MongoDB\BSON\Regex;
use MongoDB\Driver\Query;
use MongoDB\Driver\Session;
use MongoDB\Driver\Manager;
use MongoDB\Driver\Command;
use MongoDB\Driver\BulkWrite;
use MongoDB\Driver\ReadConcern;
use MongoDB\Driver\WriteConcern;
use MongoDB\Driver\ReadPreference;
use MongoDB\Driver\Exception\RuntimeException;
use ZN\Database\Exception\OrderByInvalidSecondArgumentException;
/**
* @codeCoverageIgnore
*/
class MDB implements MDBInterface
{
/**
* Keeps database
*/
protected $database;
/**
* Keeps manager
*
* @var Manager
*/
protected $manager;
/**
* Keeps host
*
* @var string
*/
protected $host = '127.0.0.1';
/**
* Keeps options
*
* @var array
*/
protected $options = [];
/**
* Keeps executable
*
* @var array
*/
protected $executable = [];
/**
* Keeps filters
*
* @var array
*/
protected $filters = [];
/**
* Keeps config
*
* @var array
*/
protected $config = [];
/**
* Keeps result
*
* @var array
*/
protected $result;
/**
* Keeps error
*
* @var string
*/
protected $error = '';
/**
* Magic constructor method.
*
* @param array $config
*/
public function __construct($config = [])
{
if( $config !== NULL )
{
$config = $config ?: Config::get('Database')['mongodb'] ?? [];
$this->manager = new Manager
(
'mongodb://' . $config['dns'] . '/',
$config['options'] ?? [],
$config['driverOptions'] ?? []
);
$this->database = $config['database'] ?? 'test';
}
}
/**
* Executable
*
* @param array $options
*/
public function executable($options)
{
$this->executable = $config;
return $this;
}
/**
* MongoDB\Driver\WriteConcern
*
* @return WriteConcern
*/
public static function writeConcern(...$parameters)
{
return new WriteConcern(...$parameters);
}
/**
* MongoDB\Driver\ReadPreference
*
* @return ReadPreference
*/
public static function readPreference(...$parameters)
{
return new ReadPreference(...$parameters);
}
/**
* MongoDB\Driver\ReadConcern
*
* @return ReadConcern
*/
public static function readConcern(...$parameters)
{
return new ReadConcern(...$parameters);
}
/**
* MongoDB\Driver\Session
*
* @return Session
*/
public static function session(...$parameters)
{
return new Session(...$parameters);
}
/**
* New
*
* @param array $config
*/
public static function new(array $config)
{
return new self($config);
}
/**
* Insert
*
* @param string $table
* @param array $datas
*
* @return bool
*/
public function insert(string $table, array $datas) : bool
{
$bulk = new BulkWrite;
if( is_array($datas[0]) )
{
foreach( $datas as $data )
{
$this->setAutoIncrement($table, $data);
$bulk->insert($data);
}
}
else
{
$this->setAutoIncrement($table, $datas);
$bulk->insert($datas);
}
return (bool) $this->operation($table, $bulk)->getInsertedCount();
}
/**
* Delete
*
* @param string $table
*
* @return bool
*/
public function delete(string $table) : bool
{
$bulk = new BulkWrite;
$bulk->delete($this->filters);
return (bool) $this->operation($table, $bulk)->getDeletedCount();
}
/**
* Update
*
* @param string $table
* @param array $datas
*
* @return bool
*/
public function update(string $table, array $datas = []) : bool
{
$bulk = new BulkWrite;
$this->options['multi'] = true;
$bulk->update($this->filters, ['$set' => $datas], $this->options);
return (bool) $this->operation($table, $bulk)->getModifiedCount();
}
/**
* Where Regex
*
* @param string $key
* @param scalar $value
* @param string $flags = ''
*
* @return self
*/
public function whereRegex(string $key, $value, string $flags = '')
{
return $this->filter($key, new Regex($value, $flags));
}
/**
* Where
*
* @param string $key
* @param scalar $value
*
* @return self
*/
public function where(string $key, $value)
{
return $this->filter($key, $value);
}
/**
* Upsert
*
* @return self
*/
public function upsert()
{
return $this->option('upsert', true);
}
/**
* Option
*
* @param string $key
* @param scalar $value
*
* @return self
*/
public function option(string $key, $value)
{
$this->options[$key] = $value;
return $this;
}
/**
* Option
*
* @param string $key
* @param scalar $value
*
* @return self
*/
public function filter(string $key, $value)
{
$this->filters[$key] = $value;
return $this;
}
/**
* Total Rows
*
* @param int
*/
public function totalRows() : int
{
return count($this->result());
}
/**
* Limit
*
* Usage - 1
*
* @param int $limit
*
* Usage - 2
*
* @param int $skip
* @param int $limit
*
* @return self
*/
public function limit(int $skip, ?int $limit = NULL)
{
if( $limit === NULL )
{
$this->options['limit'] = $skip;
}
else
{
$this->options['limit'] = $limit;
$this->options['skip' ] = $skip;
}
return $this;
}
/**
* Order By
*
* @param string $column
* @param string $type = 'asc'
*
* @return self
*/
public function orderBy(string $column, string $type = 'asc')
{
$type = strtolower($type);
$types = ['asc' => 1, 'desc' => -1];
if( ! isset($types[$type]) )
{
throw new OrderByInvalidSecondArgumentException;
}
$this->options['sort'] = [$column => $types[$type]];
return $this;
}
/**
* Get
*
* @param string $table
*
* @return self
*/
public function get(string $table)
{
$execute = $this->execute($table);
return (new self(NULL))->complete($execute->toArray());
}
/**
* Result
*
* @return array|object
*/
public function result()
{
return $this->result ?? [];
}
/**
* Row
*
* @param int|bool $printable = 0
*
* @return object|false
*/
public function row($printable = 0)
{
$result = $this->result();
if( $printable < 0 )
{
$index = count($result) + $printable;
return isset($result[$index]) ? (object) $result[$index] : false;
}
else
{
if( $printable === true )
{
return current((array) $result[0] ?? []);
}
return isset($result[$printable]) ? (object) $result[$printable] : false;
}
}
/**
* Create Index
*
* @param string $table
* @param array $indexes
*
* @return bool
*/
public function createIndex(string $table, array $indexes) : bool
{
$generateIndexses = [];
foreach( $indexes as $key => $value )
{
$generateIndexses[] = ['name' => $key, 'key' => [$key => $value], 'ns' => $this->collect($table)];
}
$index = $this->executeWriteCommand(['createIndexes' => $table, 'indexes' => $generateIndexses]);
return ! $this->error = $index->toArray()[0]->note ?? false;
}
/**
* Drop Index
*
* @param string $table
* @param string $indexName
*
* @return bool
*/
public function dropIndex(string $table, string $indexName) : bool
{
try
{
$this->executeWriteCommand(['dropIndexes' => $table, 'index' => $indexName]);
return true;
}
catch( RuntimeException $e )
{
$this->error = $e->getMessage();
return false;
}
}
/**
* Drop/Truncate
*
* @param string $table
*
* @return bool
*/
public function drop(string $table) : bool
{
return $this->truncate($table);
}
/**
* Create
*
* @param string $table
* @param array $options = []
*
* @return bool
*/
public function create(string $table, array $options = []) : bool
{
try
{
$command = ['create' => $table];
foreach( ['autoIndexId', 'capped', 'flags', 'max', 'maxTimeMS', 'size', 'validationAction', 'validationLevel'] as $option )
{
if( isset($options[$option]) )
{
$command[$option] = $options[$option];
}
}
foreach( ['collation', 'indexOptionDefaults', 'storageEngine', 'validator'] as $option )
{
if( isset($options[$option]) )
{
$command[$option] = (object) $options[$option];
}
}
$drop = $this->executeWriteCommand($command);
return true;
}
catch( RuntimeException $e )
{
$this->error = $e->getMessage();
return false;
}
}
/**
* Create Auto Increment
*
* @param string $table
* @param string $column
*/
public function createAutoIncrement(string $table, string $column)
{
$table = $this->getIndexCollectionName($table);
if( ! $this->get($table)->row() )
{
return $this->insert($table, [$column => 1]);
}
return false;
}
/**
* protected index get index collection name
*/
protected function getIndexCollectionName(string $table)
{
return $table . 'Indexes';
}
/**
* Truncate/Drop
*
* @param string $table
*
* @return bool
*/
public function truncate(string $table) : bool
{
try
{
$drop = $this->executeWriteCommand(['drop' => $table]);
if( $this->isAutoIncrement($table) )
{
$this->executeWriteCommand(['drop' => $table]);
}
return true;
}
catch( RuntimeException $e )
{
$this->error = $e->getMessage();
return false;
}
}
/**
* Databases
*
* @return array
*/
public function databases() : array
{
$databases = $this->executeReadCommand('admin', ['listDatabases' => 1]);
$databases = $databases->toArray();
$returnDatabases = [];
foreach( $databases[0]['databases'] as $database )
{
$returnDatabases[] = $database['name'];
}
return $returnDatabases;
}
/**
* Indexes
*
* @return array
*/
public function indexes(string $table) : array
{
$indexes = $this->executeReadCommand($this->database, ['listIndexes' => $table]);
$indexes = $indexes->toArray();
$returnIndexes = [];
foreach( $indexes as $index )
{
$returnIndexes[] = ['key' => key((array) $index['key']), 'name' => $index['name'], 'value' => current((array) $index['key'])];
}
return $returnIndexes;
}
/**
* Tables/Collections
*
* @return array
*/
public function tables() : array
{
return $this->collections();
}
/**
* Collections/Tables
*
* @return array
*/
public function collections() : array
{
$collections = $this->executeReadCommand($this->database, ['listCollections' => 1]);
$collections = $collections->toArray();
$returnCollections = [];
foreach( $collections as $collection )
{
$returnCollections[] = $collection['name'];
}
return $returnCollections;
}
/**
* Error
*
* @return string
*/
public function error() : string
{
return $this->error;
}
/**
* protected is auto increment
*/
protected function isAutoIncrement(string &$table)
{
return in_array($table = $this->getIndexCollectionName($table), $this->collections());
}
/**
* protected set auto increment
*/
protected function setAutoIncrement(string $table, &$data)
{
if( $this->isAutoIncrement($table) )
{
$get = $this->get($table);
$row = $get->row();
$id = key(array_reverse((array) $row));
$data = array_merge([$id => $get->totalRows()], $data);
$this->insert($table, [$id => 1]);
}
}
/**
* protected complete
*/
protected function complete($result)
{
$this->result = $result;
return $this;
}
/**
* protected execute read command
*/
protected function executeReadCommand(string $database, array $command)
{
$query = $this->manager->executeReadCommand($database, new Command($command), $this->executable);
$query->setTypeMap(['root' => 'array', 'document' => 'array']);
$this->defaultExecuteReadCommand();
return $query;
}
/**
* protected execute write command
*/
protected function executeWriteCommand(array $command)
{
$return = $this->manager->executeWriteCommand($this->database, new Command($command), $this->executable);
$this->defaultExecuteWriteCommand();
return $return;
}
/**
* protected operation
*/
protected function operation(string $table, $bulk)
{
$return = $this->manager->executeBulkWrite($this->collect($table), $bulk, $this->executable);
$this->defaultExecute();
return $return;
}
/**
* protected execute
*/
protected function execute(string $table)
{
$return = $this->manager->executeQuery($this->collect($table), new Query($this->filters, $this->options), $this->executable);
$this->defaultExecute();
return $return;
}
/**
* protected collect
*/
protected function collect(string $collection)
{
return $this->database . '.' . $collection;
}
/**
* protected default execute read command
*/
protected function defaultExecuteReadCommand()
{
$this->executable = [];
}
/**
* protected default execute write command
*/
protected function defaultExecuteWriteCommand()
{
$this->options = [];
$this->executable = [];
}
/**
* protected default
*/
protected function defaultExecute()
{
$this->filters = [];
$this->options = [];
$this->executable = [];
}
}
+281
View File
@@ -0,0 +1,281 @@
<?php namespace ZN\Database;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
interface MDBInterface
{
/**
* Executable
*
* @param array $options
*/
public function executable($options);
/**
* MongoDB\Driver\WriteConcern
*
* @return WriteConcern
*/
public static function writeConcern(...$parameters);
/**
* MongoDB\Driver\ReadPreference
*
* @return ReadPreference
*/
public static function readPreference(...$parameters);
/**
* MongoDB\Driver\ReadConcern
*
* @return ReadConcern
*/
public static function readConcern(...$parameters);
/**
* MongoDB\Driver\Session
*
* @return Session
*/
public static function session(...$parameters);
/**
* New
*
* @param array $config
*/
public static function new(array $config);
/**
* Insert
*
* @param string $table
* @param array $datas
*
* @return bool
*/
public function insert(string $table, array $datas) : bool;
/**
* Delete
*
* @param string $table
*
* @return bool
*/
public function delete(string $table) : bool;
/**
* Update
*
* @param string $table
* @param array $datas
*
* @return bool
*/
public function update(string $table, array $datas = []) : bool;
/**
* Where Regex
*
* @param string $key
* @param scalar $value
* @param string $flags = ''
*
* @return self
*/
public function whereRegex(string $key, $value, string $flags = '');
/**
* Where
*
* @param string $key
* @param scalar $value
*
* @return self
*/
public function where(string $key, $value);
/**
* Upsert
*
* @return self
*/
public function upsert();
/**
* Option
*
* @param string $key
* @param scalar $value
*
* @return self
*/
public function option(string $key, $value);
/**
* Filter
*
* @param string $key
* @param scalar $value
*
* @return self
*/
public function filter(string $key, $value);
/**
* Total Rows
*
* @param int
*/
public function totalRows() : int;
/**
* Limit
*
* Usage - 1
*
* @param int $limit
*
* Usage - 2
*
* @param int $skip
* @param int $limit
*
* @return self
*/
public function limit(int $skip, ?int $limit = NULL);
/**
* Order By
*
* @param string $column
* @param string $type = 'asc'
*
* @return self
*/
public function orderBy(string $column, string $type = 'asc');
/**
* Get
*
* @param string $table
*
* @return self
*/
public function get(string $table);
/**
* Result
*
* @return array|object
*/
public function result();
/**
* Row
*
* @param int|bool $printable = 0
*
* @return object|false
*/
public function row($printable = 0);
/**
* Create Index
*
* @param string $table
* @param array $indexes
*
* @return bool
*/
public function createIndex(string $table, array $indexes) : bool;
/**
* Drop Index
*
* @param string $table
* @param string $indexName
*
* @return bool
*/
public function dropIndex(string $table, string $indexName) : bool;
/**
* Create
*
* @param string $table
* @param array $options = []
*
* @return bool
*/
public function create(string $table, array $options = []) : bool;
/**
* Create Auto Increment
*
* @param string $table
* @param string $column
*/
public function createAutoIncrement(string $table, string $column);
/**
* Drop/Truncate
*
* @param string $table
*
* @return bool
*/
public function drop(string $table) : bool;
/**
* Truncate/Drop
*
* @param string $table
*
* @return bool
*/
public function truncate(string $table) : bool;
/**
* Databases
*
* @return array
*/
public function databases() : array;
/**
* Indexes
*
* @return array
*/
public function indexes(string $table) : array;
/**
* Tables/Collections
*
* @return array
*/
public function tables() : array;
/**
* Collections/Tables
*
* @return array
*/
public function collections() : array;
/**
* Error
*
* @return string
*/
public function error() : string;
}
+532
View File
@@ -0,0 +1,532 @@
<?php namespace ZN\Database;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Base;
use ZN\Config;
use ZN\Singleton;
use ZN\Filesystem;
class Migration implements MigrationInterface
{
/**
* Migrations path Models/Migrations/
*
* @var string
*/
private $path = MODELS_DIR . 'Migrations/';
/**
* Keeps database config
*
* @var array
*/
private $config;
/**
* Keeps class fix
*
* @var string
*/
private $classFix = INTERNAL_ACCESS . 'Migrate';
/**
* Keeps migrate table name
*
* @var string
*/
private $migrateTableName;
/**
* Keeps version directory path
*
* @var string
*/
private $versionDir = 'Version/';
/**
* Keeps database classeses
*
* @var object
*/
private $db, $forge;
/**
* Magic constructor
*
* @param void
*
* @return void
*/
public function __construct()
{
$this->config = Config::get('Database');
if( ! is_dir($this->path) )
{
mkdir($this->path, 0755);
}
$this->db = Singleton::class('ZN\Database\DB');
$this->forge = Singleton::class('ZN\Database\DBForge');
$this->migrateTableName = defined('static::table') ? static::table : '';
$this->createMigrationTableIfNotExists();
}
/**
* Up all migrations
*
* @param string ...$migrations
*
* @return bool
*/
public function upAll(string ...$migrations) : bool
{
$this->runMigrateAll('up', $migrations);
return true;
}
/**
* Down all migrations
*
* @param string ...$migrations
*
* @return bool
*/
public function downAll(string ...$migrations) : bool
{
$this->runMigrateAll('down', $migrations);
return true;
}
/**
* Create table
*
* @param array $data
*
* @return bool
*/
public function createTable(array $data) : bool
{
$this->forge->createTable($this->getTableName(), $data);
return $this->saveActionQuery(__FUNCTION__);
}
/**
* Drop table
*
* @param void
*
* @return bool
*/
public function dropTable() : bool
{
$this->forge->dropTable($this->getTableName());
return $this->saveActionQuery(__FUNCTION__);
}
/**
* Add column
*
* @param array $column
*
* @return bool
*/
public function addColumn(array $column) : bool
{
$this->forge->addColumn($this->getTableName(), $column);
return $this->saveActionQuery(__FUNCTION__);
}
/**
* Drop column
*
* @param mixed $column
*
* @return bool
*/
public function dropColumn($column) : bool
{
$this->forge->dropColumn($this->getTableName(), $column);
return $this->saveActionQuery(__FUNCTION__);
}
/**
* Modify column
*
* @param array $column
*
* @param bool
*/
public function modifyColumn(array $column) : bool
{
$this->forge->modifyColumn($this->getTableName(), $column);
return $this->saveActionQuery(__FUNCTION__);
}
/**
* Rename column
*
* @param array $column
*
* @return bool
*/
public function renameColumn(array $column) : bool
{
$this->forge->renameColumn($this->getTableName(), $column);
return $this->saveActionQuery(__FUNCTION__);
}
/**
* Truncate table
*
* @param void
*
* @return bool
*/
public function truncate() : bool
{
$this->forge->truncate($this->getTableName());
return $this->saveActionQuery(__FUNCTION__);
}
/**
* Sets migration path
*
* @param string $path = NULL
*
* @return Migration
*/
public function path(?string $path = NULL) : Migration
{
$this->path = Base::suffix($path);
return $this;
}
/**
* Create migration
*
* @param string $name
* @param int $version = 0
*
* @return bool
*/
public function create(string $name, int $ver = 0) : bool
{
if( $version = $this->getValidVersionNumber($ver) )
{
$this->createVersionDirectoryIfNotExists($name);
$file = $this->getVersionFile($name, $version);
$name .= $version;
}
else
{
$file = $this->getWithoutVersionFile($name);
}
return $this->generateMigrateFileIfNotExists($name, $file);
}
/**
* Delete migration
*
* @param string $name
* @param int $version = 0
*
* @return bool
*/
public function delete(string $name, int $ver = 0) : bool
{
if( $version = $this->getValidVersionNumber($ver) )
{
$file = $this->getVersionFile($name, $version);
$this->deleteAllVersionDirectoryIfExists($name, $ver);
}
else
{
$file = $this->getWithoutVersionFile($name);
}
return $this->deleteMigrateFileIfExists($file);
}
/**
* Delete all migrations
*
* @param void
*
* @return bool
*/
public function deleteAll() : bool
{
if( is_dir($this->path) )
{
return Filesystem::deleteFolder($this->path);
}
else
{
return false;
}
}
/**
* Selects migration version
*
* @param int $version = 0
*
* @return object
*/
public function version(int $version = 0)
{
if( empty($this->migrateTableName) )
{
return false;
}
// @codeCoverageIgnoreStart
$name = $this->classFix.$this->getTableName();
if( $version <= 0 )
{
return Singleton::class($name);
}
$name .= $this->getValidVersionNumber($version);
return Singleton::class($name);
// @codeCoverageIgnoreEnd
}
/**
* Protected delete migrate file if exists
*/
protected function deleteMigrateFileIfExists($file)
{
if( is_file($file) )
{
return unlink($file);
}
return false;
}
/**
* Protected generate migrate file if not exists
*/
protected function generateMigrateFileIfNotExists($name, $file)
{
if( ! is_file($file) )
{
return $this->createMigrateFile($name, $file);
}
return false; // @codeCoverageIgnore
}
/**
* Protected delete all version directory if exists
*/
protected function deleteAllVersionDirectoryIfExists($name, $version)
{
$getVersionDirectory = $this->getVersionDirectory($name);
if( $version === 'all' && is_dir($getVersionDirectory) )
{
Filesystem::deleteFolder($getVersionDirectory); // @codeCoverageIgnore
}
}
/**
* Protected create version directory if not exists
*/
protected function createVersionDirectoryIfNotExists($name)
{
if( ! is_dir($getVersionDirectory = $this->getVersionDirectory($name)) )
{
mkdir($getVersionDirectory);
}
}
/**
* Protected get file without version
*/
protected function getWithoutVersionFile($name)
{
return $this->path . Base::suffix($name, '.php');
}
/**
* Protected get version file
*/
protected function getVersionFile($name, $version)
{
return $this->getVersionDirectory($name) . Base::suffix($version, '.php');
}
/**
* Protected create migrate
*/
protected function getVersionDirectory($name)
{
return $this->path . $name . $this->versionDir;
}
/**
* Protected save action query
*/
protected function saveActionQuery($type)
{
if( ! $this->forge->error() )
{
return $this->db->insert($this->config['migration']['table'],
[
'name' => $this->getTableName(),
'type' => $type ?: 'noAction',
'version' => $this->getVersionNumberFromTableName(),
'date' => date('Ymdhis')
]);
}
return false;
}
/**
* protected create
*
* @param void
*
* @return void
*/
protected function createMigrationTableIfNotExists()
{
$table = $this->config['database']['prefix'] . $this->config['migration']['table'];
$this->forge->createTable('IF NOT EXISTS '.$table, array
(
'name' => [$this->db->varchar(512), $this->db->notNull()],
'type' => [$this->db->varchar(256), $this->db->notNull()],
'version' => [$this->db->varchar(3), $this->db->notNull()],
'date' => [$this->db->varchar(15), $this->db->notNull()]
));
}
/**
* Get table name
*
* @param void
*
* @return string
*/
protected function getTableName()
{
$table = preg_replace('/[0-9][0-9][0-9]/', '', $this->migrateTableName);
return str_replace($this->classFix, '', $table);
}
/**
* Protected get version number from table name
*/
protected function getVersionNumberFromTableName()
{
preg_match('(\w+([0-9][0-9][0-9]))', $this->migrateTableName, $match);
return $match[1] ?? '000';
}
/**
* Protected get valid version number
*/
protected function getValidVersionNumber($numeric)
{
$length = strlen((string) $numeric);
if( (int) $numeric > 999 || (int) $numeric < 0 )
{
return false; // @codeCoverageIgnore
}
switch( $length )
{
case 1 : $numeric = '00'.$numeric; break;
case 2 : $numeric = '0' .$numeric; break; // @codeCoverageIgnore
}
if( $numeric === '000' )
{
return false;
}
return $numeric;
}
/**
* Protected run migrate all
*/
protected function runMigrateAll($type, $migrations)
{
foreach( $migrations as $migration )
{
$migration = Base::prefix($migration, 'Migrate');
$migration::$type();
}
}
/**
* protected create migrate file
*
* @param string $name
* @param string $file
*
* @return bool
*/
protected function createMigrateFile(string $name, string $file) : bool
{
$eol = EOL;
$str = '<?php'.$eol;
$str .= 'class '.$this->classFix.$name.' extends '.__CLASS__.$eol;
$str .= '{'.$eol;
$str .= "\t".'# Class/Table Name'.$eol;
$str .= "\t".'const table = __CLASS__;'.$eol.$eol;
$str .= "\t".'# Up'.$eol;
$str .= "\t".'public function up()'.$eol;
$str .= "\t".'{'.$eol;
$str .= "\t\t".'# Default Query'.$eol;
$str .= "\t\t".'return $this->createTable' . $eol;
$str .= "\t\t".'(['.$eol;
$str .= "\t\t\t".'\'id\' => [DB::int(11), DB::primaryKey(), DB::autoIncrement()]' . $eol;
$str .= "\t\t".']);'.$eol;
$str .= "\t".'}'.$eol.$eol;
$str .= "\t".'# Down'.$eol;
$str .= "\t".'public function down()'.$eol;
$str .= "\t".'{'.$eol;
$str .= "\t\t".'# Default Query'.$eol;
$str .= "\t\t".'return $this->dropTable();'.$eol;
$str .= "\t".'}'.$eol;
$str .= '}';
return file_put_contents($file, $str);
}
}
@@ -0,0 +1,141 @@
<?php namespace ZN\Database;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
interface MigrationInterface
{
/**
* Up all migrations
*
* @param string ...$migrations
*
* @return bool
*/
public function upAll(string ...$migrations) : bool;
/**
* Down all migrations
*
* @param string ...$migrations
*
* @return bool
*/
public function downAll(string ...$migrations) : bool;
/**
* Create table
*
* @param array $data
*
* @return bool
*/
public function createTable(array $data) : bool;
/**
* Drop table
*
* @param void
*
* @return bool
*/
public function dropTable() : bool;
/**
* Add column
*
* @param array $column
*
* @return bool
*/
public function addColumn(array $columns) : bool;
/**
* Drop column
*
* @param mixed $column
*
* @return bool
*/
public function dropColumn($columns) : bool;
/**
* Modify column
*
* @param array $column
*
* @param bool
*/
public function modifyColumn(array $columns) : bool;
/**
* Rename column
*
* @param array $column
*
* @return bool
*/
public function renameColumn(array $column) : bool;
/**
* Truncate table
*
* @param void
*
* @return bool
*/
public function truncate() : bool;
/**
* Sets migration path
*
* @param string $path = NULL
*
* @return Migration
*/
public function path(string $path) : Migration;
/**
* Selects migration version
*
* @param int $version = 0
*
* @return object
*/
public function version(int $version = 0);
/**
* Create migration
*
* @param string $name
* @param int $version = 0
*
* @return bool
*/
public function create(string $name, int $ver = 0) : bool;
/**
* Delete migration
*
* @param string $name
* @param int $version = 0
*
* @return bool
*/
public function delete(string $name, int $ver = 0) : bool;
/**
* Delete all migrations
*
* @param void
*
* @return bool
*/
public function deleteAll() : bool;
}
+444
View File
@@ -0,0 +1,444 @@
<?php namespace ZN\Database\MySQLi;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use MySQLi;
use stdClass;
use Exception;
use ZN\Support;
use ZN\ErrorHandling\Errors;
use ZN\Database\DriverMappingAbstract;
use ZN\Database\Exception\ConnectionErrorException;
class DB extends DriverMappingAbstract
{
/**
* Keep Operators
*
* @var array
*/
protected $operators =
[
'like' => '%'
];
/**
* Keep Statements
*
* @var array
*/
protected $statements =
[
'autoincrement' => 'AUTO_INCREMENT',
'primarykey' => 'PRIMARY KEY',
'foreignkey' => 'FOREIGN KEY',
'unique' => 'UNIQUE',
'null' => 'NULL',
'notnull' => 'NOT NULL',
'exists' => 'EXISTS',
'notexists' => 'NOT EXISTS',
'constraint' => 'CONSTRAINT',
'default' => 'DEFAULT'
];
/**
* Keep Variable Types
*
* @var array
*/
protected $variableTypes =
[
'int' => 'INT',
'smallint' => 'SMALLINT',
'tinyint' => 'TINYINT',
'mediumint' => 'MEDIUMINT',
'bigint' => 'BIGINT',
'decimal' => 'DECIMAL',
'double' => 'DOUBLE',
'float' => 'FLOAT',
'char' => 'CHAR',
'varchar' => 'VARCHAR',
'tinytext' => ':TINYTEXT',
'text' => 'TEXT',
'mediumtext' => ':MEDIUMTEXT',
'longtext' => ':LONGTEXT',
'date' => ':DATE',
'datetime' => 'DATETIME',
'time' => 'TIME',
'timestamp' => 'TIMESTAMP'
];
/**
* Keeps Types
*
* @var array
*/
protected $types =
[
0 => 'DECIMAL',
1 => 'TINY',
2 => 'SHORT',
3 => 'LONG',
4 => 'FLOAT',
5 => 'DOUBLE',
6 => 'NULL',
7 => 'TIMESTAMP',
8 => 'LONGLONG',
9 => 'INT24',
10 => 'DATE',
11 => 'TIME',
12 => 'DATETIME',
13 => 'YEAR',
14 => 'NEWDATE',
247 => 'ENUM',
248 => 'SET',
249 => 'TINY_BLOB',
250 => 'MEDIUM_BLOB',
251 => 'LONG_BLOG',
252 => 'BLOB',
253 => 'VAR_STRING',
254 => 'STRING',
255 => 'GEOMETRY'
];
/**
* Magic Constructor
*/
public function __construct()
{
Support::extension('MySQLi');
}
/**
* Connection
*
* @param array $config = []
*/
public function connect($config = [])
{
$this->config = $config;
$host = ($this->config['pconnect'] === true ? 'p:' : NULL) . $this->config['host'];
$user = $this->config['user'];
$pass = $this->config['password'];
$db = $this->config['database'];
$port = $this->config['port'] ?: 3306;
$ssl = $this->config['ssl'] ?? NULL;
// @codeCoverageIgnoreStart
set_error_handler(function(){});
if( ! empty($ssl['key']) || ! empty($ssl['cert']) || ! empty($ssl['ca']) || ! empty($ssl['capath']) || ! empty($ssl['cipher']) )
{
$this->connect = new MySQLi;
$this->connect->options(MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, true);
$this->connect->ssl_set($ssl['key'] ?? NULL, $ssl['cert'] ?? NULL, $ssl['ca'] ?? NULL, $ssl['capath'] ?? NULL, $ssl['cipher'] ?? NULL);
$this->connect->real_connect($host, $user, $pass, $db, $port, NULL, MYSQLI_CLIENT_SSL);
}
// @codeCoverageIgnoreEnd
else
{
$this->connect = new MySQLi($host, $user, $pass, $db, $port);
}
restore_error_handler();
if( $this->connect->connect_errno )
{
throw new ConnectionErrorException(NULL, $this->connect->connect_error); // @codeCoverageIgnore
}
mysqli_report(MYSQLI_REPORT_OFF);
if( ! empty($this->config['charset'] ) ) $this->query("SET NAMES '".$this->config['charset']."'");
if( ! empty($this->config['charset'] ) ) $this->query('SET CHARACTER SET '.$this->config['charset']);
if( ! empty($this->config['collation']) ) $this->query('SET COLLATION_CONNECTION = "'.$this->config['collation'].'"');
}
/**
* Execute
*
* @param string $query
* @param array $security = NULL
*
* @return bool
*/
public function exec($query, $security = NULL)
{
if( empty($query) )
{
return false;
}
return $this->connect->query($query);
}
/**
* Query
*
* @param string $query
* @param array $security = NULL
*
* @return bool
*/
public function query($query, $security = NULL)
{
return $this->query = $this->exec($query, $security);
}
/**
* Multiple Queries
*
* @param string $query
* @param array $security = NULL
*
* @return bool
*/
public function multiQuery($query, $security = NULL)
{
if( empty($query) )
{
return false; // @codeCoverageIgnore
}
if( $this->query = $this->connect->multi_query($query) )
{
while( $this->connect->next_result() )
{
if( ! $this->connect->more_results() )
{
break;
}
}
}
return (bool) $this->query;
}
/**
* Start Transaction Query
*
* @return bool
*/
public function transStart()
{
$this->connect->autocommit(false);
return $this->connect->begin_transaction();
}
/**
* Rollback Transaction Query
*
* @return bool
*/
public function transRollback()
{
if( $this->connect->rollback() )
{
return $this->connect->autocommit(true);
}
return false; // @codeCoverageIgnore
}
/**
* Commit Transaction Query
*
* @return bool
*/
public function transCommit()
{
if( $this->connect->commit() )
{
return $this->connect->autocommit(true);
}
return false; // @codeCoverageIgnore
}
/**
* Insert Last ID
*
* @return int|false
*/
public function insertID()
{
return $this->connect->insert_id ?? false;
}
/**
* Returns column data
*
* @param string $column
*
* @return array|object
*/
public function columnData($column)
{
if( empty($this->query) )
{
return false;
}
$columns = [];
$fieldData = $this->query->fetch_fields();
$count = count($fieldData);
for( $i = 0; $i < $count; $i++ )
{
$fieldName = $fieldData[$i]->name;
$columns[$fieldName] = new stdClass();
$columns[$fieldName]->name = $fieldName;
$columns[$fieldName]->type = $this->types[$fieldData[$i]->type] ?? NULL;
$columns[$fieldName]->maxLength = $fieldData[$i]->max_length;
$columns[$fieldName]->primaryKey = (int) ($fieldData[$i]->flags & 2);
$columns[$fieldName]->default = $fieldData[$i]->def;
}
return $columns[$column] ?? $columns;
}
/**
* Numrows
*
* @return int
*/
public function numRows()
{
return $this->query->num_rows ?? 0;
}
/**
* Returns columns
*
* @return array
*/
public function columns()
{
if( empty($this->query) )
{
return [];
}
$columns = [];
$fields = $this->query->fetch_fields();
$numFields = $this->numFields();
for( $i = 0; $i < $numFields; $i++ )
{
$columns[] = $fields[$i]->name;
}
return $columns;
}
/**
* Numfields
*
* @return int
*/
public function numFields()
{
return $this->query->field_count ?? 0;
}
/**
* Real Escape String
*
* @param string $data
*
* @return string|false
*/
public function realEscapeString($data)
{
if( empty($this->query) )
{
return $data; // @codeCoverageIgnore
}
return $this->connect->real_escape_string($data);
}
/**
* Returns a string description of the last error.
*
* @return string|false
*/
public function error()
{
return $this->connect->error ?: false;
}
/**
* Fetch a result row as an associative, a numeric array, or both
*
* @return mixed
*/
public function fetchArray()
{
if( empty($this->query) )
{
return [];
}
return $this->query->fetch_array();
}
/**
* Fetch a result row as an associative array
*
* @return mixed
*/
public function fetchAssoc()
{
if( empty($this->query) )
{
return [];
}
return $this->query->fetch_assoc();
}
/**
* Get a result row as an enumerated array
*
* @return mixed
*/
public function fetchRow()
{
if( empty($this->query) )
{
return [];
}
return $this->query->fetch_row();
}
/**
* Gets the number of affected rows in a previous MySQL operation
*
* @return int
*/
public function affectedRows()
{
return $this->connect->affected_rows ?? 0;
}
/**
* Returns the version of the MySQL server as an integer
*
* @return int
*/
public function version()
{
return (string) ($this->connect->server_version ?? 0);
}
}
@@ -0,0 +1,45 @@
<?php namespace ZN\Database\MySQLi;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Database\DriverForge;
class DBForge extends DriverForge
{
/**
* Drop Foreign Key
*
* 5.7.4[added]
*
* @param string $table
* @param string $constraint = NULL
*
* @return string
*/
public function dropForeignKey($table, $constraint = NULL)
{
return 'ALTER TABLE ' . $table . ' DROP ' . $this->db()->foreignKey() . ' ' . $constraint . ';';
}
/**
* Drop Primary Key
*
* 5.7.4[added]
*
* @param string $table
* @param string $constraint = NULL
*
* @return string
*/
public function dropPrimaryKey($table, $constraint = NULL)
{
return 'ALTER TABLE ' . $table . ' DROP ' . $this->db()->primaryKey() . ';';
}
}
@@ -0,0 +1,17 @@
<?php namespace ZN\Database\MySQLi;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Database\DriverTool;
class DBTool extends DriverTool
{
}
+410
View File
@@ -0,0 +1,410 @@
<?php namespace ZN\Database\ODBC;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use stdClass;
use ZN\Base;
use ZN\Support;
use ZN\Security;
use ZN\ErrorHandling\Errors;
use ZN\Database\DriverMappingAbstract;
use ZN\Database\Exception\ConnectionErrorException;
/**
* @codeCoverageIgnore
*/
class DB extends DriverMappingAbstract
{
/**
* Keep Operators
*
* @var array
*/
protected $operators =
[
'like' => '*'
];
/**
* Keep Statements
*
* @var array
*/
protected $statements =
[
'autoincrement' => 'AUTOINCREMENT',
'primarykey' => 'PRIMARY KEY',
'foreignkey' => 'FOREIGN KEY',
'unique' => 'UNIQUE',
'null' => 'NULL',
'notnull' => 'NOT NULL',
'exists' => 'EXISTS',
'notexists' => 'NOT EXISTS',
'constraint' => 'CONSTRAINT',
'default' => 'DEFAULT'
];
/**
* Keep Variable Types
*
* @var array
*/
protected $variableTypes =
[
'int' => ':INTEGER',
'smallint' => ':SMALLINT',
'tinyint' => ':TINYINT',
'mediumint' => ':INTEGER',
'bigint' => ':BIGINT',
'decimal' => 'DECIMAL',
'double' => 'FLOAT',
'float' => 'FLOAT',
'char' => 'CHAR',
'varchar' => 'VARCHAR',
'tinytext' => ':VARCHAR(255)',
'text' => ':VARCHAR(65535)',
'mediumtext' => ':VARCHAR(16277215)',
'longtext' => ':VARCHAR(16277215)',
'date' => ':DATE',
'datetime' => ':DATETIME',
'time' => ':TIME',
'timestamp' => ':TIMESTAMP'
];
/**
* Magic Constructor
*/
public function __construct()
{
Support::func('odbc_connect', 'Microsoft Access(ODBC)');
}
/**
* Connection
*
* @param array $config = []
*/
public function connect($config = [])
{
$this->config = $config;
$host = Base::suffix(Base::prefix($this->config['host'], '{'), '}');
if( ! empty($this->config['dsn']) )
{
$dsn = $this->config['dsn'];
}
else if( is_file($this->config['database']) )
{
$dsn = 'DRIVER=' . $host . ';DBQ=' . $this->config['database'];
}
else
{
$dsn = 'DRIVER=' . $host . ';SERVER=' . $this->config['server'] . ';DATABASE=' . $this->config['database'];
}
$connectMethod = $this->config['pconnect'] === true ? 'odbc_pconnect' : 'odbc_connect';
$this->connect = $connectMethod($dsn, $this->config['user'], $this->config['password']);
if( empty($this->connect) )
{
throw new ConnectionErrorException(NULL, 'connection');
}
}
/**
* Execute
*
* @param string $query
* @param array $security = NULL
*
* @return bool
*/
public function exec($query, $security = NULL)
{
if( empty($query) )
{
return false;
}
return odbc_exec($this->connect, $this->comma($query));
}
/**
* Multiple Queries
*
* @param string $query
* @param array $security = []
*
* @return bool
*/
public function multiQuery($query, $security = [])
{
return (bool) $this->query($query, $security);
}
/**
* Query
*
* @param string $query
* @param array $security = NULL
*
* @return bool
*/
public function query($query, $security = [])
{
if( $this->query = odbc_prepare($this->connect, $this->comma($query)) )
{
return odbc_execute($this->query, $security);
}
return $this->query;
}
/**
* Start Transaction Query
*
* @return bool
*/
public function transStart()
{
return odbc_autocommit($this->connect, false);
}
/**
* Rollback Transaction Query
*
* @return bool
*/
public function transRollback()
{
$rollback = odbc_rollback($this->connect);
odbc_autocommit($this->connect, true);
return $rollback;
}
/**
* Commit Transaction Query
*
* @return bool
*/
public function transCommit()
{
$commit = odbc_commit($this->connect);
odbc_autocommit($this->connect, true);
return $commit;
}
/**
* Insert Last ID
*
* @return int|false
*/
public function insertID()
{
return false;
}
/**
* Returns column data
*
* @param string $column
*
* @return array|object
*/
public function columnData($col = '')
{
if( empty($this->query) )
{
return false;
}
$columns = [];
$numFields = $this->numFields();
for( $index = 1; $index <= $numFields; $index++ )
{
$fieldName = odbc_field_name($this->query, $index);
$columns[$fieldName] = new stdClass();
$columns[$fieldName]->name = $fieldName;
$columns[$fieldName]->type = odbc_field_type($this->query, $index);
$columns[$fieldName]->maxLength = odbc_field_len($this->query, $index);
$columns[$fieldName]->primaryKey = NULL;
$columns[$fieldName]->default = NULL;
}
return $columns[$col] ?? $columns;
}
/**
* Numrows
*
* @return int
*/
public function numRows()
{
if( ! empty($this->query) )
{
return odbc_num_rows($this->query);
}
else
{
return 0;
}
}
/**
* Returns columns
*
* @return array
*/
public function columns()
{
if( empty($this->query) )
{
return [];
}
$columns = [];
$numFields = $this->numFields();
for( $index = 1; $index <= $numFields; $index++ )
{
$columns[] = odbc_field_name($this->query, $index);
}
return $columns;
}
/**
* Numfields
*
* @return int
*/
public function numFields()
{
if( ! empty($this->query) )
{
return odbc_num_fields($this->query);
}
else
{
return 0;
}
}
/**
* Real Escape String
*
* @param string $data
*
* @return string|false
*/
public function realEscapeString($data = '')
{
return Security\Injection::escapeStringEncode($data);
}
/**
* Returns a string description of the last error.
*
* @return string|false
*/
public function error()
{
if( ! empty($this->connect) )
{
return odbc_error($this->connect) ? (odbc_errormsg($this->connect) ?: false) : false;
}
else
{
return false;
}
}
/**
* Fetch a result row as an associative, a numeric array, or both
*
* @return mixed
*/
public function fetchArray()
{
if( ! empty($this->query) )
{
return odbc_fetch_array($this->query);
}
else
{
return [];
}
}
/**
* Fetch a result row as an associative array
*
* @return mixed
*/
public function fetchAssoc()
{
if( ! empty($this->query) )
{
return odbc_fetch_array($this->query);
}
else
{
return [];
}
}
/**
* Get a result row as an enumerated array
*
* @return mixed
*/
public function fetchRow()
{
if( ! empty($this->query) )
{
return odbc_fetch_array($this->query);
}
else
{
return [];
}
}
/**
* Gets the number of affected rows in a previous MySQL operation
*
* @return int
*/
public function affectedRows()
{
return 0;
}
/**
* Returns the version of the MySQL server as an integer
*
* @return int
*/
public function version()
{
return false;
}
protected function comma($query)
{
return Base::suffix(trim($query), ';');
}
}
@@ -0,0 +1,55 @@
<?php namespace ZN\Database\ODBC;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Database\DriverForge;
class DBForge extends DriverForge
{
/**
* Truncate table
*
* @param string $table
*
* @return string
*/
public function truncate($table)
{
return 'DELETE FROM '.$table.';';
}
/**
* Rename column
*
* @param string $table
* @param string $table
*
* @return string
*/
public function renameColumn($table, $column)
{
return 'ALTER TABLE '.$table.' RENAME COLUMN '.rtrim($column, ',').';';
}
/**
* Drop index
*
* 5.7.4[added]
*
* @param string $indexName
* @param string $table
*
* @return string
*/
public function dropIndex($indexName, $table)
{
return 'DROP INDEX ' . $indexName . ' ON ' . $table . ';';
}
}
+17
View File
@@ -0,0 +1,17 @@
<?php namespace ZN\Database\ODBC;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Database\DriverTool;
class DBTool extends DriverTool
{
}
+396
View File
@@ -0,0 +1,396 @@
<?php namespace ZN\Database\Oracle;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use stdClass;
use ZN\Support;
use ZN\Security;
use ZN\ErrorHandling\Errors;
use ZN\Database\DriverMappingAbstract;
use ZN\Database\Exception\ConnectionErrorException;
/**
* @codeCoverageIgnore
*/
class DB extends DriverMappingAbstract
{
/**
* Keep Operators
*
* @var array
*/
protected $operators =
[
'like' => '%'
];
/**
* Keep Statements
*
* @var array
*/
protected $statements =
[
'autoincrement' => 'CREATE SEQUENCE % MINVALUE 1 STARVALUE WITH 1 INCREMENT BY 1;',
'primarykey' => 'PRIMARY KEY',
'foreignkey' => 'FOREIGN KEY',
'unique' => 'UNIQUE',
'null' => 'NULL',
'notnull' => 'NOT NULL',
'exists' => 'EXISTS',
'notexists' => 'NOT EXISTS',
'constraint' => 'CONSTRAINT',
'default' => 'DEFAULT'
];
/**
* Keep Variable Types
*
* @var array
*/
protected $variableTypes =
[
'int' => 'NUMBER',
'smallint' => 'NUMBER',
'tinyint' => 'NUMBER',
'mediumint' => 'NUMBER',
'bigint' => 'NUMBER',
'decimal' => 'DECIMAL',
'double' => 'FLOAT',
'float' => 'FLOAT',
'char' => 'CHAR',
'varchar' => 'VARCHAR2',
'tinytext' => ':VARCHAR2(255)',
'text' => ':VARCHAR2(65535)',
'mediumtext' => ':VARCHAR2(16277215)',
'longtext' => ':CLOB',
'date' => ':DATE',
'datetime' => 'TIMESTAMP',
'time' => 'TIMESTAMP',
'timestamp' => 'TIMESTAMP'
];
/**
* Magic Constructor
*/
public function __construct()
{
Support::func('oci_connect', 'Oracle 8');
}
/**
* Connection
*
* @param array $config = []
*/
public function connect($config = [])
{
$this->config = $config;
$dsn = ( ! empty($this->config['dsn']))
? $this->config['dsn']
: $this->config['host'];
$connectMethod = $this->config['pconnect'] === true ? 'oci_pconnect' : 'oci_connect';
$this->connect = $connectMethod($this->config['user'], $this->config['password'], $dsn);
if( empty($this->connect) )
{
throw new ConnectionErrorException(NULL, oci_error($this->connect)['message']);
}
}
/**
* Execute
*
* @param string $query
* @param array $security = NULL
*
* @return bool
*/
public function exec($query, $security = NULL)
{
if( empty($query) )
{
return false;
}
$que = oci_parse($this->connect, $query);
oci_execute($que);
return $que;
}
/**
* Multiple Queries
*
* @param string $query
* @param array $security = NULL
*
* @return bool
*/
public function multiQuery($query, $security = NULL)
{
return (bool) $this->query($query, $security);
}
/**
* Query
*
* @param string $query
* @param array $security = NULL
*
* @return bool
*/
public function query($query, $security = [])
{
$this->query = oci_parse($this->connect, $query);
return oci_execute($this->query);
}
/**
* Start Transaction Query
*
* @return bool
*/
public function transStart()
{
$this->exec(OCI_NO_AUTO_COMMIT);
return true;
}
/**
* Rollback Transaction Query
*
* @return bool
*/
public function transRollback()
{
oci_rollback($this->connect);
return $this->exec(OCI_COMMIT_ON_SUCCESS);
}
/**
* Commit Transaction Query
*
* @return bool
*/
public function transCommit()
{
oci_commit($this->connect);
return $this->exec(OCI_COMMIT_ON_SUCCESS);
}
/**
* Returns column data
*
* @param string $column
*
* @return array|object
*/
public function columnData($col = '')
{
if( empty($this->query) )
{
return false;
}
$columns = [];
$numFields = $this->numFields();
for( $i = 1; $i <= $numFields; $i++ )
{
$fieldName = oci_field_name($this->query, $i);
$columns[$fieldName] = new stdClass();
$columns[$fieldName]->name = $fieldName;
$columns[$fieldName]->type = oci_field_type($this->query, $i);
$columns[$fieldName]->maxLength = oci_field_size($this->query, $i);
$columns[$fieldName]->primaryKey = NULL;
$columns[$fieldName]->default = NULL;
}
return $columns[$col] ?? $columns;
}
/**
* Numrows
*
* @return int
*/
public function numRows()
{
if( ! empty($this->query) )
{
return oci_num_rows($this->query);
}
else
{
return 0;
}
}
/**
* Returns columns
*
* @return array
*/
public function columns()
{
if( empty($this->query) )
{
return [];
}
$columns = [];
$numFields = $this->numFields();
for( $i = 0; $i < $numFields; $i++ )
{
$columns[] = oci_field_name($this->query, $i);
}
return $columns;
}
/**
* Numfields
*
* @return int
*/
public function numFields()
{
if( ! empty($this->query) )
{
return oci_num_fields($this->query);
}
else
{
return 0;
}
}
/**
* Real Escape String
*
* @param string $data
*
* @return string|false
*/
public function realEscapeString($data = '')
{
return Security\Injection::escapeStringEncode($data);
}
/**
* Returns a string description of the last error.
*
* @return string|false
*/
public function error()
{
if( ! empty($this->connect) )
{
$error = oci_error($this->connect);
return ! empty($error['code']) ? ($error['message'] ?: false) : false;
}
else
{
return false;
}
}
/**
* Fetch a result row as an associative, a numeric array, or both
*
* @return mixed
*/
public function fetchArray()
{
if( ! empty($this->query) )
{
return oci_fetch_array($this->query);
}
else
{
return [];
}
}
/**
* Fetch a result row as an associative array
*
* @return mixed
*/
public function fetchAssoc()
{
if( ! empty($this->query) )
{
return oci_fetch_assoc($this->query);
}
else
{
return [];
}
}
/**
* Get a result row as an enumerated array
*
* @return mixed
*/
public function fetchRow()
{
if( ! empty($this->query) )
{
return oci_fetch_row($this->query);
}
else
{
return [];
}
}
/**
* Gets the number of affected rows in a previous MySQL operation
*
* @return int
*/
public function affectedRows()
{
if( ! empty($this->connect) )
{
return 0;
}
else
{
return 0;
}
}
/**
* Returns the version of the MySQL server as an integer
*
* @return int
*/
public function version()
{
if( ! empty($this->connect) )
{
return oci_server_version($this->connect);
}
else
{
return false;
}
}
}
@@ -0,0 +1,57 @@
<?php namespace ZN\Database\Oracle;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Database\DriverForge;
class DBForge extends DriverForge
{
/**
* Create Temporary Table
*
* @param string $tabşe
* @param array $columns
* @param string $extras
*
* @return string
*/
public function createTempTable($table, $columns, $extras)
{
return 'CREATE GLOBAL TEMPORARY TABLE ' . $this->createTableColumnsSyntax($table, $columns, $extras) . ' ON COMMIT PRESERVE ROWS;';
}
/**
* Rename column
*
* @param string $table
* @param array $column
*
* @return string
*/
public function renameColumn($table, $column)
{
return 'ALTER TABLE '.$table.' RENAME COLUMN '.key($column).' TO '.current($column).';';
}
/**
* Drop index
*
* 5.7.4[added]
*
* @param string $indexName
* @param string $table
*
* @return string
*/
public function dropIndex($indexName, $table = NULL)
{
return 'DROP INDEX ' . $indexName . ';';
}
}
@@ -0,0 +1,17 @@
<?php namespace ZN\Database\Oracle;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Database\DriverTool;
class DBTool extends DriverTool
{
}
+382
View File
@@ -0,0 +1,382 @@
<?php namespace ZN\Database\Postgres;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use stdClass;
use ZN\Support;
use ZN\Database\Properties;
use ZN\ErrorHandling\Errors;
use ZN\Database\DriverMappingAbstract;
use ZN\Database\Exception\ConnectionErrorException;
class DB extends DriverMappingAbstract
{
/**
* Keep Operators
*
* @var array
*/
protected $operators =
[
'like' => '%'
];
/**
* Keep Statements
*
* @var array
*/
protected $statements =
[
'autoincrement' => 'BIGSERIAL',
'primarykey' => 'PRIMARY KEY',
'foreignkey' => 'FOREIGN KEY',
'unique' => 'UNIQUE',
'null' => 'NULL',
'notnull' => 'NOT NULL',
'exists' => 'EXISTS',
'notexists' => 'NOT EXISTS',
'constraint' => 'CONSTRAINT',
'default' => 'DEFAULT'
];
/**
* Keep Variable Types
*
* @var array
*/
protected $variableTypes =
[
'int' => ':INTEGER',
'smallint' => ':SMALLINT',
'tinyint' => ':SMALLINT',
'mediumint' => ':INTEGER',
'bigint' => ':BIGINT',
'decimal' => ':DECIMAL',
'double' => ':DOUBLE PRECISION',
'float' => ':NUMERIC',
'char' => 'CHARACTER',
'varchar' => 'CHARACTER VARYING',
'tinytext' => ':CHARACTER VARYING(255)',
'text' => ':TEXT',
'mediumtext' => ':TEXT',
'longtext' => ':TEXT',
'date' => ':DATE',
'datetime' => 'TIMESTAMP',
'time' => 'TIME',
'timestamp' => 'TIMESTAMP'
];
/**
* Magic Constructor
*/
public function __construct()
{
Support::func('pg_connect', 'Postgres');
}
/**
* Connection
*
* @param array $config = []
*/
public function connect($config = [])
{
$this->config = $config;
$dsn = 'host='.$this->config['host'].' ';
if( ! empty($this->config['port']) ) $dsn .= 'port='.$this->config['port'].' ';
if( ! empty($this->config['database']) ) $dsn .= 'dbname='.$this->config['database'].' ';
if( ! empty($this->config['user']) ) $dsn .= 'user='.$this->config['user'].' ';
if( ! empty($this->config['password']) ) $dsn .= 'password='.$this->config['password'].' ';
if( ! empty($this->config['dsn']) )
{
$dsn = $this->config['dsn']; // @codeCoverageIgnore
}
$connectMethod = $this->config['pconnect'] === true ? 'pg_pconnect' : 'pg_connect';
$this->connect = $connectMethod(rtrim($dsn));
if( empty($this->connect) )
{
throw new ConnectionErrorException(NULL, 'connection'); // @codeCoverageIgnore
}
if( ! empty($this->config['charset']) )
{
$charset = $this->config['charset'] === 'utf8' ? 'UNICODE' : $this->config['charset'];
pg_set_client_encoding($this->connect, $charset);
}
}
/**
* Execute
*
* @param string $query
* @param array $security = NULL
*
* @return bool
*/
public function exec($query, $security = NULL)
{
if( empty($query) )
{
return false; // @codeCoverageIgnore
}
set_error_handler(function(){});
$return = pg_query($this->connect, $query);
restore_error_handler();
return $return;
}
/**
* Multiple Queries
*
* @param string $query
* @param array $security = NULL
*
* @return bool
*/
public function multiQuery($query, $security = NULL)
{
return (bool) $this->query($query, $security);
}
/**
* Query
*
* @param string $query
* @param array $security = NULL
*
* @return bool
*/
public function query($query, $security = [])
{
return $this->query = $this->exec($query);
}
/**
* Start Transaction Query
*
* @return bool
*/
public function transStart()
{
return (bool) pg_query($this->connect, 'BEGIN');
}
/**
* Rollback Transaction Query
*
* @return bool
*/
public function transRollback()
{
return (bool) pg_query($this->connect, 'ROLLBACK');
}
/**
* Commit Transaction Query
*
* @return bool
*
* @codeCoverageIgnore
*/
public function transCommit()
{
return (bool) pg_query($this->connect, 'COMMIT');
}
/**
* Insert Last ID
*
* @return int|string
*
* @codeCoverageIgnore
*/
public function insertID()
{
if( empty($this->query) )
{
return false;
}
$returningId = Properties::$returningId;
Properties::$returningId = 'id';
return $returningId === '*' ? (object) $this->fetchAssoc() : ( $this->fetchAssoc()[$returningId] ?? false );
}
/**
* Returns column data
*
* @param string $column
*
* @return array|object
*/
public function columnData($col = '')
{
if( empty($this->query) )
{
return false; // @codeCoverageIgnore
}
$columns = [];
$numFields = $this->numFields();
for( $i = 0; $i < $numFields; $i++ )
{
$fieldName = pg_field_name($this->query, $i);
$columns[$fieldName] = new stdClass();
$columns[$fieldName]->name = $fieldName;
$columns[$fieldName]->type = pg_field_type($this->query, $i);
$columns[$fieldName]->maxLength = pg_field_size($this->query, $i);
$columns[$fieldName]->primaryKey = NULL;
$columns[$fieldName]->default = NULL;
}
return $columns[$col] ?? $columns;
}
/**
* Numrows
*
* @return int
*/
public function numRows()
{
return ! empty($this->query) ? pg_num_rows($this->query) : 0;
}
/**
* Returns columns
*
* @return array
*/
public function columns()
{
if( empty($this->query) )
{
return []; // @codeCoverageIgnore
}
$columns = [];
$numFields = $this->numFields();
for( $i = 0; $i < $numFields; $i++ )
{
$columns[] = pg_field_name($this->query, $i);
}
return $columns;
}
/**
* Numfields
*
* @return int
*/
public function numFields()
{
return ! empty($this->query) ? pg_num_fields($this->query) : 0;
}
/**
* Real Escape String
*
* @param string $data
*
* @return string|false
*/
public function realEscapeString($data = '')
{
return pg_escape_string($this->connect, $data);
}
/**
* Returns a string description of the last error.
*
* @return string|false
*/
public function error()
{
return is_resource($this->connect) ? ( pg_last_error($this->connect) ?: false ) : false;
}
/**
* Fetch a result row as an associative, a numeric array, or both
*
* @return mixed
*/
public function fetchArray()
{
return ! empty($this->query) ? pg_fetch_array($this->query) : [];
}
/**
* Fetch a result row as an associative array
*
* @return mixed
*/
public function fetchAssoc()
{
return ! empty($this->query) ? pg_fetch_assoc($this->query) : [];
}
/**
* Get a result row as an enumerated array
*
* @return mixed
*/
public function fetchRow()
{
return ! empty($this->query) ? pg_fetch_row($this->query) : [];
}
/**
* Gets the number of affected rows in a previous MySQL operation
*
* @return int
*/
public function affectedRows()
{
return ! empty($this->query) ? pg_affected_rows($this->query) : 0;
}
/**
* Returns the version of the MySQL server as an integer
*
* @return int
*/
public function version()
{
return is_resource($this->connect) ? pg_version($this->connect)['client'] : false;
}
/**
* protected get insert extras by drvier
*
* @codeCoverageIgnore
*/
public function getInsertExtrasByDriver()
{
return ' RETURNING ' . Properties::$returningId . ';';
}
}
@@ -0,0 +1,85 @@
<?php namespace ZN\Database\Postgres;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Database\DriverForge;
class DBForge extends DriverForge
{
/**
* Unsupported
*/
public function extras($extras)
{
return NULL;
}
/**
* Modify Column
*
* @param string $table
* @param array $column
*
* @return string
*/
public function modifyColumn($table, $column)
{
$col = key($column); $values = (array) current($column); $query = '';
foreach( $values as $value )
{
$type = preg_match('/(NULL|DEFAULT|CONSTRAINT|EXISTS|UNIQUE|KEY|BIGSERIAL)/i', $value ?? '') ? 'SET' : 'TYPE';
$query .= 'ALTER TABLE ' . $table . ' ALTER COLUMN ' . $this->buildForgeColumnsSyntax([$col => [$value]], $type) . ';';
}
return $query;
}
/**
* Rename Column
*
* @param string $table
* @param array $column
*
* @return string
*/
public function renameColumn($table, $column)
{
return 'ALTER TABLE '.$table.' RENAME COLUMN ' . $this->buildForgeColumnsSyntax($column, 'TO') . ';';
}
/**
* Add Column
*
* @param string $table
* @param array $column
*
* @return string
*/
public function addColumn($table, $columns)
{
return 'ALTER TABLE ' . $table . ' ADD ' . $this->buildForgeColumnsQuery($columns) . ';';
}
/**
* Drop index
*
* @param string $indexName
* @param string $table
*
* @return string
*/
public function dropIndex($indexName, $table)
{
return 'DROP INDEX ' . $indexName . ';';
}
}
@@ -0,0 +1,67 @@
<?php namespace ZN\Database\Postgres;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Database\DriverTool;
class DBTool extends DriverTool
{
/**
* List Databases
*
* @return array
*/
public function listDatabases($query = 'SELECT datname FROM pg_database')
{
return $this->runListQuery($query);
}
/**
* List Tables
*
* @return array
*/
public function listTables($query = "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'")
{
return $this->runListQuery($query);
}
/**
* Unsupported
*/
public function statusTables($table)
{
return false;
}
/**
* Unsupported
*/
public function optimizeTables($table)
{
return false;
}
/**
* Unsupported
*/
public function repairTables($table, $query = '', $message = '')
{
return false;
}
/**
* Unsupported
*/
public function backup($tables, $fileName, $path)
{
return false;
}
}
+34
View File
@@ -0,0 +1,34 @@
<?php namespace ZN\Database;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
class Properties
{
/**
* Keeps Table Name
*
* @var string
*/
public static $table = NULL;
/**
* Keeps Table Prefix
*
* @var string
*/
public static $prefix = NULL;
/**
* Keeps Postgres Driver Returning ID
*
* @var string
*/
public static $returningId = 'id';
}
+452
View File
@@ -0,0 +1,452 @@
<?php namespace ZN\Database\SQLServer;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use stdClass;
use ZN\Support;
use ZN\Security;
use ZN\ErrorHandling\Errors;
use ZN\Database\Exception\ConnectionErrorException;
use ZN\Database\DriverMappingAbstract;
class DB extends DriverMappingAbstract
{
/**
* Keep Operators
*
* @var array
*/
protected $operators =
[
'like' => '%'
];
/**
* Keep Statements
*
* @var array
*/
protected $statements =
[
'autoincrement' => 'IDENTITY(1,1)',
'primarykey' => 'PRIMARY KEY',
'foreignkey' => 'FOREIGN KEY',
'unique' => 'UNIQUE',
'null' => 'NULL',
'notnull' => 'NOT NULL',
'exists' => 'EXISTS',
'notexists' => 'NOT EXISTS',
'constraint' => 'CONSTRAINT',
'default' => 'DEFAULT'
];
/**
* Keep Variable Types
*
* @var array
*/
protected $variableTypes =
[
'int' => ':INT',
'smallint' => ':SMALLINT',
'tinyint' => ':TINYINT',
'mediumint' => ':INT',
'bigint' => ':BIGINT',
'decimal' => 'DECIMAL',
'double' => 'FLOAT',
'float' => 'FLOAT',
'char' => 'CHAR',
'varchar' => 'VARCHAR',
'tinytext' => ':VARCHAR(255)',
'text' => ':VARCHAR(65535)',
'mediumtext' => ':VARCHAR(16277215)',
'longtext' => ':VARCHAR(16277215)',
'date' => ':DATE',
'datetime' => ':DATETIME',
'time' => ':TIME',
'timestamp' => ':TIMESTAMP'
];
/**
* Magic Constructor
*/
public function __construct()
{
Support::func('sqlsrv_connect', 'SQL Server');
}
/**
* Connection
*
* @param array $config = []
*/
public function connect($config = [])
{
$this->config = $config;
$server = ( ! empty($this->config['server']) )
? $this->config['server'] // @codeCoverageIgnore
: $this->config['host'];
if( ! empty($this->config['port']) )
{
$server .= ', '.$this->config['port'];
}
$charset = $this->config['charset'] === 'utf8' ? 'utf-8' : $this->config['charset'];
$connection =
[
'UID' => $this->config['user'],
'PWD' => $this->config['password'],
'Database' => $this->config['database'],
'ConnectionPooling' => $this->config['pconnect'] === true ? 1 : 0,
'CharacterSet' => $charset ?: 'utf-8',
'Encrypt' => $this->config['encode'] ?: false,
'ReturnDatesAsStrings' => 1
];
$this->connect = @sqlsrv_connect($server, $connection);
if( empty($this->connect) )
{
throw new ConnectionErrorException(NULL, sqlsrv_errors(SQLSRV_ERR_ERRORS)[0]['message']); // @codeCoverageIgnore
}
}
/**
* Execute
*
* @param string $query
* @param array $security = NULL
*
* @return bool
*/
public function exec($query, $security = NULL)
{
if( empty($query) )
{
return false; // @codeCoverageIgnore
}
return sqlsrv_query($this->connect, $query);
}
/**
* Multiple Queries
*
* @param string $query
* @param array $security = NULL
*
* @return bool
*/
public function multiQuery($query, $security = NULL)
{
return (bool) $this->query($query, $security);
}
/**
* Query
*
* @param string $query
* @param array $security = NULL
*
* @return bool
*/
public function query($query, $security = NULL)
{
return $this->query = $this->exec($query);
}
/**
* Start Transaction Query
*
* @return bool
*/
public function transStart()
{
return sqlsrv_begin_transaction($this->connect);
}
/**
* Rollback Transaction Query
*
* @return bool
*/
public function transRollback()
{
return sqlsrv_rollback($this->connect);
}
/**
* Commit Transaction Query
*
* @return bool
*/
public function transCommit()
{
return sqlsrv_commit($this->connect);
}
/**
* Insert Last ID
*
* @return int|false
*/
public function insertID()
{
$this->query('SELECT @@IDENTITY AS insert_id');
return $this->fetchAssoc()['insert_id'];
}
/**
* Returns column data
*
* @param string $column
*
* @return array|object
*/
public function columnData($col = '')
{
if( empty($this->query) )
{
return false; // @codeCoverageIgnore
}
$columns = [];
foreach( sqlsrv_field_metadata($this->query) as $field )
{
$fieldName = $field['Name'];
$columns[$fieldName] = new stdClass();
$columns[$fieldName]->name = $fieldName;
$columns[$fieldName]->type = $field['Type'];
$columns[$fieldName]->maxLength = $field['Size'];
$columns[$fieldName]->primaryKey = NULL;
$columns[$fieldName]->default = NULL;
}
return $columns[$col] ?? $columns;
}
/**
* Numrows
*
* @return int
*/
public function numRows()
{
$this->query('select @@RowCount');
return $this->fetchRow()[0] ?? false;
}
/**
* Returns columns
*
* @return array
*/
public function columns()
{
if( empty($this->query) )
{
return []; // @codeCoverageIgnore
}
$columns = [];
$getFieldData = sqlsrv_field_metadata($this->query);
foreach( $getFieldData as $field )
{
$columns[] = $field['Name'];
}
return $columns;
}
/**
* Numfields
*
* @return int
*/
public function numFields()
{
if( ! empty($this->query) )
{
return sqlsrv_num_fields($this->query);
}
else
{
return 0; // @codeCoverageIgnore
}
}
/**
* Real Escape String
*
* @param string $data
*
* @return string|false
*/
public function realEscapeString($data)
{
return Security\Injection::escapeStringEncode($data);
}
/**
* Returns a string description of the last error.
*
* @return string|false
*/
public function error()
{
if( ! empty($this->connect) )
{
$error = sqlsrv_errors(SQLSRV_ERR_ERRORS)[0] ?? [];
return ! empty($error['code']) ? ($error['code'] === 15477 ? false : ($error['message'] ?: false)) : false;
}
else
{
return false; // @codeCoverageIgnore
}
}
/**
* Fetch a result row as an associative, a numeric array, or both
*
* @return mixed
*/
public function fetchArray()
{
if( ! empty($this->query) )
{
return sqlsrv_fetch_array($this->query, SQLSRV_FETCH_BOTH);
}
else
{
return []; // @codeCoverageIgnore
}
}
/**
* Fetch a result row as an associative array
*
* @return mixed
*/
public function fetchAssoc()
{
if( ! empty($this->query) )
{
return sqlsrv_fetch_array($this->query, SQLSRV_FETCH_ASSOC);
}
else
{
return []; // @codeCoverageIgnore
}
}
/**
* Get a result row as an enumerated array
*
* @return mixed
*/
public function fetchRow()
{
if( ! empty($this->query) )
{
return sqlsrv_fetch_array($this->query, SQLSRV_FETCH_NUMERIC);
}
else
{
return []; // @codeCoverageIgnore
}
}
/**
* Gets the number of affected rows in a previous MySQL operation
*
* @return int
*/
public function affectedRows()
{
if( ! empty($this->query) )
{
return sqlsrv_rows_affected($this->query);
}
else
{
return 0; // @codeCoverageIgnore
}
}
/**
* Returns the version of the MySQL server as an integer
*
* @return int
*/
public function version()
{
if( ! empty($this->connect) )
{
return sqlsrv_server_info($this->connect)['SQLServerVersion'];
}
else
{
return false; // @codeCoverageIgnore
}
}
/**
* Limit
*
* @param int $start = NULL
* @param int $limit = 0
*
* @return DB
*
* @codeCoverageIgnore
*/
public function limit($start = NULL, int $limit = 0)
{
if( $limit === 0 )
{
$limit = $start;
$start = 0;
}
return ' OFFSET ' . $start . ' ROWS FETCH NEXT ' . $limit . ' ROWS ONLY';
}
/**
* Protected Clean Limit
*
* @codeCoverageIgnore
*/
public function cleanLimit($data)
{
return preg_replace('/OFFSET\s+[0-9]+\s+ROWS\sFETCH\sNEXT\s+[0-9]+\s+ROWS\sONLY/xi', '', $data);
}
/**
* Protected Get Limit Values
*
* @codeCoverageIgnore
*/
public function getLimitValues($data)
{
preg_match('/OFFSET\s+(?<start>[0-9]+)\s+ROWS\sFETCH\sNEXT\s+(?<limit>[0-9]+)\s+ROWS\sONLY/xi', $data ?? '', $match);
return $match;
}
}
@@ -0,0 +1,119 @@
<?php namespace ZN\Database\SQLServer;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Database\DriverForge;
class DBForge extends DriverForge
{
/**
* Unsupported
*/
public function extras($extras)
{
return NULL;
}
/**
* Rename column
*
* @param string $table
* @param array $column
*
* @return string
*/
public function renameColumn($table, $column)
{
return "sp_rename '$table." . key($column) . "', '" . current($column) . "', 'COLUMN';";
}
/**
* Drop index
*
* 5.7.4[added]
*
* @param string $indexName
* @param string $table
*
* @return string
*/
public function dropIndex($indexName, $table)
{
return 'DROP INDEX ' . $table . '.' . $indexName . ';';
}
/**
* Rename Table
*
* @param string $name
* @param string $newname
* 1
* @return string
*/
public function renameTable($name, $newName)
{
return "sp_rename '$name', '$newName';";
}
/**
* Add Column
*
* @param string $table
* @param array $columns
*
* @return string
*/
public function addColumn($table, $columns)
{
return 'ALTER TABLE ' . $table . ' ADD ' . $this->buildForgeColumnsQuery($columns) . ';';
}
/**
* MOdify Column
*
* @param string $table
* @param array $columns
*
* @return string
*/
public function modifyColumn($table, $columns)
{
return 'ALTER TABLE ' . $table . ' ALTER COLUMN ' . $this->buildForgeColumnsQuery($columns) . ';';
}
/**
* Drop Column
*
* @param string $table
* @param array $columns
*
* @return string
*/
public function dropColumn($table, $column)
{
return 'ALTER TABLE ' . $table . ' DROP COLUMN ' . $column . ';';
}
/**
* Create index
*
* 5.7.4[added]
*
* @param string $indexName
* @param string $table
* @param string $columns
*
* @return string
*/
public function createFulltextIndex($indexName, $table, $columns)
{
return false;
}
}
@@ -0,0 +1,70 @@
<?php namespace ZN\Database\SQLServer;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Config;
use ZN\Database\DriverTool;
class DBTool extends DriverTool
{
/**
* List Databases
*
* @return array
*/
public function listDatabases($query = 'SELECT name FROM master.dbo.sysdatabases')
{
return $this->runListQuery($query);
}
/**
* List Tables
*
* @return array
*/
public function listTables($query = "")
{
$query = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_CATALOG='".($this->settings['database'] ?? Config::get('Database', 'database')['database'])."'";
return $this->runListQuery($query);
}
/**
* Unsupported
*/
public function statusTables($table)
{
return false;
}
/**
* Unsupported
*/
public function optimizeTables($table)
{
return false;
}
/**
* Unsupported
*/
public function repairTables($table, $query = '', $message = '')
{
return false;
}
/**
* Unsupported
*/
public function backup($tables, $fileName, $path)
{
return false;
}
}
+416
View File
@@ -0,0 +1,416 @@
<?php namespace ZN\Database\SQLite;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use SQLite3;
use stdClass;
use Exception;
use ZN\Support;
use ZN\ErrorHandling\Errors;
use ZN\Database\DriverMappingAbstract;
use ZN\Database\Exception\ConnectionErrorException;
class DB extends DriverMappingAbstract
{
/**
* Keep Operators
*
* @var array
*/
protected $operators =
[
'like' => '%'
];
/**
* Keep Statements
*
* @var array
*/
protected $statements =
[
'autoincrement' => 'AUTOINCREMENT',
'primarykey' => 'PRIMARY KEY',
'foreignkey' => 'FOREIGN KEY',
'unique' => 'UNIQUE',
'null' => 'NULL',
'notnull' => 'NOT NULL',
'exists' => 'EXISTS',
'notexists' => 'NOT EXISTS',
'constraint' => 'CONSTRAINT',
'default' => 'DEFAULT'
];
/**
* Keep Variable Types
*
* @var array
*/
protected $variableTypes =
[
'int' => ':INTEGER',
'smallint' => ':SMALLINT',
'tinyint' => ':TINYINT',
'mediumint' => ':MEDIUMINT',
'bigint' => ':BIGINT',
'decimal' => 'DECIMAL',
'double' => ':DOUBLE',
'float' => ':FLOAT',
'char' => 'CHARACTER',
'varchar' => 'VARCHAR',
'tinytext' => ':VARCHAR(255)',
'text' => ':TEXT',
'mediumtext' => ':CLOB',
'longtext' => ':BLOB',
'date' => ':DATE',
'datetime' => ':DATETIME',
'time' => ':DATETIME',
'timestamp' => ':DATETIME'
];
/**
* Magic Constructor
*/
public function __construct()
{
Support::extension('SQLite3');
}
/**
* Connection
*
* @param array $config = []
*/
public function connect($config = [])
{
$this->config = $config;
try
{
$this->connect = ( ! empty($this->config['password']) )
? new SQLite3($this->config['database'], SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE, $this->config['password'])
: new SQLite3($this->config['database']);
}
// @codeCoverageIgnoreStart
catch( Exception $e )
{
throw new ConnectionErrorException(NULL, $this->connect->lastErrorMsg());
}
// @codeCoverageIgnoreEnd
}
/**
* Execute
*
* @param string $query
* @param array $security = NULL
*
* @return bool
*/
public function exec($query, $security = NULL)
{
if( empty($query) )
{
return false; // @codeCoverageIgnore
}
return $this->connect->exec($query);
}
/**
* Multiple Queries
*
* @param string $query
* @param array $security = NULL
*
* @return bool
*/
public function multiQuery($query, $security = NULL)
{
return (bool) $this->query($query, $security);
}
/**
* Query
*
* @param string $query
* @param array $security = NULL
*
* @return bool
*/
public function query($query, $security = [])
{
return $this->query = $this->connect->query($query);
}
/**
* Start Transaction Query
*
* @return bool
*/
public function transStart()
{
return $this->connect->exec('BEGIN TRANSACTION');
}
/**
* Rollback Transaction Query
*
* @return bool
*/
public function transRollback()
{
return $this->connect->exec('ROLLBACK');
}
/**
* Commit Transaction Query
*
* @return bool
*/
public function transCommit()
{
return $this->connect->exec('END TRANSACTION');
}
/**
* Insert Last ID
*
* @return int|false
*/
public function insertID()
{
if( empty($this->connect) )
{
return false; // @codeCoverageIgnore
}
return $this->connect->lastInsertRowID();
}
/**
* Returns column data
*
* @param string $column
*
* @return array|object
*/
public function columnData($col = '')
{
if( empty($this->query) )
{
return false; // @codeCoverageIgnore
}
$dataTypes =
[
SQLITE3_INTEGER => 'integer',
SQLITE3_FLOAT => 'float',
SQLITE3_TEXT => 'text',
SQLITE3_BLOB => 'blob',
SQLITE3_NULL => 'null'
];
$columns = [];
$numFields = $this->numFields();
for( $i = 0; $i < $numFields; $i++ )
{
$type = $this->query->columnType($i);
$fieldName = $this->query->columnName($i);
$columns[$fieldName] = new stdClass();
$columns[$fieldName]->name = $fieldName;
$columns[$fieldName]->type = $dataTypes[$type] ?? $type;
$columns[$fieldName]->maxLength = NULL;
$columns[$fieldName]->primaryKey = NULL;
$columns[$fieldName]->default = NULL;
}
return $columns[$col] ?? $columns;
}
/**
* Numrows
*
* @return int
*/
public function numRows()
{
if( ! empty($this->query) )
{
return count($this->result());
}
return 0;
}
/**
* Returns columns
*
* @return array
*/
public function columns()
{
if( empty($this->query) )
{
return [];
}
$columns = [];
$numFields = $this->numFields();
for( $i = 0; $i < $numFields; $i++ )
{
$columns[] = $this->query->columnName($i);
}
return $columns;
}
/**
* Numfields
*
* @return int
*/
public function numFields()
{
if( ! empty($this->query) )
{
return $this->query->numColumns();
}
else
{
return 0;
}
}
/**
* Real Escape String
*
* @param string $data
*
* @return string|false
*/
public function realEscapeString($data)
{
if( empty($this->connect) )
{
return $data; // @codeCoverageIgnore
}
return $this->connect->escapeString($data);
}
/**
* Returns a string description of the last error.
*
* @return string|false
*/
public function error()
{
if( ! empty($this->connect) && $this->connect->lastErrorCode() )
{
return $this->connect->lastErrorMsg();
}
else
{
return false;
}
}
/**
* Fetch a result row as an associative, a numeric array, or both
*
* @return mixed
*/
public function fetchArray()
{
if( ! empty($this->query) )
{
return $this->query->fetchArray(SQLITE3_BOTH);
}
else
{
return []; // @codeCoverageIgnore
}
}
/**
* Fetch a result row as an associative array
*
* @return mixed
*/
public function fetchAssoc()
{
if( ! empty($this->query) )
{
return $this->query->fetchArray(SQLITE3_ASSOC);
}
else
{
return []; // @codeCoverageIgnore
}
}
/**
* Get a result row as an enumerated array
*
* @return mixed
*/
public function fetchRow()
{
if( ! empty($this->query) )
{
return $this->query->fetchArray();
}
else
{
return [];
}
}
/**
* Gets the number of affected rows in a previous MySQL operation
*
* @return int
*/
public function affectedRows()
{
if( ! empty($this->connect) )
{
return $this->connect->changes();
}
else
{
return 0; // @codeCoverageIgnore
}
}
/**
* Returns the version of the MySQL server as an integer
*
* @return int
*/
public function version($v = 'versionString')
{
if( ! empty($this->connect) )
{
$version = SQLite3::version();
return $version[$v];
}
else
{
return false; // @codeCoverageIgnore
}
}
}
@@ -0,0 +1,85 @@
<?php namespace ZN\Database\SQLite;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Database\DriverForge;
class DBForge extends DriverForge
{
/**
* Unsupported
*/
public function extras($extras)
{
return NULL;
}
/**
* Truncate
*
* @param string $table
*
* @return string
*/
public function truncate($table)
{
return 'DELETE FROM '.$table;
}
/**
* Unsupported
*/
public function dropColumn($table, $column)
{
return false;
}
/**
* Unsupported
*/
public function modifyColumn($table, $column)
{
return false;
}
/**
* Unsupported
*/
public function renameColumn($table, $column)
{
return 'ALTER TABLE '.$table.' RENAME COLUMN ' . $this->buildForgeColumnsSyntax($column, 'TO') . ';';
}
/**
* Add column
*
* @param string $table
* @param array $columns
*
* @return string
*/
public function addColumn($table, $columns)
{
return 'ALTER TABLE ' . $table . ' ADD ' . $this->buildForgeColumnsQuery($columns) . ';';
}
/**
* Drop index
*
* @param string $indexName
* @param string $table
*
* @return string
*/
public function dropIndex($indexName, $table)
{
return 'DROP INDEX ' . $indexName . ';';
}
}
@@ -0,0 +1,67 @@
<?php namespace ZN\Database\SQLite;
/**
* ZN PHP Web Framework
*
* "Simplicity is the ultimate sophistication." ~ Da Vinci
*
* @package ZN
* @license MIT [http://opensource.org/licenses/MIT]
* @author Ozan UYKUN [ozan@znframework.com]
*/
use ZN\Database\DriverTool, Config;
class DBTool extends DriverTool
{
/**
* List Databases
*
* @return array
*/
public function listDatabases($query = "")
{
return [Config::get('Database', 'database')['database']];
}
/**
* List Tables
*
* @return array
*/
public function listTables($query = "SELECT name FROM sqlite_master WHERE type = 'table'")
{
return $this->runListQuery($query);
}
/**
* Unsupported
*/
public function statusTables($table)
{
return false;
}
/**
* Unsupported
*/
public function optimizeTables($table)
{
return false;
}
/**
* Unsupported
*/
public function repairTables($table, $query = '', $message = '')
{
return false;
}
/**
* Unsupported
*/
public function backup($tables, $fileName, $path)
{
return false;
}
}