diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 2346d54d..00000000
--- a/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-[MIT LICENSE]
-
-Copyright (c) 2017 Angel Lai, https://medoo.in
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-Software), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, andor sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 00000000..aaf1c4b3
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 Angel Lai
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
index cb0e0858..f31e1d06 100644
--- a/README.md
+++ b/README.md
@@ -1,26 +1,28 @@
-![](https://cloud.githubusercontent.com/assets/1467904/19835326/ca62bc36-9ebd-11e6-8b37-7240d76319cd.png)
+
+
+
-## [Medoo](https://medoo.in)
-
-[![Total Downloads](https://poser.pugx.org/catfan/medoo/downloads)](https://packagist.org/packages/catfan/medoo)
-[![Latest Stable Version](https://poser.pugx.org/catfan/medoo/v/stable)](https://packagist.org/packages/catfan/medoo)
-[![License](https://poser.pugx.org/catfan/medoo/license)](https://packagist.org/packages/catfan/medoo)
+
+
+
+
+
> The Lightest PHP database framework to accelerate development
-## Main Features
+## Features
-* **Lightweight** - 32KB around with only one file.
+* **Lightweight** - Less than 100 KB, portable with only one file
-* **Easy** - Extremely easy to learn and use, friendly construction.
+* **Easy** - Extremely easy to learn and use, friendly construction
-* **Powerful** - Supports various common and complex SQL queries, data mapping, and prevent SQL injection.
+* **Powerful** - Supports various common and complex SQL queries, data mapping, and prevent SQL injection
-* **Compatible** - Supports all SQL databases, including MySQL, MSSQL, SQLite, MariaDB, Sybase, Oracle, PostgreSQL and more.
+* **Compatible** - Supports all SQL databases, including MySQL, MSSQL, SQLite, MariaDB, PostgreSQL, Sybase, Oracle and more
-* **Friendly** - Works well with every PHP frameworks, like Laravel, Codeigniter, Yii, Slim, and framework which supports singleton extension.
+* **Friendly** - Works well with every PHP frameworks, like Laravel, Codeigniter, Yii, Slim, and framework which supports singleton extension or composer
-* **Free** - Under MIT license, you can use it anywhere if you want.
+* **Free** - Under MIT license, you can use it anywhere whatever you want
## Requirement
diff --git a/composer.json b/composer.json
index 81b73cee..39c1a9de 100644
--- a/composer.json
+++ b/composer.json
@@ -5,6 +5,10 @@
"keywords": ["database", "lightweight", "PHP framework", "SQL", "MySQL", "MSSQL", "SQLite", "PostgreSQL", "MariaDB", "Oracle"],
"homepage": "https://medoo.in",
"license": "MIT",
+ "support": {
+ "issues": "https://github.com/catfan/Medoo/issues",
+ "source": "https://github.com/catfan/Medoo"
+ },
"authors": [
{"name": "Angel Lai", "email": "angel@catfan.me"}
],
@@ -14,7 +18,7 @@
},
"suggest": {
"ext-pdo_mysql": "For MySQL or MariaDB database",
- "ext-pdo_sqlsrv": "For MSSQL database on Windows platform",
+ "ext-pdo_sqlsrv": "For MSSQL database",
"ext-pdo_dblib": "For MSSQL or Sybase database on Linux/UNIX platform",
"ext-pdo_oci": "For Oracle database",
"ext-pdo_oci8": "For Oracle version 8 database",
diff --git a/src/Medoo.php b/src/Medoo.php
index 097d998d..762bfca7 100644
--- a/src/Medoo.php
+++ b/src/Medoo.php
@@ -2,7 +2,7 @@
/*!
* Medoo database framework
* https://medoo.in
- * Version 1.4.5
+ * Version 1.5
*
* Copyright 2017, Angel Lai
* Released under the MIT license
@@ -14,9 +14,16 @@
use Exception;
use PDOException;
+class Raw {
+ public $map;
+ public $value;
+}
+
class Medoo
{
- protected $database_type;
+ public $pdo;
+
+ protected $type;
protected $prefix;
@@ -34,200 +41,192 @@ class Medoo
public function __construct($options = null)
{
- try {
- if (is_array($options))
- {
- if (isset($options[ 'database_type' ]))
- {
- $this->database_type = strtolower($options[ 'database_type' ]);
- }
- }
- else
- {
- return false;
- }
+ if (!is_array($options))
+ {
+ return false;
+ }
- if (isset($options[ 'prefix' ]))
- {
- $this->prefix = $options[ 'prefix' ];
- }
+ if (isset($options[ 'database_type' ]))
+ {
+ $this->type = strtolower($options[ 'database_type' ]);
+ }
- if (isset($options[ 'option' ]))
- {
- $this->option = $options[ 'option' ];
- }
+ if (isset($options[ 'prefix' ]))
+ {
+ $this->prefix = $options[ 'prefix' ];
+ }
- if (isset($options[ 'logging' ]) && is_bool($options[ 'logging' ]))
- {
- $this->logging = $options[ 'logging' ];
- }
+ if (isset($options[ 'option' ]))
+ {
+ $this->option = $options[ 'option' ];
+ }
- if (isset($options[ 'command' ]) && is_array($options[ 'command' ]))
- {
- $commands = $options[ 'command' ];
- }
- else
+ if (isset($options[ 'logging' ]) && is_bool($options[ 'logging' ]))
+ {
+ $this->logging = $options[ 'logging' ];
+ }
+
+ if (isset($options[ 'command' ]) && is_array($options[ 'command' ]))
+ {
+ $commands = $options[ 'command' ];
+ }
+ else
+ {
+ $commands = [];
+ }
+
+ if (isset($options[ 'dsn' ]))
+ {
+ if (is_array($options[ 'dsn' ]) && isset($options[ 'dsn' ][ 'driver' ]))
{
- $commands = [];
+ $attr = $options[ 'dsn' ];
}
- if (isset($options[ 'dsn' ]))
+ return false;
+ }
+ else
+ {
+ if (
+ isset($options[ 'port' ]) &&
+ is_int($options[ 'port' ] * 1)
+ )
{
- if (isset($options[ 'dsn' ][ 'driver' ]))
- {
- $attr = $options[ 'dsn' ];
- }
- else
- {
- return false;
- }
+ $port = $options[ 'port' ];
}
- else
- {
- if (
- isset($options[ 'port' ]) &&
- is_int($options[ 'port' ] * 1)
- )
- {
- $port = $options[ 'port' ];
- }
- $is_port = isset($port);
+ $is_port = isset($port);
- switch ($this->database_type)
- {
- case 'mariadb':
- case 'mysql':
- $attr = [
- 'driver' => 'mysql',
- 'dbname' => $options[ 'database_name' ]
- ];
+ switch ($this->type)
+ {
+ case 'mariadb':
+ case 'mysql':
+ $attr = [
+ 'driver' => 'mysql',
+ 'dbname' => $options[ 'database_name' ]
+ ];
- if (isset($options[ 'socket' ]))
+ if (isset($options[ 'socket' ]))
+ {
+ $attr[ 'unix_socket' ] = $options[ 'socket' ];
+ }
+ else
+ {
+ $attr[ 'host' ] = $options[ 'server' ];
+
+ if ($is_port)
{
- $attr[ 'unix_socket' ] = $options[ 'socket' ];
+ $attr[ 'port' ] = $port;
}
- else
- {
- $attr[ 'host' ] = $options[ 'server' ];
+ }
- if ($is_port)
- {
- $attr[ 'port' ] = $port;
- }
- }
+ // Make MySQL using standard quoted identifier
+ $commands[] = 'SET SQL_MODE=ANSI_QUOTES';
+ break;
- // Make MySQL using standard quoted identifier
- $commands[] = 'SET SQL_MODE=ANSI_QUOTES';
- break;
+ case 'pgsql':
+ $attr = [
+ 'driver' => 'pgsql',
+ 'host' => $options[ 'server' ],
+ 'dbname' => $options[ 'database_name' ]
+ ];
- case 'pgsql':
- $attr = [
- 'driver' => 'pgsql',
- 'host' => $options[ 'server' ],
- 'dbname' => $options[ 'database_name' ]
- ];
+ if ($is_port)
+ {
+ $attr[ 'port' ] = $port;
+ }
- if ($is_port)
- {
- $attr[ 'port' ] = $port;
- }
+ break;
- break;
+ case 'sybase':
+ $attr = [
+ 'driver' => 'dblib',
+ 'host' => $options[ 'server' ],
+ 'dbname' => $options[ 'database_name' ]
+ ];
+
+ if ($is_port)
+ {
+ $attr[ 'port' ] = $port;
+ }
- case 'sybase':
+ break;
+
+ case 'oracle':
+ $attr = [
+ 'driver' => 'oci',
+ 'dbname' => $options[ 'server' ] ?
+ '//' . $options[ 'server' ] . ($is_port ? ':' . $port : ':1521') . '/' . $options[ 'database_name' ] :
+ $options[ 'database_name' ]
+ ];
+
+ if (isset($options[ 'charset' ]))
+ {
+ $attr[ 'charset' ] = $options[ 'charset' ];
+ }
+
+ break;
+
+ case 'mssql':
+ if (isset($options[ 'driver' ]) && $options[ 'driver' ] === 'dblib')
+ {
$attr = [
'driver' => 'dblib',
- 'host' => $options[ 'server' ],
+ 'host' => $options[ 'server' ] . ($is_port ? ':' . $port : ''),
'dbname' => $options[ 'database_name' ]
];
-
- if ($is_port)
- {
- $attr[ 'port' ] = $port;
- }
-
- break;
-
- case 'oracle':
+ }
+ else
+ {
$attr = [
- 'driver' => 'oci',
- 'dbname' => $options[ 'server' ] ?
- '//' . $options[ 'server' ] . ($is_port ? ':' . $port : ':1521') . '/' . $options[ 'database_name' ] :
- $options[ 'database_name' ]
+ 'driver' => 'sqlsrv',
+ 'Server' => $options[ 'server' ] . ($is_port ? ',' . $port : ''),
+ 'Database' => $options[ 'database_name' ]
];
+ }
- if (isset($options[ 'charset' ]))
- {
- $attr[ 'charset' ] = $options[ 'charset' ];
- }
-
- break;
-
- case 'mssql':
- if (strstr(PHP_OS, 'WIN'))
- {
- $attr = [
- 'driver' => 'sqlsrv',
- 'Server' => $options[ 'server' ] . ($is_port ? ',' . $port : ''),
- 'Database' => $options[ 'database_name' ]
- ];
- }
- else
- {
- $attr = [
- 'driver' => 'dblib',
- 'host' => $options[ 'server' ] . ($is_port ? ':' . $port : ''),
- 'dbname' => $options[ 'database_name' ]
- ];
- }
-
- // Keep MSSQL QUOTED_IDENTIFIER is ON for standard quoting
- $commands[] = 'SET QUOTED_IDENTIFIER ON';
+ // Keep MSSQL QUOTED_IDENTIFIER is ON for standard quoting
+ $commands[] = 'SET QUOTED_IDENTIFIER ON';
- // Make ANSI_NULLS is ON for NULL value
- $commands[] = 'SET ANSI_NULLS ON';
- break;
+ // Make ANSI_NULLS is ON for NULL value
+ $commands[] = 'SET ANSI_NULLS ON';
+ break;
- case 'sqlite':
- $this->pdo = new PDO('sqlite:' . $options[ 'database_file' ], null, null, $this->option);
+ case 'sqlite':
+ $attr = [
+ 'driver' => 'sqlite',
+ $options[ 'database_file' ]
+ ];
- return;
- }
+ break;
}
+ }
- $driver = $attr[ 'driver' ];
+ $driver = $attr[ 'driver' ];
- unset($attr[ 'driver' ]);
+ unset($attr[ 'driver' ]);
- $stack = [];
+ $stack = [];
- foreach ($attr as $key => $value)
- {
- if (is_int($key))
- {
- $stack[] = $value;
- }
- else
- {
- $stack[] = $key . '=' . $value;
- }
- }
+ foreach ($attr as $key => $value)
+ {
+ $stack[] = is_int($key) ? $value : $key . '=' . $value;
+ }
- $dsn = $driver . ':' . implode($stack, ';');
+ $dsn = $driver . ':' . implode($stack, ';');
- if (
- in_array($this->database_type, ['mariadb', 'mysql', 'pgsql', 'sybase', 'mssql']) &&
- isset($options[ 'charset' ])
- )
- {
- $commands[] = "SET NAMES '" . $options[ 'charset' ] . "'";
- }
+ if (
+ in_array($this->type, ['mariadb', 'mysql', 'pgsql', 'sybase', 'mssql']) &&
+ isset($options[ 'charset' ])
+ )
+ {
+ $commands[] = "SET NAMES '" . $options[ 'charset' ] . "'";
+ }
+ try {
$this->pdo = new PDO(
$dsn,
- $options[ 'username' ],
- $options[ 'password' ],
+ isset($options[ 'username' ]) ? $options[ 'username' ] : null,
+ isset($options[ 'password' ]) ? $options[ 'password' ] : null,
$this->option
);
@@ -237,41 +236,27 @@ public function __construct($options = null)
}
}
catch (PDOException $e) {
- throw new Exception($e->getMessage());
+ throw new PDOException($e->getMessage());
}
}
- public function query($query, $map = [])
+ public function __call($name, $arguments)
{
- if (!empty($map))
- {
- foreach ($map as $key => $value)
- {
- switch (gettype($value))
- {
- case 'NULL':
- $map[ $key ] = [null, PDO::PARAM_NULL];
- break;
+ $aggregation = ['avg', 'count', 'max', 'min', 'sum'];
- case 'resource':
- $map[ $key ] = [$value, PDO::PARAM_LOB];
- break;
+ if (in_array($name, $aggregation))
+ {
+ array_unshift($arguments, $name);
- case 'boolean':
- $map[ $key ] = [($value ? '1' : '0'), PDO::PARAM_BOOL];
- break;
+ return call_user_func_array([$this, 'aggregate'], $arguments);
+ }
+ }
- case 'integer':
- case 'double':
- $map[ $key ] = [$value, PDO::PARAM_INT];
- break;
+ public function query($query, $map = [])
+ {
+ $raw = $this->raw($query, $map);
- case 'string':
- $map[ $key ] = [$value, PDO::PARAM_STR];
- break;
- }
- }
- }
+ $query = $this->buildRaw($raw, $map);
return $this->exec($query, $map);
}
@@ -311,28 +296,94 @@ public function exec($query, $map = [])
return $statement;
}
- else
- {
- return false;
- }
+
+ return false;
}
protected function generate($query, $map)
{
+ $identifier = [
+ 'mysql' => '`$1`',
+ 'mariadb' => '`$1`',
+ 'mssql' => '[$1]'
+ ];
+
+ $query = preg_replace(
+ '/"([a-zA-Z0-9_]+)"/i',
+ isset($identifier[ $this->type ]) ? $identifier[ $this->type ] : '"$1"',
+ $query
+ );
+
foreach ($map as $key => $value)
{
if ($value[ 1 ] === PDO::PARAM_STR)
{
- $query = str_replace($key, $this->quote($value[ 0 ]), $query);
+ $replace = $this->quote($value[ 0 ]);
}
elseif ($value[ 1 ] === PDO::PARAM_NULL)
{
- $query = str_replace($key, 'NULL', $query);
+ $replace = 'NULL';
+ }
+ elseif ($value[ 1 ] === PDO::PARAM_LOB)
+ {
+ $replace = '{LOB_DATA}';
}
else
{
- $query = str_replace($key, $value[ 0 ], $query);
+ $replace = $value[ 0 ];
}
+
+ $query = str_replace($key, $replace, $query);
+ }
+
+ return $query;
+ }
+
+ public static function raw($string, $map = [])
+ {
+ $raw = new Raw();
+
+ $raw->map = $map;
+ $raw->value = $string;
+
+ return $raw;
+ }
+
+ protected function isRaw($object)
+ {
+ return $object instanceof Raw;
+ }
+
+ protected function buildRaw($raw, &$map)
+ {
+ if (!$this->isRaw($raw))
+ {
+ return false;
+ }
+
+ $query = preg_replace_callback(
+ '/((FROM|TABLE|INTO|UPDATE)\s*)?\<([a-zA-Z0-9_\.]+)\>/i',
+ function ($matches)
+ {
+ if (!empty($matches[ 2 ]))
+ {
+ return $matches[ 2 ] . ' ' . $this->tableQuote($matches[ 3 ]);
+ }
+
+ return $this->columnQuote($matches[ 3 ]);
+ },
+ $raw->value);
+
+ $raw_map = $raw->map;
+
+ if (!empty($raw_map))
+ {
+ foreach ($raw_map as $key => $value)
+ {
+ $raw_map[ $key ] = $this->typeMap($value, gettype($value));
+ }
+
+ $map = $raw_map;
}
return $query;
@@ -353,19 +404,41 @@ protected function mapKey()
return ':MeDoO_' . $this->guid++ . '_mEdOo';
}
- protected function columnQuote($string)
+ protected function typeMap($value, $type)
{
- preg_match('/(^#)?([a-zA-Z0-9_]*)\.([a-zA-Z0-9_]*)(\s*\[JSON\]$)?/', $string, $column_match);
+ $map = [
+ 'NULL' => PDO::PARAM_NULL,
+ 'integer' => PDO::PARAM_INT,
+ 'double' => PDO::PARAM_STR,
+ 'boolean' => PDO::PARAM_BOOL,
+ 'string' => PDO::PARAM_STR,
+ 'object' => PDO::PARAM_STR,
+ 'resource' => PDO::PARAM_LOB
+ ];
- if (isset($column_match[ 2 ], $column_match[ 3 ]))
+ if ($type === 'boolean')
{
- return '"' . $this->prefix . $column_match[ 2 ] . '"."' . $column_match[ 3 ] . '"';
+ $value = ($value ? '1' : '0');
+ }
+ elseif ($type === 'NULL')
+ {
+ $value = null;
+ }
+
+ return [$value, $map[ $type ]];
+ }
+
+ protected function columnQuote($string)
+ {
+ if (strpos($string, '.') !== false)
+ {
+ return '"' . $this->prefix . str_replace('.', '"."', $string) . '"';
}
return '"' . $string . '"';
}
- protected function columnPush(&$columns)
+ protected function columnPush(&$columns, &$map)
{
if ($columns === '*')
{
@@ -383,17 +456,28 @@ protected function columnPush(&$columns)
{
if (is_array($value))
{
- $stack[] = $this->columnPush($value);
+ $stack[] = $this->columnPush($value, $map);
}
- else
+ elseif (!is_int($key) && $raw = $this->buildRaw($value, $map))
+ {
+ preg_match('/(?[a-zA-Z0-9_\.]+)(\s*\[(?(String|Bool|Int|Number))\])?/i', $key, $match);
+
+ $stack[] = $raw . ' AS ' . $this->columnQuote( $match[ 'column' ] );
+ }
+ elseif (is_int($key) && is_string($value))
{
- preg_match('/(?[a-zA-Z0-9_\.]+)(?:\s*\((?[a-zA-Z0-9_]+)\)|\s*\[(?(String|Bool|Int|Number|Object|JSON))\])?/i', $value, $match);
+ preg_match('/(?[a-zA-Z0-9_\.]+)(?:\s*\((?[a-zA-Z0-9_]+)\))?(?:\s*\[(?(?:String|Bool|Int|Number|Object|JSON))\])?/i', $value, $match);
if (!empty($match[ 'alias' ]))
{
$stack[] = $this->columnQuote( $match[ 'column' ] ) . ' AS ' . $this->columnQuote( $match[ 'alias' ] );
$columns[ $key ] = $match[ 'alias' ];
+
+ if (!empty($match[ 'type' ]))
+ {
+ $columns[ $key ] .= ' [' . $match[ 'type' ] . ']';
+ }
}
else
{
@@ -429,198 +513,209 @@ protected function innerConjunct($data, $map, $conjunctor, $outer_conjunctor)
return implode($outer_conjunctor . ' ', $stack);
}
- protected function fnQuote($column, $string)
- {
- return (strpos($column, '#') === 0 && preg_match('/^[A-Z0-9\_]*\([^)]*\)$/', $string)) ?
-
- $string :
-
- $this->quote($string);
- }
-
protected function dataImplode($data, &$map, $conjunctor)
{
- $wheres = [];
+ $stack = [];
foreach ($data as $key => $value)
{
- $map_key = $this->mapKey();
-
$type = gettype($value);
+ if ($type === 'array')
+ {
+ $relationship = strpos($key, 'AND', 0) !== false ? 'AND' :
+ (strpos($key, 'OR', 0) !== false ? 'OR' : false);
+
+ if ($relationship)
+ {
+ $stack[] = !empty(array_diff_key($value, array_keys(array_keys($value)))) ?
+ '(' . $this->dataImplode($value, $map, ' ' . $relationship) . ')' :
+ '(' . $this->innerConjunct($value, $map, ' ' . $relationship, $conjunctor) . ')';
+
+ continue;
+ }
+ }
+
+ $map_key = $this->mapKey();
+
if (
- preg_match("/^(AND|OR)(\s+#.*)?$/i", $key, $relation_match) &&
- $type === 'array'
+ is_int($key) &&
+ preg_match('/([a-zA-Z0-9_\.]+)\[(?\>\=?|\<\=?|\!|\=)\]([a-zA-Z0-9_\.]+)/i', $value, $match)
)
{
- $wheres[] = 0 !== count(array_diff_key($value, array_keys(array_keys($value)))) ?
- '(' . $this->dataImplode($value, $map, ' ' . $relation_match[ 1 ]) . ')' :
- '(' . $this->innerConjunct($value, $map, ' ' . $relation_match[ 1 ], $conjunctor) . ')';
+ $stack[] = $this->columnQuote($match[ 1 ]) . ' ' . $match[ 'operator' ] . ' ' . $this->columnQuote($match[ 3 ]);
}
else
{
- if (
- is_int($key) &&
- preg_match('/([a-zA-Z0-9_\.]+)\[(?\>|\>\=|\<|\<\=|\!|\=)\]([a-zA-Z0-9_\.]+)/i', $value, $match)
- )
- {
- $wheres[] = $this->columnQuote($match[ 1 ]) . ' ' . $match[ 'operator' ] . ' ' . $this->columnQuote($match[ 3 ]);
- }
- else
+ preg_match('/([a-zA-Z0-9_\.]+)(\[(?\>\=?|\<\=?|\!|\<\>|\>\<|\!?~|REGEXP)\])?/i', $key, $match);
+ $column = $this->columnQuote($match[ 1 ]);
+
+ if (isset($match[ 'operator' ]))
{
- preg_match('/(#?)([a-zA-Z0-9_\.]+)(\[(?\>|\>\=|\<|\<\=|\!|\<\>|\>\<|\!?~)\])?/i', $key, $match);
- $column = $this->columnQuote($match[ 2 ]);
+ $operator = $match[ 'operator' ];
- if (!empty($match[ 1 ]))
+ if (in_array($operator, ['>', '>=', '<', '<=']))
{
- $wheres[] = $column .
- (isset($match[ 'operator' ]) ? ' ' . $match[ 'operator' ] . ' ' : ' = ') .
- $this->fnQuote($key, $value);
+ $condition = $column . ' ' . $operator . ' ';
+
+ if (is_numeric($value))
+ {
+ $condition .= $map_key;
+ $map[ $map_key ] = [$value, PDO::PARAM_INT];
+ }
+ elseif ($raw = $this->buildRaw($value, $map))
+ {
+ $condition .= $raw;
+ }
+ else
+ {
+ $condition .= $map_key;
+ $map[ $map_key ] = [$value, PDO::PARAM_STR];
+ }
- continue;
+ $stack[] = $condition;
}
-
- if (isset($match[ 'operator' ]))
+ elseif ($operator === '!')
{
- $operator = $match[ 'operator' ];
-
- if ($operator === '!')
+ switch ($type)
{
- switch ($type)
- {
- case 'NULL':
- $wheres[] = $column . ' IS NOT NULL';
- break;
-
- case 'array':
- $wheres[] = $column . ' NOT IN (' . $this->arrayQuote($value) . ')';
- break;
-
- case 'integer':
- case 'double':
- $wheres[] = $column . ' != ' . $map_key;
- $map[ $map_key ] = [$value, PDO::PARAM_INT];
- break;
-
- case 'boolean':
- $wheres[] = $column . ' != ' . $map_key;
- $map[ $map_key ] = [($value ? '1' : '0'), PDO::PARAM_BOOL];
- break;
-
- case 'string':
- $wheres[] = $column . ' != ' . $map_key;
- $map[ $map_key ] = [$value, PDO::PARAM_STR];
- break;
- }
- }
+ case 'NULL':
+ $stack[] = $column . ' IS NOT NULL';
+ break;
- if ($operator === '<>' || $operator === '><')
- {
- if ($type === 'array')
- {
- if ($operator === '><')
+ case 'array':
+ $placeholders = [];
+
+ foreach ($value as $index => $item)
{
- $column .= ' NOT';
+ $placeholders[] = $map_key . $index;
+ $map[ $map_key . $index ] = [
+ $item,
+ $this->typeMap($item, gettype($item))
+ ];
}
- $wheres[] = '(' . $column . ' BETWEEN ' . $map_key . 'a AND ' . $map_key . 'b)';
+ $stack[] = $column . ' NOT IN (' . implode(', ', $placeholders) . ')';
+ break;
- $data_type = (is_numeric($value[ 0 ]) && is_numeric($value[ 1 ])) ? PDO::PARAM_INT : PDO::PARAM_STR;
+ case 'object':
+ if ($raw = $this->buildRaw($value, $map))
+ {
+ $stack[] = $column . ' != ' . $raw;
+ }
+ break;
- $map[ $map_key . 'a' ] = [$value[ 0 ], $data_type];
- $map[ $map_key . 'b' ] = [$value[ 1 ], $data_type];
- }
+ case 'integer':
+ case 'double':
+ case 'boolean':
+ case 'string':
+ $stack[] = $column . ' != ' . $map_key;
+ $map[ $map_key ] = $this->typeMap($value, $type);
+ break;
}
-
- if ($operator === '~' || $operator === '!~')
+ }
+ elseif ($operator === '~' || $operator === '!~')
+ {
+ if ($type !== 'array')
{
- if ($type !== 'array')
- {
- $value = [ $value ];
- }
+ $value = [ $value ];
+ }
- $connector = ' OR ';
- $stack = array_values($value);
+ $connector = ' OR ';
+ $data = array_values($value);
- if (is_array($stack[ 0 ]))
+ if (is_array($data[ 0 ]))
+ {
+ if (isset($value[ 'AND' ]) || isset($value[ 'OR' ]))
{
- if (isset($value[ 'AND' ]) || isset($value[ 'OR' ]))
- {
- $connector = ' ' . array_keys($value)[ 0 ] . ' ';
- $value = $stack[ 0 ];
- }
+ $connector = ' ' . array_keys($value)[ 0 ] . ' ';
+ $value = $data[ 0 ];
}
+ }
- $like_clauses = [];
-
- foreach ($value as $index => $item)
- {
- $item = strval($item);
+ $like_clauses = [];
- if (!preg_match('/(\[.+\]|_|%.+|.+%)/', $item))
- {
- $item = '%' . $item . '%';
- }
+ foreach ($value as $index => $item)
+ {
+ $item = strval($item);
- $like_clauses[] = $column . ($operator === '!~' ? ' NOT' : '') . ' LIKE ' . $map_key . 'L' . $index;
- $map[ $map_key . 'L' . $index ] = [$item, PDO::PARAM_STR];
+ if (!preg_match('/(\[.+\]|_|%.+|.+%)/', $item))
+ {
+ $item = '%' . $item . '%';
}
- $wheres[] = '(' . implode($connector, $like_clauses) . ')';
+ $like_clauses[] = $column . ($operator === '!~' ? ' NOT' : '') . ' LIKE ' . $map_key . 'L' . $index;
+ $map[ $map_key . 'L' . $index ] = [$item, PDO::PARAM_STR];
}
- if (in_array($operator, ['>', '>=', '<', '<=']))
+ $stack[] = '(' . implode($connector, $like_clauses) . ')';
+ }
+ elseif ($operator === '<>' || $operator === '><')
+ {
+ if ($type === 'array')
{
- $condition = $column . ' ' . $operator . ' ';
-
- if (is_numeric($value))
+ if ($operator === '><')
{
- $condition .= $map_key;
- $map[ $map_key ] = [$value, PDO::PARAM_INT];
- }
- else
- {
- $condition .= $map_key;
- $map[ $map_key ] = [$value, PDO::PARAM_STR];
+ $column .= ' NOT';
}
- $wheres[] = $condition;
+ $stack[] = '(' . $column . ' BETWEEN ' . $map_key . 'a AND ' . $map_key . 'b)';
+
+ $data_type = (is_numeric($value[ 0 ]) && is_numeric($value[ 1 ])) ? PDO::PARAM_INT : PDO::PARAM_STR;
+
+ $map[ $map_key . 'a' ] = [$value[ 0 ], $data_type];
+ $map[ $map_key . 'b' ] = [$value[ 1 ], $data_type];
}
}
- else
+ elseif ($operator === 'REGEXP')
{
- switch ($type)
- {
- case 'NULL':
- $wheres[] = $column . ' IS NULL';
- break;
+ $stack[] = $column . ' REGEXP ' . $map_key;
+ $map[ $map_key ] = [$value, PDO::PARAM_STR];
+ }
+ }
+ else
+ {
+ switch ($type)
+ {
+ case 'NULL':
+ $stack[] = $column . ' IS NULL';
+ break;
- case 'array':
- $wheres[] = $column . ' IN (' . $this->arrayQuote($value) . ')';
- break;
+ case 'array':
+ $placeholders = [];
- case 'integer':
- case 'double':
- $wheres[] = $column . ' = ' . $map_key;
- $map[ $map_key ] = [$value, PDO::PARAM_INT];
- break;
+ foreach ($value as $index => $item)
+ {
+ $placeholders[] = $map_key . $index;
+ $map[ $map_key . $index ] = [
+ $item,
+ $this->typeMap($item, gettype($item))
+ ];
+ }
- case 'boolean':
- $wheres[] = $column . ' = ' . $map_key;
- $map[ $map_key ] = [($value ? '1' : '0'), PDO::PARAM_BOOL];
- break;
+ $stack[] = $column . ' IN (' . implode(', ', $placeholders) . ')';
+ break;
- case 'string':
- $wheres[] = $column . ' = ' . $map_key;
- $map[ $map_key ] = [$value, PDO::PARAM_STR];
- break;
- }
+ case 'object':
+ if ($raw = $this->buildRaw($value, $map))
+ {
+ $stack[] = $column . ' = ' . $raw;
+ }
+ break;
+
+ case 'integer':
+ case 'double':
+ case 'boolean':
+ case 'string':
+ $stack[] = $column . ' = ' . $map_key;
+ $map[ $map_key ] = $this->typeMap($value, $type);
+ break;
}
}
}
}
- return implode($conjunctor . ' ', $wheres);
+ return implode($conjunctor . ' ', $stack);
}
protected function whereClause($where, &$map)
@@ -630,33 +725,14 @@ protected function whereClause($where, &$map)
if (is_array($where))
{
$where_keys = array_keys($where);
- $where_AND = preg_grep("/^AND\s*#?$/i", $where_keys);
- $where_OR = preg_grep("/^OR\s*#?$/i", $where_keys);
- $single_condition = array_diff_key($where, array_flip(
- ['AND', 'OR', 'GROUP', 'ORDER', 'HAVING', 'LIMIT', 'LIKE', 'MATCH']
+ $conditions = array_diff_key($where, array_flip(
+ ['GROUP', 'ORDER', 'HAVING', 'LIMIT', 'LIKE', 'MATCH']
));
- if (!empty($single_condition))
- {
- $condition = $this->dataImplode($single_condition, $map, ' AND');
-
- if ($condition !== '')
- {
- $where_clause = ' WHERE ' . $condition;
- }
- }
-
- if (!empty($where_AND))
+ if (!empty($conditions))
{
- $value = array_values($where_AND);
- $where_clause = ' WHERE ' . $this->dataImplode($where[ $value[ 0 ] ], $map, ' AND');
- }
-
- if (!empty($where_OR))
- {
- $value = array_values($where_OR);
- $where_clause = ' WHERE ' . $this->dataImplode($where[ $value[ 0 ] ], $map, ' OR');
+ $where_clause = ' WHERE ' . $this->dataImplode($conditions, $map, ' AND');
}
if (isset($where[ 'MATCH' ]))
@@ -702,14 +778,25 @@ protected function whereClause($where, &$map)
$where_clause .= ' GROUP BY ' . implode($stack, ',');
}
+ elseif ($raw = $this->buildRaw($GROUP, $map))
+ {
+ $where_clause .= ' GROUP BY ' . $raw;
+ }
else
{
- $where_clause .= ' GROUP BY ' . $this->columnQuote($where[ 'GROUP' ]);
+ $where_clause .= ' GROUP BY ' . $this->columnQuote($GROUP);
}
if (isset($where[ 'HAVING' ]))
{
- $where_clause .= ' HAVING ' . $this->dataImplode($where[ 'HAVING' ], $map, ' AND');
+ if ($raw = $this->buildRaw($where[ 'HAVING' ], $map))
+ {
+ $where_clause .= ' HAVING ' . $raw;
+ }
+ else
+ {
+ $where_clause .= ' HAVING ' . $this->dataImplode($where[ 'HAVING' ], $map, ' AND');
+ }
}
}
@@ -739,6 +826,10 @@ protected function whereClause($where, &$map)
$where_clause .= ' ORDER BY ' . implode($stack, ',');
}
+ elseif ($raw = $this->buildRaw($ORDER, $map))
+ {
+ $where_clause .= ' ORDER BY ' . $raw;
+ }
else
{
$where_clause .= ' ORDER BY ' . $this->columnQuote($ORDER);
@@ -746,16 +837,16 @@ protected function whereClause($where, &$map)
if (
isset($where[ 'LIMIT' ]) &&
- in_array($this->database_type, ['oracle', 'mssql'])
+ in_array($this->type, ['oracle', 'mssql'])
)
{
$LIMIT = $where[ 'LIMIT' ];
if (is_numeric($LIMIT))
{
- $where_clause .= ' FETCH FIRST ' . $LIMIT . ' ROWS ONLY';
+ $LIMIT = [0, $LIMIT];
}
-
+
if (
is_array($LIMIT) &&
is_numeric($LIMIT[ 0 ]) &&
@@ -767,7 +858,7 @@ protected function whereClause($where, &$map)
}
}
- if (isset($where[ 'LIMIT' ]) && !in_array($this->database_type, ['oracle', 'mssql']))
+ if (isset($where[ 'LIMIT' ]) && !in_array($this->type, ['oracle', 'mssql']))
{
$LIMIT = $where[ 'LIMIT' ];
@@ -775,8 +866,7 @@ protected function whereClause($where, &$map)
{
$where_clause .= ' LIMIT ' . $LIMIT;
}
-
- if (
+ elseif (
is_array($LIMIT) &&
is_numeric($LIMIT[ 0 ]) &&
is_numeric($LIMIT[ 1 ])
@@ -786,12 +876,9 @@ protected function whereClause($where, &$map)
}
}
}
- else
+ elseif ($raw = $this->buildRaw($where, $map))
{
- if ($where !== null)
- {
- $where_clause .= ' ' . $where;
- }
+ $where_clause .= ' ' . $raw;
}
return $where_clause;
@@ -832,7 +919,7 @@ protected function selectContext($table, &$map, $join, &$columns = null, $where
foreach($join as $sub_table => $relation)
{
- preg_match('/(\[(?\<|\>|\>\<|\<\>)\])?(?[a-zA-Z0-9_]+)\s?(\((?[a-zA-Z0-9_]+)\))?/', $sub_table, $match);
+ preg_match('/(\[(?\<\>?|\>\)\])?(?[a-zA-Z0-9_]+)\s?(\((?[a-zA-Z0-9_]+)\))?/', $sub_table, $match);
if ($match[ 'join' ] !== '' && $match[ 'table' ] !== '')
{
@@ -887,26 +974,18 @@ protected function selectContext($table, &$map, $join, &$columns = null, $where
{
if (is_null($columns))
{
- if (is_null($where))
+ if (
+ !is_null($where) ||
+ (is_array($join) && isset($column_fn))
+ )
{
- if (
- is_array($join) &&
- isset($column_fn)
- )
- {
- $where = $join;
- $columns = null;
- }
- else
- {
- $where = null;
- $columns = $join;
- }
+ $where = $join;
+ $columns = null;
}
else
{
- $where = $join;
- $columns = null;
+ $where = null;
+ $columns = $join;
}
}
else
@@ -935,12 +1014,12 @@ protected function selectContext($table, &$map, $join, &$columns = null, $where
$where = $join;
}
- $column = $column_fn . '(' . $this->columnPush($columns) . ')';
+ $column = $column_fn . '(' . $this->columnPush($columns, $map) . ')';
}
}
else
{
- $column = $this->columnPush($columns);
+ $column = $this->columnPush($columns, $map);
}
return 'SELECT ' . $column . ' FROM ' . $table_query . $this->whereClause($where, $map);
@@ -957,11 +1036,11 @@ protected function columnMap($columns, &$stack)
{
if (is_int($key))
{
- preg_match('/(?[a-zA-Z0-9_\.]*)(?:\s*\((?[a-zA-Z0-9_]+)\)|\s*\[(?(String|Bool|Int|Number|Object|JSON))\])?/i', $value, $key_match);
+ preg_match('/([a-zA-Z0-9_]+\.)?(?[a-zA-Z0-9_]+)(?:\s*\((?[a-zA-Z0-9_]+)\))?(?:\s*\[(?(?:String|Bool|Int|Number|Object|JSON))\])?/i', $value, $key_match);
$column_key = !empty($key_match[ 'alias' ]) ?
$key_match[ 'alias' ] :
- preg_replace('/^[\w]*\./i', '', $key_match[ 'column' ]);
+ $key_match[ 'column' ];
if (isset($key_match[ 'type' ]))
{
@@ -972,7 +1051,22 @@ protected function columnMap($columns, &$stack)
$stack[ $value ] = [$column_key, 'String'];
}
}
- else
+ elseif ($this->isRaw($value))
+ {
+ preg_match('/([a-zA-Z0-9_]+\.)?(?[a-zA-Z0-9_]+)(\s*\[(?(String|Bool|Int|Number))\])?/i', $key, $key_match);
+
+ $column_key = $key_match[ 'column' ];
+
+ if (isset($key_match[ 'type' ]))
+ {
+ $stack[ $key ] = [$column_key, $key_match[ 'type' ]];
+ }
+ else
+ {
+ $stack[ $key ] = [$column_key, 'String'];
+ }
+ }
+ elseif (!is_int($key) && is_array($value))
{
$this->columnMap($value, $stack);
}
@@ -985,16 +1079,27 @@ protected function dataMap($data, $columns, $column_map, &$stack)
{
foreach ($columns as $key => $value)
{
- if (is_int($key))
+ $isRaw = $this->isRaw($value);
+
+ if (is_int($key) || $isRaw)
{
- $map = $column_map[ $value ];
+ $map = $column_map[ $isRaw ? $key : $value ];
+
$column_key = $map[ 0 ];
if (isset($map[ 1 ]))
{
+ if ($isRaw && in_array($map[ 1 ], ['Object', 'JSON']))
+ {
+ continue;
+ }
+
switch ($map[ 1 ])
{
case 'Number':
+ $stack[ $column_key ] = (double) $data[ $column_key ];
+ break;
+
case 'Int':
$stack[ $column_key ] = (int) $data[ $column_key ];
break;
@@ -1042,7 +1147,7 @@ public function select($table, $join, $columns = null, $where = null)
$column = $where === null ? $join : $columns;
- $is_single_column = (is_string($column) && $column !== '*');
+ $is_single = (is_string($column) && $column !== '*');
$query = $this->exec($this->selectContext($table, $map, $join, $columns, $where), $map);
@@ -1058,7 +1163,7 @@ public function select($table, $join, $columns = null, $where = null)
return $query->fetchAll(PDO::FETCH_ASSOC);
}
- if ($is_single_column)
+ if ($is_single)
{
return $query->fetchAll(PDO::FETCH_COLUMN);
}
@@ -1105,9 +1210,9 @@ public function insert($table, $datas)
foreach ($columns as $key)
{
- if (strpos($key, '#') === 0)
+ if ($raw = $this->buildRaw($data[ $key ], $map))
{
- $values[] = $this->fnQuote($key, $data[ $key ]);
+ $values[] = $raw;
continue;
}
@@ -1123,12 +1228,10 @@ public function insert($table, $datas)
{
$value = $data[ $key ];
- switch (gettype($value))
- {
- case 'NULL':
- $map[ $map_key ] = [null, PDO::PARAM_NULL];
- break;
+ $type = gettype($value);
+ switch ($type)
+ {
case 'array':
$map[ $map_key ] = [
strpos($key, '[JSON]') === strlen($key) - 6 ?
@@ -1139,24 +1242,15 @@ public function insert($table, $datas)
break;
case 'object':
- $map[ $map_key ] = [serialize($value), PDO::PARAM_STR];
- break;
+ $value = serialize($value);
+ case 'NULL':
case 'resource':
- $map[ $map_key ] = [$value, PDO::PARAM_LOB];
- break;
-
case 'boolean':
- $map[ $map_key ] = [($value ? '1' : '0'), PDO::PARAM_BOOL];
- break;
-
case 'integer':
case 'double':
- $map[ $map_key ] = [$value, PDO::PARAM_INT];
- break;
-
case 'string':
- $map[ $map_key ] = [$value, PDO::PARAM_STR];
+ $map[ $map_key ] = $this->typeMap($value, $type);
break;
}
}
@@ -1167,7 +1261,7 @@ public function insert($table, $datas)
foreach ($columns as $key)
{
- $fields[] = $this->columnQuote(preg_replace("/(^#|\s*\[JSON\]$)/i", '', $key));
+ $fields[] = $this->columnQuote(preg_replace("/(\s*\[JSON\]$)/i", '', $key));
}
return $this->exec('INSERT INTO ' . $this->tableQuote($table) . ' (' . implode(', ', $fields) . ') VALUES ' . implode(', ', $stack), $map);
@@ -1180,11 +1274,11 @@ public function update($table, $data, $where = null)
foreach ($data as $key => $value)
{
- $column = $this->columnQuote(preg_replace("/(^#|\s*\[(JSON|\+|\-|\*|\/)\]$)/i", '', $key));
+ $column = $this->columnQuote(preg_replace("/(\s*\[(JSON|\+|\-|\*|\/)\]$)/i", '', $key));
- if (strpos($key, '#') === 0)
+ if ($raw = $this->buildRaw($value, $map))
{
- $fields[] = $column . ' = ' . $value;
+ $fields[] = $column . ' = ' . $raw;
continue;
}
@@ -1203,12 +1297,10 @@ public function update($table, $data, $where = null)
{
$fields[] = $column . ' = ' . $map_key;
- switch (gettype($value))
- {
- case 'NULL':
- $map[ $map_key ] = [null, PDO::PARAM_NULL];
- break;
+ $type = gettype($value);
+ switch ($type)
+ {
case 'array':
$map[ $map_key ] = [
strpos($key, '[JSON]') === strlen($key) - 6 ?
@@ -1219,24 +1311,15 @@ public function update($table, $data, $where = null)
break;
case 'object':
- $map[ $map_key ] = [serialize($value), PDO::PARAM_STR];
- break;
+ $value = serialize($value);
+ case 'NULL':
case 'resource':
- $map[ $map_key ] = [$value, PDO::PARAM_LOB];
- break;
-
case 'boolean':
- $map[ $map_key ] = [($value ? '1' : '0'), PDO::PARAM_BOOL];
- break;
-
case 'integer':
case 'double':
- $map[ $map_key ] = [$value, PDO::PARAM_INT];
- break;
-
case 'string':
- $map[ $map_key ] = [$value, PDO::PARAM_STR];
+ $map[ $map_key ] = $this->typeMap($value, $type);
break;
}
}
@@ -1254,41 +1337,36 @@ public function delete($table, $where)
public function replace($table, $columns, $where = null)
{
+ if (!is_array($columns) || empty($columns))
+ {
+ return false;
+ }
+
$map = [];
+ $stack = [];
- if (is_array($columns))
+ foreach ($columns as $column => $replacements)
{
- $replace_query = [];
-
- foreach ($columns as $column => $replacements)
+ if (is_array($replacements))
{
- if (is_array($replacements[ 0 ]))
- {
- foreach ($replacements as $replacement)
- {
- $map_key = $this->mapKey();
-
- $replace_query[] = $this->columnQuote($column) . ' = REPLACE(' . $this->columnQuote($column) . ', ' . $map_key . 'a, ' . $map_key . 'b)';
-
- $map[ $map_key . 'a' ] = [$replacement[ 0 ], PDO::PARAM_STR];
- $map[ $map_key . 'b' ] = [$replacement[ 1 ], PDO::PARAM_STR];
- }
- }
- else
+ foreach ($replacements as $old => $new)
{
$map_key = $this->mapKey();
- $replace_query[] = $this->columnQuote($column) . ' = REPLACE(' . $this->columnQuote($column) . ', ' . $map_key . 'a, ' . $map_key . 'b)';
+ $stack[] = $this->columnQuote($column) . ' = REPLACE(' . $this->columnQuote($column) . ', ' . $map_key . 'a, ' . $map_key . 'b)';
- $map[ $map_key . 'a' ] = [$replacements[ 0 ], PDO::PARAM_STR];
- $map[ $map_key . 'b' ] = [$replacements[ 1 ], PDO::PARAM_STR];
+ $map[ $map_key . 'a' ] = [$old, PDO::PARAM_STR];
+ $map[ $map_key . 'b' ] = [$new, PDO::PARAM_STR];
}
}
+ }
- $replace_query = implode(', ', $replace_query);
+ if (!empty($stack))
+ {
+ return $this->exec('UPDATE ' . $this->tableQuote($table) . ' SET ' . implode(', ', $stack) . $this->whereClause($where, $map), $map);
}
- return $this->exec('UPDATE ' . $this->tableQuote($table) . ' SET ' . $replace_query . $this->whereClause($where, $map), $map);
+ return false;
}
public function get($table, $join = null, $columns = null, $where = null)
@@ -1297,9 +1375,18 @@ public function get($table, $join = null, $columns = null, $where = null)
$stack = [];
$column_map = [];
- $column = $where === null ? $join : $columns;
+ if ($where === null)
+ {
+ $column = $join;
+ unset($columns[ 'LIMIT' ]);
+ }
+ else
+ {
+ $column = $columns;
+ unset($where[ 'LIMIT' ]);
+ }
- $is_single_column = (is_string($column) && $column !== '*');
+ $is_single = (is_string($column) && $column !== '*');
$query = $this->exec($this->selectContext($table, $map, $join, $columns, $where) . ' LIMIT 1', $map);
@@ -1318,22 +1405,18 @@ public function get($table, $join = null, $columns = null, $where = null)
$this->dataMap($data[ 0 ], $columns, $column_map, $stack);
- if ($is_single_column)
+ if ($is_single)
{
return $stack[ $column_map[ $column ][ 0 ] ];
}
return $stack;
}
- else
- {
- return false;
- }
- }
- else
- {
+
return false;
}
+
+ return false;
}
public function has($table, $join, $where = null)
@@ -1345,75 +1428,28 @@ public function has($table, $join, $where = null)
if ($query)
{
- return $query->fetchColumn() === '1';
- }
- else
- {
- return false;
- }
- }
-
- public function count($table, $join = null, $column = null, $where = null)
- {
- $map = [];
-
- $query = $this->exec($this->selectContext($table, $map, $join, $column, $where, 'COUNT'), $map);
-
- return $query ? 0 + $query->fetchColumn() : false;
- }
-
- public function max($table, $join, $column = null, $where = null)
- {
- $map = [];
-
- $query = $this->exec($this->selectContext($table, $map, $join, $column, $where, 'MAX'), $map);
-
- if ($query)
- {
- $max = $query->fetchColumn();
+ $result = $query->fetchColumn();
- return is_numeric($max) ? $max + 0 : $max;
- }
- else
- {
- return false;
+ return $result === '1' || $result === true;
}
+
+ return false;
}
- public function min($table, $join, $column = null, $where = null)
+ private function aggregate($type, $table, $join = null, $column = null, $where = null)
{
$map = [];
- $query = $this->exec($this->selectContext($table, $map, $join, $column, $where, 'MIN'), $map);
+ $query = $this->exec($this->selectContext($table, $map, $join, $column, $where, strtoupper($type)), $map);
if ($query)
{
- $min = $query->fetchColumn();
+ $number = $query->fetchColumn();
- return is_numeric($min) ? $min + 0 : $min;
+ return is_numeric($number) ? $number + 0 : $number;
}
- else
- {
- return false;
- }
- }
-
- public function avg($table, $join, $column = null, $where = null)
- {
- $map = [];
- $query = $this->exec($this->selectContext($table, $map, $join, $column, $where, 'AVG'), $map);
-
- return $query ? 0 + $query->fetchColumn() : false;
- }
-
- public function sum($table, $join, $column = null, $where = null)
- {
- $map = [];
-
- $query = $this->exec($this->selectContext($table, $map, $join, $column, $where, 'SUM'), $map);
-
- return $query ? 0 + $query->fetchColumn() : false;
+ return false;
}
public function action($actions)
@@ -1422,26 +1458,33 @@ public function action($actions)
{
$this->pdo->beginTransaction();
- $result = $actions($this);
+ try {
+ $result = $actions($this);
- if ($result === false)
- {
- $this->pdo->rollBack();
+ if ($result === false)
+ {
+ $this->pdo->rollBack();
+ }
+ else
+ {
+ $this->pdo->commit();
+ }
}
- else
- {
- $this->pdo->commit();
+ catch (Exception $e) {
+ $this->pdo->rollBack();
+
+ throw $e;
}
+
+ return $result;
}
- else
- {
- return false;
- }
+
+ return false;
}
public function id()
{
- $type = $this->database_type;
+ $type = $this->type;
if ($type === 'oracle')
{