Aggiunta libreria notorm per collegarsi con pdo al db
This commit is contained in:
parent
6ad9bc1954
commit
bb6a3db435
51 changed files with 2530 additions and 0 deletions
104
vendor/notorm/NotORM.php
vendored
Normal file
104
vendor/notorm/NotORM.php
vendored
Normal file
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
/** NotORM - simple reading data from the database
|
||||
* @link http://www.notorm.com/
|
||||
* @author Jakub Vrana, http://www.vrana.cz/
|
||||
* @copyright 2010 Jakub Vrana
|
||||
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2 (one or other)
|
||||
*/
|
||||
|
||||
if (!interface_exists('JsonSerializable')) {
|
||||
interface JsonSerializable {
|
||||
function jsonSerialize();
|
||||
}
|
||||
}
|
||||
|
||||
include_once dirname(__FILE__) . "/NotORM/Structure.php";
|
||||
include_once dirname(__FILE__) . "/NotORM/Cache.php";
|
||||
include_once dirname(__FILE__) . "/NotORM/Literal.php";
|
||||
include_once dirname(__FILE__) . "/NotORM/Result.php";
|
||||
include_once dirname(__FILE__) . "/NotORM/MultiResult.php";
|
||||
include_once dirname(__FILE__) . "/NotORM/Row.php";
|
||||
|
||||
|
||||
|
||||
// friend visibility emulation
|
||||
abstract class NotORM_Abstract {
|
||||
protected $connection, $driver, $structure, $cache;
|
||||
protected $notORM, $table, $primary, $rows, $referenced = array();
|
||||
|
||||
protected $debug = false;
|
||||
protected $debugTimer;
|
||||
protected $freeze = false;
|
||||
protected $rowClass = 'NotORM_Row';
|
||||
protected $jsonAsArray = false;
|
||||
|
||||
protected function access($key, $delete = false) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Database representation
|
||||
* @property-write mixed $debug = false Enable debugging queries, true for error_log($query), callback($query, $parameters) otherwise
|
||||
* @property-write bool $freeze = false Disable persistence
|
||||
* @property-write string $rowClass = 'NotORM_Row' Class used for created objects
|
||||
* @property-write bool $jsonAsArray = false Use array instead of object in Result JSON serialization
|
||||
* @property-write string $transaction Assign 'BEGIN', 'COMMIT' or 'ROLLBACK' to start or stop transaction
|
||||
*/
|
||||
class NotORM extends NotORM_Abstract {
|
||||
|
||||
/** Create database representation
|
||||
* @param PDO
|
||||
* @param NotORM_Structure or null for new NotORM_Structure_Convention
|
||||
* @param NotORM_Cache or null for no cache
|
||||
*/
|
||||
function __construct(PDO $connection, NotORM_Structure $structure = null, NotORM_Cache $cache = null) {
|
||||
$this->connection = $connection;
|
||||
$this->driver = $connection->getAttribute(PDO::ATTR_DRIVER_NAME);
|
||||
if (!isset($structure)) {
|
||||
$structure = new NotORM_Structure_Convention;
|
||||
}
|
||||
$this->structure = $structure;
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
/** Get table data to use as $db->table[1]
|
||||
* @param string
|
||||
* @return NotORM_Result
|
||||
*/
|
||||
function __get($table) {
|
||||
return new NotORM_Result($this->structure->getReferencingTable($table, ''), $this, true);
|
||||
}
|
||||
|
||||
/** Set write-only properties
|
||||
* @return null
|
||||
*/
|
||||
function __set($name, $value) {
|
||||
if ($name == "debug" || $name == "debugTimer" || $name == "freeze" || $name == "rowClass" || $name == "jsonAsArray") {
|
||||
$this->$name = $value;
|
||||
}
|
||||
if ($name == "transaction") {
|
||||
switch (strtoupper($value)) {
|
||||
case "BEGIN": return $this->connection->beginTransaction();
|
||||
case "COMMIT": return $this->connection->commit();
|
||||
case "ROLLBACK": return $this->connection->rollback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Get table data
|
||||
* @param string
|
||||
* @param array (["condition"[, array("value")]]) passed to NotORM_Result::where()
|
||||
* @return NotORM_Result
|
||||
*/
|
||||
function __call($table, array $where) {
|
||||
$return = new NotORM_Result($this->structure->getReferencingTable($table, ''), $this);
|
||||
if ($where) {
|
||||
call_user_func_array(array($return, 'where'), $where);
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
}
|
187
vendor/notorm/NotORM/Cache.php
vendored
Normal file
187
vendor/notorm/NotORM/Cache.php
vendored
Normal file
|
@ -0,0 +1,187 @@
|
|||
<?php
|
||||
|
||||
/** Loading and saving data, it's only cache so load() does not need to block until save()
|
||||
*/
|
||||
interface NotORM_Cache {
|
||||
|
||||
/** Load stored data
|
||||
* @param string
|
||||
* @return mixed or null if not found
|
||||
*/
|
||||
function load($key);
|
||||
|
||||
/** Save data
|
||||
* @param string
|
||||
* @param mixed
|
||||
* @return null
|
||||
*/
|
||||
function save($key, $data);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Cache using $_SESSION["NotORM"]
|
||||
*/
|
||||
class NotORM_Cache_Session implements NotORM_Cache {
|
||||
|
||||
function load($key) {
|
||||
if (!isset($_SESSION["NotORM"][$key])) {
|
||||
return null;
|
||||
}
|
||||
return $_SESSION["NotORM"][$key];
|
||||
}
|
||||
|
||||
function save($key, $data) {
|
||||
$_SESSION["NotORM"][$key] = $data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Cache using file
|
||||
*/
|
||||
class NotORM_Cache_File implements NotORM_Cache {
|
||||
private $filename, $data = array();
|
||||
|
||||
function __construct($filename) {
|
||||
$this->filename = $filename;
|
||||
$this->data = unserialize(@file_get_contents($filename)); // @ - file may not exist
|
||||
}
|
||||
|
||||
function load($key) {
|
||||
if (!isset($this->data[$key])) {
|
||||
return null;
|
||||
}
|
||||
return $this->data[$key];
|
||||
}
|
||||
|
||||
function save($key, $data) {
|
||||
if (!isset($this->data[$key]) || $this->data[$key] !== $data) {
|
||||
$this->data[$key] = $data;
|
||||
file_put_contents($this->filename, serialize($this->data), LOCK_EX);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Cache using PHP include
|
||||
*/
|
||||
class NotORM_Cache_Include implements NotORM_Cache {
|
||||
private $filename, $data = array();
|
||||
|
||||
function __construct($filename) {
|
||||
$this->filename = $filename;
|
||||
$this->data = @include realpath($filename); // @ - file may not exist, realpath() to not include from include_path //! silently falls with syntax error and fails with unreadable file
|
||||
if (!is_array($this->data)) { // empty file returns 1
|
||||
$this->data = array();
|
||||
}
|
||||
}
|
||||
|
||||
function load($key) {
|
||||
if (!isset($this->data[$key])) {
|
||||
return null;
|
||||
}
|
||||
return $this->data[$key];
|
||||
}
|
||||
|
||||
function save($key, $data) {
|
||||
if (!isset($this->data[$key]) || $this->data[$key] !== $data) {
|
||||
$this->data[$key] = $data;
|
||||
file_put_contents($this->filename, '<?php return ' . var_export($this->data, true) . ';', LOCK_EX);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Cache storing data to the "notorm" table in database
|
||||
*/
|
||||
class NotORM_Cache_Database implements NotORM_Cache {
|
||||
private $connection;
|
||||
|
||||
function __construct(PDO $connection) {
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
function load($key) {
|
||||
$result = $this->connection->prepare("SELECT data FROM notorm WHERE id = ?");
|
||||
$result->execute(array($key));
|
||||
$return = $result->fetchColumn();
|
||||
if (!$return) {
|
||||
return null;
|
||||
}
|
||||
return unserialize($return);
|
||||
}
|
||||
|
||||
function save($key, $data) {
|
||||
// REPLACE is not supported by PostgreSQL and MS SQL
|
||||
$parameters = array(serialize($data), $key);
|
||||
$result = $this->connection->prepare("UPDATE notorm SET data = ? WHERE id = ?");
|
||||
$result->execute($parameters);
|
||||
if (!$result->rowCount()) {
|
||||
$result = $this->connection->prepare("INSERT INTO notorm (data, id) VALUES (?, ?)");
|
||||
try {
|
||||
@$result->execute($parameters); // @ - ignore duplicate key error
|
||||
} catch (PDOException $e) {
|
||||
if ($e->getCode() != "23000") { // "23000" - duplicate key
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// eAccelerator - user cache is obsoleted
|
||||
|
||||
|
||||
|
||||
/** Cache using "NotORM." prefix in Memcache
|
||||
*/
|
||||
class NotORM_Cache_Memcache implements NotORM_Cache {
|
||||
private $memcache;
|
||||
|
||||
function __construct(Memcache $memcache) {
|
||||
$this->memcache = $memcache;
|
||||
}
|
||||
|
||||
function load($key) {
|
||||
$return = $this->memcache->get("NotORM.$key");
|
||||
if ($return === false) {
|
||||
return null;
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
function save($key, $data) {
|
||||
$this->memcache->set("NotORM.$key", $data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Cache using "NotORM." prefix in APC
|
||||
*/
|
||||
class NotORM_Cache_APC implements NotORM_Cache {
|
||||
|
||||
function load($key) {
|
||||
$return = apc_fetch("NotORM.$key", $success);
|
||||
if (!$success) {
|
||||
return null;
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
function save($key, $data) {
|
||||
apc_store("NotORM.$key", $data);
|
||||
}
|
||||
|
||||
}
|
29
vendor/notorm/NotORM/Literal.php
vendored
Normal file
29
vendor/notorm/NotORM/Literal.php
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
/** SQL literal value
|
||||
*/
|
||||
class NotORM_Literal {
|
||||
protected $value = '';
|
||||
|
||||
/** @var array */
|
||||
public $parameters = array();
|
||||
|
||||
/** Create literal value
|
||||
* @param string
|
||||
* @param mixed parameter
|
||||
* @param mixed ...
|
||||
*/
|
||||
function __construct($value) {
|
||||
$this->value = $value;
|
||||
$this->parameters = func_get_args();
|
||||
array_shift($this->parameters);
|
||||
}
|
||||
|
||||
/** Get literal value
|
||||
* @return string
|
||||
*/
|
||||
function __toString() {
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
}
|
143
vendor/notorm/NotORM/MultiResult.php
vendored
Normal file
143
vendor/notorm/NotORM/MultiResult.php
vendored
Normal file
|
@ -0,0 +1,143 @@
|
|||
<?php
|
||||
|
||||
/** Representation of filtered table grouped by some column
|
||||
*/
|
||||
class NotORM_MultiResult extends NotORM_Result {
|
||||
private $result, $column, $active;
|
||||
|
||||
/** @access protected must be public because it is called from Row */
|
||||
function __construct($table, NotORM_Result $result, $column, $active) {
|
||||
parent::__construct($table, $result->notORM);
|
||||
$this->result = $result;
|
||||
$this->column = $column;
|
||||
$this->active = $active;
|
||||
}
|
||||
|
||||
/** Specify referencing column
|
||||
* @param string
|
||||
* @return NotORM_MultiResult fluent interface
|
||||
*/
|
||||
function via($column) {
|
||||
$this->column = $column;
|
||||
$this->conditions[0] = "$this->table.$column AND";
|
||||
$this->where[0] = "(" . $this->whereIn("$this->table.$column", array_keys((array) $this->result->rows)) . ")";
|
||||
return $this;
|
||||
}
|
||||
|
||||
function insert_multi(array $rows) {
|
||||
$args = array();
|
||||
foreach ($rows as $data) {
|
||||
if ($data instanceof Traversable && !$data instanceof NotORM_Result) {
|
||||
$data = iterator_to_array($data);
|
||||
}
|
||||
if (is_array($data)) {
|
||||
$data[$this->column] = $this->active;
|
||||
}
|
||||
$args[] = $data;
|
||||
}
|
||||
return parent::insert_multi($args);
|
||||
}
|
||||
|
||||
function insert_update(array $unique, array $insert, array $update = array()) {
|
||||
$unique[$this->column] = $this->active;
|
||||
return parent::insert_update($unique, $insert, $update);
|
||||
}
|
||||
|
||||
protected function single() {
|
||||
$this->where[0] = "($this->column = " . $this->quote($this->active) . ")";
|
||||
}
|
||||
|
||||
function update(array $data) {
|
||||
$where = $this->where;
|
||||
$this->single();
|
||||
$return = parent::update($data);
|
||||
$this->where = $where;
|
||||
return $return;
|
||||
}
|
||||
|
||||
function delete() {
|
||||
$where = $this->where;
|
||||
$this->single();
|
||||
$return = parent::delete();
|
||||
$this->where = $where;
|
||||
return $return;
|
||||
}
|
||||
|
||||
function select($columns) {
|
||||
$args = func_get_args();
|
||||
if (!$this->select) {
|
||||
array_unshift($args, "$this->table.$this->column");
|
||||
}
|
||||
return call_user_func_array(array($this, 'parent::select'), $args);
|
||||
}
|
||||
|
||||
function order($columns) {
|
||||
if (!$this->order) { // improve index utilization
|
||||
$this->order[] = "$this->table.$this->column" . (preg_match('~\\bDESC$~i', $columns) ? " DESC" : "");
|
||||
}
|
||||
$args = func_get_args();
|
||||
return call_user_func_array(array($this, 'parent::order'), $args);
|
||||
}
|
||||
|
||||
function aggregation($function) {
|
||||
$join = $this->createJoins(implode(",", $this->conditions) . ",$function");
|
||||
$column = ($join ? "$this->table." : "") . $this->column;
|
||||
$query = "SELECT $function, $column FROM $this->table" . implode($join);
|
||||
if ($this->where) {
|
||||
$query .= " WHERE " . implode($this->where);
|
||||
}
|
||||
$query .= " GROUP BY $column";
|
||||
$aggregation = &$this->result->aggregation[$query];
|
||||
if (!isset($aggregation)) {
|
||||
$aggregation = array();
|
||||
foreach ($this->query($query, $this->parameters) as $row) {
|
||||
$aggregation[$row[$this->column]] = $row;
|
||||
}
|
||||
}
|
||||
if (isset($aggregation[$this->active])) {
|
||||
foreach ($aggregation[$this->active] as $return) {
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function count($column = "") {
|
||||
$return = parent::count($column);
|
||||
return (isset($return) ? $return : 0);
|
||||
}
|
||||
|
||||
protected function execute() {
|
||||
if (!isset($this->rows)) {
|
||||
$referencing = &$this->result->referencing[$this->__toString()];
|
||||
if (!isset($referencing)) {
|
||||
if (!$this->limit || count($this->result->rows) <= 1 || $this->union) {
|
||||
parent::execute();
|
||||
} else { //! doesn't work with union
|
||||
$result = clone $this;
|
||||
$first = true;
|
||||
foreach ((array) $this->result->rows as $val) {
|
||||
if ($first) {
|
||||
$result->where[0] = "$this->column = " . $this->quote($val);
|
||||
$first = false;
|
||||
} else {
|
||||
$clone = clone $this;
|
||||
$clone->where[0] = "$this->column = " . $this->quote($val);
|
||||
$result->union($clone);
|
||||
}
|
||||
}
|
||||
$result->execute();
|
||||
$this->rows = $result->rows;
|
||||
}
|
||||
$referencing = array();
|
||||
foreach ($this->rows as $key => $row) {
|
||||
$referencing[$row[$this->column]][$key] = $row;
|
||||
}
|
||||
}
|
||||
$this->data = &$referencing[$this->active];
|
||||
if (!isset($this->data)) {
|
||||
$this->data = array();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
830
vendor/notorm/NotORM/Result.php
vendored
Normal file
830
vendor/notorm/NotORM/Result.php
vendored
Normal file
|
@ -0,0 +1,830 @@
|
|||
<?php
|
||||
|
||||
/** Filtered table representation
|
||||
* @method NotORM_Result and(mixed $condition, mixed $parameters = array()) Add AND condition
|
||||
* @method NotORM_Result or(mixed $condition, mixed $parameters = array()) Add OR condition
|
||||
*/
|
||||
class NotORM_Result extends NotORM_Abstract implements Iterator, ArrayAccess, Countable, JsonSerializable {
|
||||
protected $single;
|
||||
protected $select = array(), $conditions = array(), $where = array(), $parameters = array(), $order = array(), $limit = null, $offset = null, $group = "", $having = "", $lock = null;
|
||||
protected $union = array(), $unionOrder = array(), $unionLimit = null, $unionOffset = null;
|
||||
protected $data, $referencing = array(), $aggregation = array(), $accessed, $access, $keys = array();
|
||||
|
||||
/** Create table result
|
||||
* @param string
|
||||
* @param NotORM
|
||||
* @param bool single row
|
||||
* @access protected must be public because it is called from NotORM
|
||||
*/
|
||||
function __construct($table, NotORM $notORM, $single = false) {
|
||||
$this->table = $table;
|
||||
$this->notORM = $notORM;
|
||||
$this->single = $single;
|
||||
$this->primary = $notORM->structure->getPrimary($table);
|
||||
}
|
||||
|
||||
/** Save data to cache and empty result
|
||||
*/
|
||||
function __destruct() {
|
||||
if ($this->notORM->cache && !$this->select && isset($this->rows)) {
|
||||
$access = $this->access;
|
||||
if (is_array($access)) {
|
||||
$access = array_filter($access);
|
||||
}
|
||||
$this->notORM->cache->save("$this->table;" . implode(",", $this->conditions), $access);
|
||||
}
|
||||
$this->rows = null;
|
||||
unset($this->data);
|
||||
}
|
||||
|
||||
protected function limitString($limit, $offset = null) {
|
||||
$return = "";
|
||||
if (isset($limit) && $this->notORM->driver != "oci" && $this->notORM->driver != "dblib" && $this->notORM->driver != "mssql" && $this->notORM->driver != "sqlsrv") {
|
||||
$return .= " LIMIT $limit";
|
||||
if ($offset) {
|
||||
$return .= " OFFSET $offset";
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
protected function removeExtraDots($expression) {
|
||||
return preg_replace('~(?:\\b[a-z_][a-z0-9_.:]*[.:])?([a-z_][a-z0-9_]*)[.:]([a-z_*])~i', '\\1.\\2', $expression); // rewrite tab1.tab2.col
|
||||
}
|
||||
|
||||
protected function whereString() {
|
||||
$return = "";
|
||||
if ($this->group) {
|
||||
$return .= " GROUP BY $this->group";
|
||||
}
|
||||
if ($this->having) {
|
||||
$return .= " HAVING $this->having";
|
||||
}
|
||||
if ($this->order) {
|
||||
$return .= " ORDER BY " . implode(", ", $this->order);
|
||||
}
|
||||
$return = $this->removeExtraDots($return);
|
||||
|
||||
$where = $this->where;
|
||||
if (isset($this->limit) && $this->notORM->driver == "oci") {
|
||||
$where[] = ($where ? " AND " : "") . "(" . ($this->offset ? "rownum > $this->offset AND " : "") . "rownum <= " . ($this->limit + $this->offset) . ")"; //! rownum > doesn't work - requires subselect (see adminer/drivers/oracle.inc.php)
|
||||
}
|
||||
if ($where) {
|
||||
$return = " WHERE " . implode($where) . $return;
|
||||
}
|
||||
|
||||
$return .= $this->limitString($this->limit, $this->offset);
|
||||
if (isset($this->lock)) {
|
||||
$return .= ($this->lock ? " FOR UPDATE" : " LOCK IN SHARE MODE");
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
protected function topString($limit, $offset = null) {
|
||||
if (isset($limit) && ($this->notORM->driver == "dblib" || $this->notORM->driver == "mssql" || $this->notORM->driver == "sqlsrv")) {
|
||||
return " TOP ($this->limit)"; //! offset is not supported
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
protected function createJoins($val) {
|
||||
$return = array();
|
||||
preg_match_all('~\\b([a-z_][a-z0-9_.:]*[.:])[a-z_*]~i', $val, $matches);
|
||||
foreach ($matches[1] as $names) {
|
||||
$parent = $this->table;
|
||||
if ($names != "$parent.") { // case-sensitive
|
||||
preg_match_all('~\\b([a-z_][a-z0-9_]*)([.:])~i', $names, $matches, PREG_SET_ORDER);
|
||||
foreach ($matches as $match) {
|
||||
list(, $name, $delimiter) = $match;
|
||||
$table = $this->notORM->structure->getReferencedTable($name, $parent);
|
||||
$column = ($delimiter == ':' ? $this->notORM->structure->getPrimary($parent) : $this->notORM->structure->getReferencedColumn($name, $parent));
|
||||
$primary = ($delimiter == ':' ? $this->notORM->structure->getReferencedColumn($parent, $table) : $this->notORM->structure->getPrimary($table));
|
||||
$return[$name] = " LEFT JOIN $table" . ($table != $name ? " AS $name" : "") . " ON $parent.$column = $name.$primary"; // should use alias if the table is used on more places
|
||||
$parent = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Get SQL query
|
||||
* @return string
|
||||
*/
|
||||
function __toString() {
|
||||
$return = "SELECT" . $this->topString($this->limit, $this->offset) . " ";
|
||||
$join = $this->createJoins(implode(",", $this->conditions) . "," . implode(",", $this->select) . ",$this->group,$this->having," . implode(",", $this->order));
|
||||
if (!isset($this->rows) && $this->notORM->cache && !is_string($this->accessed)) {
|
||||
$this->accessed = $this->notORM->cache->load("$this->table;" . implode(",", $this->conditions));
|
||||
$this->access = $this->accessed;
|
||||
}
|
||||
if ($this->select) {
|
||||
$return .= $this->removeExtraDots(implode(", ", $this->select));
|
||||
} elseif ($this->accessed) {
|
||||
$return .= ($join ? "$this->table." : "") . implode(", " . ($join ? "$this->table." : ""), array_keys($this->accessed));
|
||||
} else {
|
||||
$return .= ($join ? "$this->table." : "") . "*";
|
||||
}
|
||||
$return .= " FROM $this->table" . implode($join) . $this->whereString();
|
||||
if ($this->union) {
|
||||
$return = ($this->notORM->driver == "sqlite" || $this->notORM->driver == "oci" ? $return : "($return)") . implode($this->union);
|
||||
if ($this->unionOrder) {
|
||||
$return .= " ORDER BY " . implode(", ", $this->unionOrder);
|
||||
}
|
||||
$return .= $this->limitString($this->unionLimit, $this->unionOffset);
|
||||
$top = $this->topString($this->unionLimit, $this->unionOffset);
|
||||
if ($top) {
|
||||
$return = "SELECT$top * FROM ($return) t";
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
protected function query($query, $parameters) {
|
||||
if ($this->notORM->debug) {
|
||||
if (!is_callable($this->notORM->debug)) {
|
||||
$debug = "$query;";
|
||||
if ($parameters) {
|
||||
$debug .= " -- " . implode(", ", array_map(array($this, 'quote'), $parameters));
|
||||
}
|
||||
$pattern = '(^' . preg_quote(dirname(__FILE__)) . '(\\.php$|[/\\\\]))'; // can be static
|
||||
foreach (debug_backtrace() as $backtrace) {
|
||||
if (isset($backtrace["file"]) && !preg_match($pattern, $backtrace["file"])) { // stop on first file outside NotORM source codes
|
||||
break;
|
||||
}
|
||||
}
|
||||
error_log("$backtrace[file]:$backtrace[line]:$debug\n", 0);
|
||||
} elseif (call_user_func($this->notORM->debug, $query, $parameters) === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$return = $this->notORM->connection->prepare($query);
|
||||
if (!$return || !$return->execute(array_map(array($this, 'formatValue'), $parameters))) {
|
||||
$return = false;
|
||||
}
|
||||
if ($this->notORM->debugTimer) {
|
||||
call_user_func($this->notORM->debugTimer);
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
protected function formatValue($val) {
|
||||
if ($val instanceof DateTime) {
|
||||
return $val->format("Y-m-d H:i:s"); //! may be driver specific
|
||||
}
|
||||
return $val;
|
||||
}
|
||||
|
||||
protected function quote($val) {
|
||||
if (!isset($val)) {
|
||||
return "NULL";
|
||||
}
|
||||
if (is_array($val)) { // (a, b) IN ((1, 2), (3, 4))
|
||||
return "(" . implode(", ", array_map(array($this, 'quote'), $val)) . ")";
|
||||
}
|
||||
$val = $this->formatValue($val);
|
||||
if (is_float($val)) {
|
||||
return sprintf("%F", $val); // otherwise depends on setlocale()
|
||||
}
|
||||
if ($val === false) {
|
||||
return "0";
|
||||
}
|
||||
if (is_int($val) || $val instanceof NotORM_Literal) { // number or SQL code - for example "NOW()"
|
||||
return (string) $val;
|
||||
}
|
||||
return $this->notORM->connection->quote($val);
|
||||
}
|
||||
|
||||
/** Shortcut for call_user_func_array(array($this, 'insert'), $rows)
|
||||
* @param array
|
||||
* @return int number of affected rows or false in case of an error
|
||||
*/
|
||||
function insert_multi(array $rows) {
|
||||
if ($this->notORM->freeze) {
|
||||
return false;
|
||||
}
|
||||
if (!$rows) {
|
||||
return 0;
|
||||
}
|
||||
$data = reset($rows);
|
||||
$parameters = array();
|
||||
if ($data instanceof NotORM_Result) {
|
||||
$parameters = $data->parameters; //! other parameters
|
||||
$data = (string) $data;
|
||||
} elseif ($data instanceof Traversable) {
|
||||
$data = iterator_to_array($data);
|
||||
}
|
||||
$insert = $data;
|
||||
if (is_array($data)) {
|
||||
$values = array();
|
||||
foreach ($rows as $value) {
|
||||
if ($value instanceof Traversable) {
|
||||
$value = iterator_to_array($value);
|
||||
}
|
||||
$values[] = $this->quote($value);
|
||||
foreach ($value as $val) {
|
||||
if ($val instanceof NotORM_Literal && $val->parameters) {
|
||||
$parameters = array_merge($parameters, $val->parameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
//! driver specific extended insert
|
||||
$insert = ($data || $this->notORM->driver == "mysql"
|
||||
? "(" . implode(", ", array_keys($data)) . ") VALUES " . implode(", ", $values)
|
||||
: "DEFAULT VALUES"
|
||||
);
|
||||
}
|
||||
// requires empty $this->parameters
|
||||
$return = $this->query("INSERT INTO $this->table $insert", $parameters);
|
||||
if (!$return) {
|
||||
return false;
|
||||
}
|
||||
$this->rows = null;
|
||||
return $return->rowCount();
|
||||
}
|
||||
|
||||
/** Insert row in a table
|
||||
* @param mixed array($column => $value)|Traversable for single row insert or NotORM_Result|string for INSERT ... SELECT
|
||||
* @param ... used for extended insert
|
||||
* @return mixed inserted NotORM_Row or false in case of an error or number of affected rows for INSERT ... SELECT
|
||||
*/
|
||||
function insert($data) {
|
||||
$rows = func_get_args();
|
||||
$return = $this->insert_multi($rows);
|
||||
if (!$return) {
|
||||
return false;
|
||||
}
|
||||
if (!is_array($data)) {
|
||||
return $return;
|
||||
}
|
||||
if (!isset($data[$this->primary]) && ($id = $this->notORM->connection->lastInsertId($this->notORM->structure->getSequence($this->table)))) {
|
||||
$data[$this->primary] = $id;
|
||||
}
|
||||
return new $this->notORM->rowClass($data, $this);
|
||||
}
|
||||
|
||||
/** Update all rows in result set
|
||||
* @param array ($column => $value)
|
||||
* @return int number of affected rows or false in case of an error
|
||||
*/
|
||||
function update(array $data) {
|
||||
if ($this->notORM->freeze) {
|
||||
return false;
|
||||
}
|
||||
if (!$data) {
|
||||
return 0;
|
||||
}
|
||||
$values = array();
|
||||
$parameters = array();
|
||||
foreach ($data as $key => $val) {
|
||||
// doesn't use binding because $this->parameters can be filled by ? or :name
|
||||
$values[] = "$key = " . $this->quote($val);
|
||||
if ($val instanceof NotORM_Literal && $val->parameters) {
|
||||
$parameters = array_merge($parameters, $val->parameters);
|
||||
}
|
||||
}
|
||||
if ($this->parameters) {
|
||||
$parameters = array_merge($parameters, $this->parameters);
|
||||
}
|
||||
// joins in UPDATE are supported only in MySQL
|
||||
$return = $this->query("UPDATE" . $this->topString($this->limit, $this->offset) . " $this->table SET " . implode(", ", $values) . $this->whereString(), $parameters);
|
||||
if (!$return) {
|
||||
return false;
|
||||
}
|
||||
return $return->rowCount();
|
||||
}
|
||||
|
||||
/** Insert row or update if it already exists
|
||||
* @param array ($column => $value)
|
||||
* @param array ($column => $value)
|
||||
* @param array ($column => $value), empty array means use $insert
|
||||
* @return int number of affected rows or false in case of an error
|
||||
*/
|
||||
function insert_update(array $unique, array $insert, array $update = array()) {
|
||||
if (!$update) {
|
||||
$update = $insert;
|
||||
}
|
||||
$insert = $unique + $insert;
|
||||
$values = "(" . implode(", ", array_keys($insert)) . ") VALUES " . $this->quote($insert);
|
||||
//! parameters
|
||||
if ($this->notORM->driver == "mysql") {
|
||||
$set = array();
|
||||
if (!$update) {
|
||||
$update = $unique;
|
||||
}
|
||||
foreach ($update as $key => $val) {
|
||||
$set[] = "$key = " . $this->quote($val);
|
||||
//! parameters
|
||||
}
|
||||
return $this->insert("$values ON DUPLICATE KEY UPDATE " . implode(", ", $set));
|
||||
} else {
|
||||
$connection = $this->notORM->connection;
|
||||
$errorMode = $connection->getAttribute(PDO::ATTR_ERRMODE);
|
||||
$connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
try {
|
||||
$return = $this->insert($values);
|
||||
$connection->setAttribute(PDO::ATTR_ERRMODE, $errorMode);
|
||||
return $return;
|
||||
} catch (PDOException $e) {
|
||||
$connection->setAttribute(PDO::ATTR_ERRMODE, $errorMode);
|
||||
if ($e->getCode() == "23000" || $e->getCode() == "23505") { // "23000" - duplicate key, "23505" unique constraint pgsql
|
||||
if (!$update) {
|
||||
return 0;
|
||||
}
|
||||
$clone = clone $this;
|
||||
$return = $clone->where($unique)->update($update);
|
||||
return ($return ? $return + 1 : $return);
|
||||
}
|
||||
if ($errorMode == PDO::ERRMODE_EXCEPTION) {
|
||||
throw $e;
|
||||
} elseif ($errorMode == PDO::ERRMODE_WARNING) {
|
||||
trigger_error("PDOStatement::execute(): " . $e->getMessage(), E_USER_WARNING); // E_WARNING is unusable
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Get last insert ID
|
||||
* @return string number
|
||||
*/
|
||||
function insert_id() {
|
||||
return $this->notORM->connection->lastInsertId();
|
||||
}
|
||||
|
||||
/** Delete all rows in result set
|
||||
* @return int number of affected rows or false in case of an error
|
||||
*/
|
||||
function delete() {
|
||||
if ($this->notORM->freeze) {
|
||||
return false;
|
||||
}
|
||||
$return = $this->query("DELETE" . $this->topString($this->limit, $this->offset) . " FROM $this->table" . $this->whereString(), $this->parameters);
|
||||
if (!$return) {
|
||||
return false;
|
||||
}
|
||||
return $return->rowCount();
|
||||
}
|
||||
|
||||
/** Add select clause, more calls appends to the end
|
||||
* @param string for example "column, MD5(column) AS column_md5", empty string to reset previously set columns
|
||||
* @param string ...
|
||||
* @return NotORM_Result fluent interface
|
||||
*/
|
||||
function select($columns) {
|
||||
$this->__destruct();
|
||||
if ($columns != "") {
|
||||
foreach (func_get_args() as $columns) {
|
||||
$this->select[] = $columns;
|
||||
}
|
||||
} else {
|
||||
$this->select = array();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** Add where condition, more calls appends with AND
|
||||
* @param mixed string possibly containing ? or :name; or array($condition => $parameters, ...)
|
||||
* @param mixed array accepted by PDOStatement::execute or a scalar value
|
||||
* @param mixed ...
|
||||
* @return NotORM_Result fluent interface
|
||||
*/
|
||||
function where($condition, $parameters = array()) {
|
||||
$args = func_get_args();
|
||||
return $this->whereOperator("AND", $args);
|
||||
}
|
||||
|
||||
protected function whereOperator($operator, array $args) {
|
||||
$condition = $args[0];
|
||||
$parameters = (count($args) > 1 ? $args[1] : array());
|
||||
if (is_array($condition)) { // where(array("column1" => 1, "column2 > ?" => 2))
|
||||
foreach ($condition as $key => $val) {
|
||||
$this->where($key, $val);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
$this->__destruct();
|
||||
$this->conditions[] = "$operator $condition";
|
||||
$condition = $this->removeExtraDots($condition);
|
||||
if (count($args) != 2 || strpbrk($condition, "?:")) { // where("column < ? OR column > ?", array(1, 2))
|
||||
if (count($args) != 2 || !is_array($parameters)) { // where("column < ? OR column > ?", 1, 2)
|
||||
$parameters = array_slice($args, 1);
|
||||
}
|
||||
$this->parameters = array_merge($this->parameters, $parameters);
|
||||
} elseif ($parameters === null) { // where("column", null)
|
||||
$condition .= " IS NULL";
|
||||
} elseif ($parameters instanceof NotORM_Result) { // where("column", $db->$table())
|
||||
$clone = clone $parameters;
|
||||
if (!$clone->select) {
|
||||
$clone->select($this->notORM->structure->getPrimary($clone->table));
|
||||
}
|
||||
if ($this->notORM->driver != "mysql") {
|
||||
if ($clone instanceof NotORM_MultiResult) {
|
||||
array_shift($clone->select);
|
||||
$clone->single();
|
||||
}
|
||||
$condition .= " IN ($clone)";
|
||||
$this->parameters = array_merge($this->parameters, $clone->parameters);
|
||||
} else {
|
||||
$in = array();
|
||||
foreach ($clone as $row) {
|
||||
$row = array_values(iterator_to_array($row));
|
||||
if ($clone instanceof NotORM_MultiResult && count($row) > 1) {
|
||||
array_shift($row);
|
||||
}
|
||||
if (count($row) == 1) {
|
||||
$in[] = $this->quote($row[0]);
|
||||
} else {
|
||||
$in[] = $this->quote($row);
|
||||
}
|
||||
}
|
||||
if ($in) {
|
||||
$condition .= " IN (" . implode(", ", $in) . ")";
|
||||
} else {
|
||||
$condition = "($condition) IS NOT NULL AND $condition IS NULL"; // $condition = "NOT id"
|
||||
}
|
||||
}
|
||||
} elseif (!is_array($parameters)) { // where("column", "x")
|
||||
$condition .= " = " . $this->quote($parameters);
|
||||
} else { // where("column", array(1, 2))
|
||||
$condition = $this->whereIn($condition, $parameters);
|
||||
}
|
||||
$this->where[] = (preg_match('~^\)+$~', $condition)
|
||||
? $condition
|
||||
: ($this->where ? " $operator " : "") . "($condition)"
|
||||
);
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function whereIn($condition, $parameters) {
|
||||
if (!$parameters) {
|
||||
$condition = "($condition) IS NOT NULL AND $condition IS NULL";
|
||||
} elseif ($this->notORM->driver != "oci") {
|
||||
$column = $condition;
|
||||
$condition .= " IN " . $this->quote($parameters);
|
||||
$nulls = array_filter($parameters, 'is_null');
|
||||
if ($nulls) {
|
||||
$condition = "$condition OR $column IS NULL";
|
||||
}
|
||||
} else { // http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/expressions014.htm
|
||||
$or = array();
|
||||
for ($i=0; $i < count($parameters); $i += 1000) {
|
||||
$or[] = "$condition IN " . $this->quote(array_slice($parameters, $i, 1000));
|
||||
}
|
||||
$condition = implode(" OR ", $or);
|
||||
}
|
||||
return $condition;
|
||||
}
|
||||
|
||||
function __call($name, array $args) {
|
||||
$operator = strtoupper($name);
|
||||
switch ($operator) {
|
||||
case "AND":
|
||||
case "OR":
|
||||
return $this->whereOperator($operator, $args);
|
||||
}
|
||||
trigger_error("Call to undefined method NotORM_Result::$name()", E_USER_ERROR);
|
||||
}
|
||||
|
||||
/** Shortcut for where()
|
||||
* @param string
|
||||
* @param mixed
|
||||
* @param mixed ...
|
||||
* @return NotORM_Result fluent interface
|
||||
*/
|
||||
function __invoke($where, $parameters = array()) {
|
||||
$args = func_get_args();
|
||||
return $this->whereOperator("AND", $args);
|
||||
}
|
||||
|
||||
/** Add order clause, more calls appends to the end
|
||||
* @param mixed "column1, column2 DESC" or array("column1", "column2 DESC"), empty string to reset previous order
|
||||
* @param string ...
|
||||
* @return NotORM_Result fluent interface
|
||||
*/
|
||||
function order($columns) {
|
||||
$this->rows = null;
|
||||
if ($columns != "") {
|
||||
$columns = (is_array($columns) ? $columns : func_get_args());
|
||||
foreach ($columns as $column) {
|
||||
if ($this->union) {
|
||||
$this->unionOrder[] = $column;
|
||||
} else {
|
||||
$this->order[] = $column;
|
||||
}
|
||||
}
|
||||
} elseif ($this->union) {
|
||||
$this->unionOrder = array();
|
||||
} else {
|
||||
$this->order = array();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** Set limit clause, more calls rewrite old values
|
||||
* @param int
|
||||
* @param int
|
||||
* @return NotORM_Result fluent interface
|
||||
*/
|
||||
function limit($limit, $offset = null) {
|
||||
$this->rows = null;
|
||||
if ($this->union) {
|
||||
$this->unionLimit = +$limit;
|
||||
$this->unionOffset = +$offset;
|
||||
} else {
|
||||
$this->limit = +$limit;
|
||||
$this->offset = +$offset;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** Set group clause, more calls rewrite old values
|
||||
* @param string
|
||||
* @param string
|
||||
* @return NotORM_Result fluent interface
|
||||
*/
|
||||
function group($columns, $having = "") {
|
||||
$this->__destruct();
|
||||
$this->group = $columns;
|
||||
$this->having = $having;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** Set select FOR UPDATE or LOCK IN SHARE MODE
|
||||
* @param bool
|
||||
* @return NotORM_Result fluent interface
|
||||
*/
|
||||
function lock($exclusive = true) {
|
||||
$this->lock = $exclusive;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param NotORM_Result
|
||||
* @param bool
|
||||
* @return NotORM_Result fluent interface
|
||||
*/
|
||||
function union(NotORM_Result $result, $all = false) {
|
||||
$this->union[] = " UNION " . ($all ? "ALL " : "") . ($this->notORM->driver == "sqlite" || $this->notORM->driver == "oci" ? $result : "($result)");
|
||||
$this->parameters = array_merge($this->parameters, $result->parameters);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** Execute aggregation function
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function aggregation($function) {
|
||||
$join = $this->createJoins(implode(",", $this->conditions) . ",$function");
|
||||
$query = "SELECT $function FROM $this->table" . implode($join);
|
||||
if ($this->where) {
|
||||
$query .= " WHERE " . implode($this->where);
|
||||
}
|
||||
foreach ($this->query($query, $this->parameters)->fetch() as $return) {
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
|
||||
/** Count number of rows
|
||||
* @param string
|
||||
* @return int
|
||||
*/
|
||||
function count($column = "") {
|
||||
if (!$column) {
|
||||
$this->execute();
|
||||
return count($this->data);
|
||||
}
|
||||
return $this->aggregation("COUNT($column)");
|
||||
}
|
||||
|
||||
/** Return minimum value from a column
|
||||
* @param string
|
||||
* @return int
|
||||
*/
|
||||
function min($column) {
|
||||
return $this->aggregation("MIN($column)");
|
||||
}
|
||||
|
||||
/** Return maximum value from a column
|
||||
* @param string
|
||||
* @return int
|
||||
*/
|
||||
function max($column) {
|
||||
return $this->aggregation("MAX($column)");
|
||||
}
|
||||
|
||||
/** Return sum of values in a column
|
||||
* @param string
|
||||
* @return int
|
||||
*/
|
||||
function sum($column) {
|
||||
return $this->aggregation("SUM($column)");
|
||||
}
|
||||
|
||||
/** Execute the built query
|
||||
* @return null
|
||||
*/
|
||||
protected function execute() {
|
||||
if (!isset($this->rows)) {
|
||||
$result = false;
|
||||
$exception = null;
|
||||
$parameters = array();
|
||||
foreach (array_merge($this->select, array($this, $this->group, $this->having), $this->order, $this->unionOrder) as $val) {
|
||||
if (($val instanceof NotORM_Literal || $val instanceof self) && $val->parameters) {
|
||||
$parameters = array_merge($parameters, $val->parameters);
|
||||
}
|
||||
}
|
||||
try {
|
||||
$result = $this->query($this->__toString(), $parameters);
|
||||
} catch (PDOException $exception) {
|
||||
// handled later
|
||||
}
|
||||
if (!$result) {
|
||||
if (!$this->select && $this->accessed) {
|
||||
$this->accessed = '';
|
||||
$this->access = array();
|
||||
$result = $this->query($this->__toString(), $parameters);
|
||||
} elseif ($exception) {
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
$this->rows = array();
|
||||
if ($result) {
|
||||
$result->setFetchMode(PDO::FETCH_ASSOC);
|
||||
foreach ($result as $key => $row) {
|
||||
if (isset($row[$this->primary])) {
|
||||
$key = $row[$this->primary];
|
||||
if (!is_string($this->access)) {
|
||||
$this->access[$this->primary] = true;
|
||||
}
|
||||
}
|
||||
$this->rows[$key] = new $this->notORM->rowClass($row, $this);
|
||||
}
|
||||
}
|
||||
$this->data = $this->rows;
|
||||
}
|
||||
}
|
||||
|
||||
/** Fetch next row of result
|
||||
* @param string column name to return or an empty string for the whole row
|
||||
* @return mixed string or null with $column, NotORM_Row without $column, false if there is no row
|
||||
*/
|
||||
function fetch($column = '') {
|
||||
// no $this->select($column) because next calls can access different columns
|
||||
$this->execute();
|
||||
$return = current($this->data);
|
||||
next($this->data);
|
||||
if ($return && $column != '') {
|
||||
return $return[$column];
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Fetch all rows as associative array
|
||||
* @param string
|
||||
* @param string column name used for an array value or an empty string for the whole row
|
||||
* @return array
|
||||
*/
|
||||
function fetchPairs($key, $value = '') {
|
||||
$return = array();
|
||||
$clone = clone $this;
|
||||
if ($value != "") {
|
||||
$clone->select = array();
|
||||
$clone->select("$key, $value"); // MultiResult adds its column
|
||||
} elseif ($clone->select) {
|
||||
array_unshift($clone->select, $key);
|
||||
} else {
|
||||
$clone->select = array("$key, $this->table.*");
|
||||
}
|
||||
foreach ($clone as $row) {
|
||||
$values = array_values(iterator_to_array($row));
|
||||
if ($value != "" && $clone instanceof NotORM_MultiResult) {
|
||||
array_shift($values);
|
||||
}
|
||||
$return[(string) $values[0]] = ($value != "" ? $values[(array_key_exists(1, $values) ? 1 : 0)] : $row); // isset($values[1]) - fetchPairs("id", "id")
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
protected function access($key, $delete = false) {
|
||||
if ($delete) {
|
||||
if (is_array($this->access)) {
|
||||
$this->access[$key] = false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (!isset($key)) {
|
||||
$this->access = '';
|
||||
} elseif (!is_string($this->access)) {
|
||||
$this->access[$key] = true;
|
||||
}
|
||||
if (!$this->select && $this->accessed && (!isset($key) || !isset($this->accessed[$key]))) {
|
||||
$this->accessed = '';
|
||||
$this->rows = null;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function single() {
|
||||
}
|
||||
|
||||
// Iterator implementation (not IteratorAggregate because $this->data can be changed during iteration)
|
||||
|
||||
function rewind() {
|
||||
$this->execute();
|
||||
$this->keys = array_keys($this->data);
|
||||
reset($this->keys);
|
||||
}
|
||||
|
||||
/** @return NotORM_Row */
|
||||
function current() {
|
||||
return $this->data[current($this->keys)];
|
||||
}
|
||||
|
||||
/** @return string row ID */
|
||||
function key() {
|
||||
return current($this->keys);
|
||||
}
|
||||
|
||||
function next() {
|
||||
next($this->keys);
|
||||
}
|
||||
|
||||
function valid() {
|
||||
return current($this->keys) !== false;
|
||||
}
|
||||
|
||||
// ArrayAccess implementation
|
||||
|
||||
/** Test if row exists
|
||||
* @param string row ID or array for where conditions
|
||||
* @return bool
|
||||
*/
|
||||
function offsetExists($key) {
|
||||
$row = $this->offsetGet($key);
|
||||
return isset($row);
|
||||
}
|
||||
|
||||
/** Get specified row
|
||||
* @param string row ID or array for where conditions
|
||||
* @return NotORM_Row or null if there is no such row
|
||||
*/
|
||||
function offsetGet($key) {
|
||||
if ($this->single && !isset($this->data)) {
|
||||
$clone = clone $this;
|
||||
if (is_array($key)) {
|
||||
$clone->where($key)->limit(1);
|
||||
} else {
|
||||
$clone->where($this->primary, $key);
|
||||
}
|
||||
$return = $clone->fetch();
|
||||
if ($return) {
|
||||
return $return;
|
||||
}
|
||||
} else {
|
||||
$this->execute();
|
||||
if (is_array($key)) {
|
||||
foreach ($this->data as $row) {
|
||||
foreach ($key as $k => $v) {
|
||||
if ((isset($v) && $row[$k] !== null ? $row[$k] != $v : $row[$k] !== $v)) {
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
return $row;
|
||||
}
|
||||
} elseif (isset($this->data[$key])) {
|
||||
return $this->data[$key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Mimic row
|
||||
* @param string row ID
|
||||
* @param NotORM_Row
|
||||
* @return null
|
||||
*/
|
||||
function offsetSet($key, $value) {
|
||||
$this->execute();
|
||||
$this->data[$key] = $value;
|
||||
}
|
||||
|
||||
/** Remove row from result set
|
||||
* @param string row ID
|
||||
* @return null
|
||||
*/
|
||||
function offsetUnset($key) {
|
||||
$this->execute();
|
||||
unset($this->data[$key]);
|
||||
}
|
||||
|
||||
// JsonSerializable implementation
|
||||
|
||||
function jsonSerialize() {
|
||||
$this->execute();
|
||||
if ($this->notORM->jsonAsArray) {
|
||||
return array_values($this->data);
|
||||
} else {
|
||||
return $this->data;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
193
vendor/notorm/NotORM/Row.php
vendored
Normal file
193
vendor/notorm/NotORM/Row.php
vendored
Normal file
|
@ -0,0 +1,193 @@
|
|||
<?php
|
||||
|
||||
/** Single row representation
|
||||
*/
|
||||
class NotORM_Row extends NotORM_Abstract implements IteratorAggregate, ArrayAccess, Countable, JsonSerializable {
|
||||
private $modified = array();
|
||||
protected $row, $result, $primary;
|
||||
|
||||
/** @access protected must be public because it is called from Result */
|
||||
function __construct(array $row, NotORM_Result $result) {
|
||||
$this->row = $row;
|
||||
$this->result = $result;
|
||||
if (array_key_exists($result->primary, $row)) {
|
||||
$this->primary = $row[$result->primary];
|
||||
}
|
||||
}
|
||||
|
||||
/** Get primary key value
|
||||
* @return string
|
||||
*/
|
||||
function __toString() {
|
||||
return (string) $this[$this->result->primary]; // (string) - PostgreSQL returns int
|
||||
}
|
||||
|
||||
/** Get referenced row
|
||||
* @param string
|
||||
* @return NotORM_Row or null if the row does not exist
|
||||
*/
|
||||
function __get($name) {
|
||||
$column = $this->result->notORM->structure->getReferencedColumn($name, $this->result->table);
|
||||
$referenced = &$this->result->referenced[$name];
|
||||
if (!isset($referenced)) {
|
||||
$keys = array();
|
||||
foreach ($this->result->rows as $row) {
|
||||
if ($row[$column] !== null) {
|
||||
$keys[$row[$column]] = null;
|
||||
}
|
||||
}
|
||||
if ($keys) {
|
||||
$table = $this->result->notORM->structure->getReferencedTable($name, $this->result->table);
|
||||
$referenced = new NotORM_Result($table, $this->result->notORM);
|
||||
$referenced->where("$table." . $this->result->notORM->structure->getPrimary($table), array_keys($keys));
|
||||
} else {
|
||||
$referenced = array();
|
||||
}
|
||||
}
|
||||
if (!isset($referenced[$this[$column]])) { // referenced row may not exist
|
||||
return null;
|
||||
}
|
||||
return $referenced[$this[$column]];
|
||||
}
|
||||
|
||||
/** Test if referenced row exists
|
||||
* @param string
|
||||
* @return bool
|
||||
*/
|
||||
function __isset($name) {
|
||||
return ($this->__get($name) !== null);
|
||||
}
|
||||
|
||||
/** Store referenced value
|
||||
* @param string
|
||||
* @param NotORM_Row or null
|
||||
* @return null
|
||||
*/
|
||||
function __set($name, NotORM_Row $value = null) {
|
||||
$column = $this->result->notORM->structure->getReferencedColumn($name, $this->result->table);
|
||||
$this[$column] = $value;
|
||||
}
|
||||
|
||||
/** Remove referenced column from data
|
||||
* @param string
|
||||
* @return null
|
||||
*/
|
||||
function __unset($name) {
|
||||
$column = $this->result->notORM->structure->getReferencedColumn($name, $this->result->table);
|
||||
unset($this[$column]);
|
||||
}
|
||||
|
||||
/** Get referencing rows
|
||||
* @param string table name
|
||||
* @param array (["condition"[, array("value")]])
|
||||
* @return NotORM_MultiResult
|
||||
*/
|
||||
function __call($name, array $args) {
|
||||
$table = $this->result->notORM->structure->getReferencingTable($name, $this->result->table);
|
||||
$column = $this->result->notORM->structure->getReferencingColumn($table, $this->result->table);
|
||||
$return = new NotORM_MultiResult($table, $this->result, $column, $this[$this->result->primary]);
|
||||
$return->where("$table.$column", array_keys((array) $this->result->rows)); // (array) - is null after insert
|
||||
if ($args) {
|
||||
call_user_func_array(array($return, 'where'), $args);
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Update row
|
||||
* @param array or null for all modified values
|
||||
* @return int number of affected rows or false in case of an error
|
||||
*/
|
||||
function update($data = null) {
|
||||
// update is an SQL keyword
|
||||
if (!isset($data)) {
|
||||
$data = $this->modified;
|
||||
}
|
||||
$result = new NotORM_Result($this->result->table, $this->result->notORM);
|
||||
$return = $result->where($this->result->primary, $this->primary)->update($data);
|
||||
$this->primary = $this[$this->result->primary];
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Delete row
|
||||
* @return int number of affected rows or false in case of an error
|
||||
*/
|
||||
function delete() {
|
||||
// delete is an SQL keyword
|
||||
$result = new NotORM_Result($this->result->table, $this->result->notORM);
|
||||
$return = $result->where($this->result->primary, $this->primary)->delete();
|
||||
$this->primary = $this[$this->result->primary];
|
||||
return $return;
|
||||
}
|
||||
|
||||
protected function access($key, $delete = false) {
|
||||
if ($this->result->notORM->cache && !isset($this->modified[$key]) && $this->result->access($key, $delete)) {
|
||||
$id = (isset($this->primary) ? $this->primary : $this->row);
|
||||
$this->row = $this->result[$id]->row;
|
||||
}
|
||||
}
|
||||
|
||||
// IteratorAggregate implementation
|
||||
|
||||
function getIterator() {
|
||||
$this->access(null);
|
||||
return new ArrayIterator($this->row);
|
||||
}
|
||||
|
||||
// Countable implementation
|
||||
|
||||
function count() {
|
||||
return count($this->row);
|
||||
}
|
||||
|
||||
// ArrayAccess implementation
|
||||
|
||||
/** Test if column exists
|
||||
* @param string column name
|
||||
* @return bool
|
||||
*/
|
||||
function offsetExists($key) {
|
||||
$this->access($key);
|
||||
$return = array_key_exists($key, $this->row);
|
||||
if (!$return) {
|
||||
$this->access($key, true);
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** Get value of column
|
||||
* @param string column name
|
||||
* @return string
|
||||
*/
|
||||
function offsetGet($key) {
|
||||
$this->access($key);
|
||||
if (!array_key_exists($key, $this->row)) {
|
||||
$this->access($key, true);
|
||||
}
|
||||
return $this->row[$key];
|
||||
}
|
||||
|
||||
/** Store value in column
|
||||
* @param string column name
|
||||
* @return null
|
||||
*/
|
||||
function offsetSet($key, $value) {
|
||||
$this->row[$key] = $value;
|
||||
$this->modified[$key] = $value;
|
||||
}
|
||||
|
||||
/** Remove column from data
|
||||
* @param string column name
|
||||
* @return null
|
||||
*/
|
||||
function offsetUnset($key) {
|
||||
unset($this->row[$key]);
|
||||
unset($this->modified[$key]);
|
||||
}
|
||||
|
||||
// JsonSerializable implementation
|
||||
|
||||
function jsonSerialize() {
|
||||
return $this->row;
|
||||
}
|
||||
|
||||
}
|
196
vendor/notorm/NotORM/Structure.php
vendored
Normal file
196
vendor/notorm/NotORM/Structure.php
vendored
Normal file
|
@ -0,0 +1,196 @@
|
|||
<?php
|
||||
|
||||
/** Information about tables and columns structure
|
||||
*/
|
||||
interface NotORM_Structure {
|
||||
|
||||
/** Get primary key of a table in $db->$table()
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function getPrimary($table);
|
||||
|
||||
/** Get column holding foreign key in $table[$id]->$name()
|
||||
* @param string
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function getReferencingColumn($name, $table);
|
||||
|
||||
/** Get target table in $table[$id]->$name()
|
||||
* @param string
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function getReferencingTable($name, $table);
|
||||
|
||||
/** Get column holding foreign key in $table[$id]->$name
|
||||
* @param string
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function getReferencedColumn($name, $table);
|
||||
|
||||
/** Get table holding foreign key in $table[$id]->$name
|
||||
* @param string
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function getReferencedTable($name, $table);
|
||||
|
||||
/** Get sequence name, used by insert
|
||||
* @param string
|
||||
* @return string
|
||||
*/
|
||||
function getSequence($table);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Structure described by some rules
|
||||
*/
|
||||
class NotORM_Structure_Convention implements NotORM_Structure {
|
||||
protected $primary, $foreign, $table, $prefix;
|
||||
|
||||
/** Create conventional structure
|
||||
* @param string %s stands for table name
|
||||
* @param string %1$s stands for key used after ->, %2$s for table name
|
||||
* @param string %1$s stands for key used after ->, %2$s for table name
|
||||
* @param string prefix for all tables
|
||||
*/
|
||||
function __construct($primary = 'id', $foreign = '%s_id', $table = '%s', $prefix = '') {
|
||||
$this->primary = $primary;
|
||||
$this->foreign = $foreign;
|
||||
$this->table = $table;
|
||||
$this->prefix = $prefix;
|
||||
}
|
||||
|
||||
function getPrimary($table) {
|
||||
return sprintf($this->primary, $this->getColumnFromTable($table));
|
||||
}
|
||||
|
||||
function getReferencingColumn($name, $table) {
|
||||
return $this->getReferencedColumn(substr($table, strlen($this->prefix)), $this->prefix . $name);
|
||||
}
|
||||
|
||||
function getReferencingTable($name, $table) {
|
||||
return $this->prefix . $name;
|
||||
}
|
||||
|
||||
function getReferencedColumn($name, $table) {
|
||||
return sprintf($this->foreign, $this->getColumnFromTable($name), substr($table, strlen($this->prefix)));
|
||||
}
|
||||
|
||||
function getReferencedTable($name, $table) {
|
||||
return $this->prefix . sprintf($this->table, $name, $table);
|
||||
}
|
||||
|
||||
function getSequence($table) {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function getColumnFromTable($name) {
|
||||
if ($this->table != '%s' && preg_match('(^' . str_replace('%s', '(.*)', preg_quote($this->table)) . '$)', $name, $match)) {
|
||||
return $match[1];
|
||||
}
|
||||
return $name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Structure reading meta-informations from the database
|
||||
*/
|
||||
class NotORM_Structure_Discovery implements NotORM_Structure {
|
||||
protected $connection, $cache, $structure = array();
|
||||
protected $foreign;
|
||||
|
||||
/** Create autodisovery structure
|
||||
* @param PDO
|
||||
* @param NotORM_Cache
|
||||
* @param string use "%s_id" to access $name . "_id" column in $row->$name
|
||||
*/
|
||||
function __construct(PDO $connection, NotORM_Cache $cache = null, $foreign = '%s') {
|
||||
$this->connection = $connection;
|
||||
$this->cache = $cache;
|
||||
$this->foreign = $foreign;
|
||||
if ($cache) {
|
||||
$this->structure = $cache->load("structure");
|
||||
}
|
||||
}
|
||||
|
||||
/** Save data to cache
|
||||
*/
|
||||
function __destruct() {
|
||||
if ($this->cache) {
|
||||
$this->cache->save("structure", $this->structure);
|
||||
}
|
||||
}
|
||||
|
||||
function getPrimary($table) {
|
||||
$return = &$this->structure["primary"][$table];
|
||||
if (!isset($return)) {
|
||||
$return = "";
|
||||
foreach ($this->connection->query("EXPLAIN $table") as $column) {
|
||||
if ($column[3] == "PRI") { // 3 - "Key" is not compatible with PDO::CASE_LOWER
|
||||
if ($return != "") {
|
||||
$return = ""; // multi-column primary key is not supported
|
||||
break;
|
||||
}
|
||||
$return = $column[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
function getReferencingColumn($name, $table) {
|
||||
$name = strtolower($name);
|
||||
$return = &$this->structure["referencing"][$table];
|
||||
if (!isset($return[$name])) {
|
||||
foreach ($this->connection->query("
|
||||
SELECT TABLE_NAME, COLUMN_NAME
|
||||
FROM information_schema.KEY_COLUMN_USAGE
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND REFERENCED_TABLE_SCHEMA = DATABASE()
|
||||
AND REFERENCED_TABLE_NAME = " . $this->connection->quote($table) . "
|
||||
AND REFERENCED_COLUMN_NAME = " . $this->connection->quote($this->getPrimary($table)) //! may not reference primary key
|
||||
) as $row) {
|
||||
$return[strtolower($row[0])] = $row[1];
|
||||
}
|
||||
}
|
||||
return $return[$name];
|
||||
}
|
||||
|
||||
function getReferencingTable($name, $table) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
function getReferencedColumn($name, $table) {
|
||||
return sprintf($this->foreign, $name);
|
||||
}
|
||||
|
||||
function getReferencedTable($name, $table) {
|
||||
$column = strtolower($this->getReferencedColumn($name, $table));
|
||||
$return = &$this->structure["referenced"][$table];
|
||||
if (!isset($return[$column])) {
|
||||
foreach ($this->connection->query("
|
||||
SELECT COLUMN_NAME, REFERENCED_TABLE_NAME
|
||||
FROM information_schema.KEY_COLUMN_USAGE
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND REFERENCED_TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = " . $this->connection->quote($table) . "
|
||||
") as $row) {
|
||||
$return[strtolower($row[0])] = $row[1];
|
||||
}
|
||||
}
|
||||
return $return[$column];
|
||||
}
|
||||
|
||||
function getSequence($table) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
16
vendor/notorm/composer.json
vendored
Normal file
16
vendor/notorm/composer.json
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "vrana/notorm",
|
||||
"description": "NotORM is a PHP library for simple working with data in the database.",
|
||||
"keywords": ["database", "dbal"],
|
||||
"homepage": "http://www.notorm.com/",
|
||||
"license": ["Apache-2.0", "GPL-2.0+"],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jakub Vrána",
|
||||
"homepage": "http://www.vrana.cz/"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"files": ["NotORM.php"]
|
||||
}
|
||||
}
|
22
vendor/notorm/readme.txt
vendored
Normal file
22
vendor/notorm/readme.txt
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
NotORM - http://www.notorm.com/
|
||||
|
||||
NotORM is a PHP library for simple working with data in the database. The most interesting feature is a very easy work with table relationships. The overall performance is also very important and NotORM can actually run faster than a native driver.
|
||||
|
||||
Requirements:
|
||||
PHP 5.1+
|
||||
any database supported by PDO (tested with MySQL, SQLite, PostgreSQL, MS SQL, Oracle)
|
||||
|
||||
Usage:
|
||||
<?php
|
||||
include "NotORM.php";
|
||||
$connection = new PDO("mysql:dbname=software");
|
||||
$software = new NotORM($connection);
|
||||
|
||||
foreach ($software->application()->order("title") as $application) { // get all applications ordered by title
|
||||
echo "$application[title]\n"; // print application title
|
||||
echo $application->author["name"] . "\n"; // print name of the application author
|
||||
foreach ($application->application_tag() as $application_tag) { // get all tags of $application
|
||||
echo $application_tag->tag["name"] . "\n"; // print the tag name
|
||||
}
|
||||
}
|
||||
?>
|
24
vendor/notorm/tests/1-basic.phpt
vendored
Normal file
24
vendor/notorm/tests/1-basic.phpt
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
--TEST--
|
||||
Basic operations
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
foreach ($software->application() as $application) {
|
||||
echo "$application[title] (" . $application->author["name"] . ")\n";
|
||||
foreach ($application->application_tag() as $application_tag) {
|
||||
echo "\t" . $application_tag->tag["name"] . "\n";
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Adminer (Jakub Vrana)
|
||||
PHP
|
||||
MySQL
|
||||
JUSH (Jakub Vrana)
|
||||
JavaScript
|
||||
Nette (David Grudl)
|
||||
PHP
|
||||
Dibi (David Grudl)
|
||||
PHP
|
||||
MySQL
|
34
vendor/notorm/tests/10-update.phpt
vendored
Normal file
34
vendor/notorm/tests/10-update.phpt
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
--TEST--
|
||||
Insert, update, delete
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
$id = 5; // auto_increment is disabled in demo
|
||||
$application = $software->application()->insert(array(
|
||||
"id" => $id,
|
||||
"author_id" => $software->author[12],
|
||||
"title" => new NotORM_Literal("'Texy'"),
|
||||
"web" => "",
|
||||
"slogan" => "The best humane Web text generator",
|
||||
));
|
||||
$application_tag = $application->application_tag()->insert(array("tag_id" => 21));
|
||||
|
||||
// retrieve the really stored value
|
||||
$application = $software->application[$id];
|
||||
echo $application["title"] . "\n";
|
||||
|
||||
$application["web"] = "http://texy.info/";
|
||||
echo $application->update() . " row updated.\n";
|
||||
echo $software->application[$id]["web"] . "\n";
|
||||
|
||||
$software->application_tag("application_id", 5)->delete(); // foreign keys may be disabled
|
||||
echo $application->delete() . " row deleted.\n";
|
||||
echo count($software->application("id", $id)) . " rows found.\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Texy
|
||||
1 row updated.
|
||||
http://texy.info/
|
||||
1 row deleted.
|
||||
0 rows found.
|
24
vendor/notorm/tests/11-pairs.phpt
vendored
Normal file
24
vendor/notorm/tests/11-pairs.phpt
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
--TEST--
|
||||
fetchPairs()
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
print_r($software->application()->order("title")->fetchPairs("id", "title"));
|
||||
print_r($software->application()->order("id")->fetchPairs("id", "id"));
|
||||
?>
|
||||
--EXPECTF--
|
||||
Array
|
||||
(
|
||||
[1] => Adminer
|
||||
[4] => Dibi
|
||||
[2] => JUSH
|
||||
[3] => Nette
|
||||
)
|
||||
Array
|
||||
(
|
||||
[1] => 1
|
||||
[2] => 2
|
||||
[3] => 3
|
||||
[4] => 4
|
||||
)
|
19
vendor/notorm/tests/12-via.phpt
vendored
Normal file
19
vendor/notorm/tests/12-via.phpt
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
--TEST--
|
||||
via()
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
foreach ($software->author() as $author) {
|
||||
$applications = $author->application()->via("maintainer_id");
|
||||
foreach ($applications as $application) {
|
||||
echo "$author[name]: $application[title]\n";
|
||||
}
|
||||
}
|
||||
echo "$applications\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Jakub Vrana: Adminer
|
||||
David Grudl: Nette
|
||||
David Grudl: Dibi
|
||||
SELECT * FROM application WHERE (application.maintainer_id IN (11, 12))
|
24
vendor/notorm/tests/13-join.phpt
vendored
Normal file
24
vendor/notorm/tests/13-join.phpt
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
--TEST--
|
||||
ORDER from other table
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
foreach ($software->application()->order("author.name, title") as $application) {
|
||||
echo $application->author["name"] . ": $application[title]\n";
|
||||
}
|
||||
echo "\n";
|
||||
|
||||
foreach ($software->application_tag("application.author.name", "Jakub Vrana")->group("application_tag.tag_id") as $application_tag) {
|
||||
echo $application_tag->tag["name"] . "\n";
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
David Grudl: Dibi
|
||||
David Grudl: Nette
|
||||
Jakub Vrana: Adminer
|
||||
Jakub Vrana: JUSH
|
||||
|
||||
PHP
|
||||
MySQL
|
||||
JavaScript
|
28
vendor/notorm/tests/14-where.phpt
vendored
Normal file
28
vendor/notorm/tests/14-where.phpt
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
--TEST--
|
||||
WHERE
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
foreach (array(
|
||||
$software->application("id", 4),
|
||||
$software->application("id < ?", 4),
|
||||
$software->application("id < ?", array(4)),
|
||||
$software->application("id", array(1, 2)),
|
||||
$software->application("id", null),
|
||||
$software->application("id", $software->application()),
|
||||
$software->application("id < ?", 4)->where("maintainer_id IS NOT NULL"),
|
||||
$software->application(array("id < ?" => 4, "author_id" => 12)),
|
||||
) as $result) {
|
||||
echo implode(", ", array_keys(iterator_to_array($result->order("id")))) . "\n"; // aggregation("GROUP_CONCAT(id)") is not available in all drivers
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
4
|
||||
1, 2, 3
|
||||
1, 2, 3
|
||||
1, 2
|
||||
|
||||
1, 2, 3, 4
|
||||
1, 3
|
||||
3
|
17
vendor/notorm/tests/15-multiple.phpt
vendored
Normal file
17
vendor/notorm/tests/15-multiple.phpt
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
--TEST--
|
||||
Multiple arguments
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
$application = $software->application[1];
|
||||
foreach ($application->application_tag()
|
||||
->select("application_id", "tag_id")
|
||||
->order("application_id DESC", "tag_id DESC")
|
||||
as $application_tag) {
|
||||
echo "$application_tag[application_id] $application_tag[tag_id]\n";
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
1 22
|
||||
1 21
|
23
vendor/notorm/tests/16-offset.phpt
vendored
Normal file
23
vendor/notorm/tests/16-offset.phpt
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
--TEST--
|
||||
Limit and offset
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
$application = $software->application[1];
|
||||
foreach ($application->application_tag()->order("tag_id")->limit(1, 1) as $application_tag) {
|
||||
echo $application_tag->tag["name"] . "\n";
|
||||
}
|
||||
echo "\n";
|
||||
|
||||
foreach ($software->application() as $application) {
|
||||
foreach ($application->application_tag()->order("tag_id")->limit(1, 1) as $application_tag) {
|
||||
echo $application_tag->tag["name"] . "\n";
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
MySQL
|
||||
|
||||
MySQL
|
||||
MySQL
|
15
vendor/notorm/tests/17-transaction.phpt
vendored
Normal file
15
vendor/notorm/tests/17-transaction.phpt
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
--TEST--
|
||||
Transactions
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
$software->transaction = "BEGIN";
|
||||
$software->tag()->insert(array("id" => 99, "name" => "Test"));
|
||||
echo $software->tag[99] . "\n";
|
||||
$software->transaction = "ROLLBACK";
|
||||
echo $software->tag[99] . "\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
99
|
||||
|
22
vendor/notorm/tests/18-union.phpt
vendored
Normal file
22
vendor/notorm/tests/18-union.phpt
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
--TEST--
|
||||
Complex UNION
|
||||
--SKIPIF--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
$driver = $connection->getAttribute(PDO::ATTR_DRIVER_NAME);
|
||||
echo (preg_match('~^(sqlite|oci)$~', $driver) ? "Not supported in $driver.\n" : "");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$applications = $software->application()->select("id")->order("id DESC")->limit(2);
|
||||
$tags = $software->tag()->select("id")->order("id")->limit(2);
|
||||
foreach ($applications->union($tags)->order("id DESC") as $row) {
|
||||
echo "$row[id]\n";
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
22
|
||||
21
|
||||
4
|
||||
3
|
19
vendor/notorm/tests/19-array-offset.phpt
vendored
Normal file
19
vendor/notorm/tests/19-array-offset.phpt
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
--TEST--
|
||||
Array offset
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
$where = array(
|
||||
"author_id" => "11",
|
||||
"maintainer_id" => null,
|
||||
);
|
||||
|
||||
echo $software->application[$where]["id"] . "\n";
|
||||
|
||||
$applications = $software->application()->order("id");
|
||||
echo $applications[$where]["id"] . "\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
2
|
||||
2
|
18
vendor/notorm/tests/2-detail.phpt
vendored
Normal file
18
vendor/notorm/tests/2-detail.phpt
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
--TEST--
|
||||
Single row detail
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
$application = $software->application[1];
|
||||
foreach ($application as $key => $val) {
|
||||
echo "$key: $val\n";
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
id: 1
|
||||
author_id: 11
|
||||
maintainer_id: 11
|
||||
title: Adminer
|
||||
web: http://www.adminer.org/
|
||||
slogan: Database management in single PHP file
|
22
vendor/notorm/tests/20-extended.phpt
vendored
Normal file
22
vendor/notorm/tests/20-extended.phpt
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
--TEST--
|
||||
Extended insert
|
||||
--SKIPIF--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
$driver = $connection->getAttribute(PDO::ATTR_DRIVER_NAME);
|
||||
echo (preg_match('~^(sqlite|oci)$~', $driver) ? "Not supported in $driver.\n" : "");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$application = $software->application[3];
|
||||
$application->application_tag()->insert(array("tag_id" => 22), array("tag_id" => 23));
|
||||
foreach ($application->application_tag()->order("tag_id DESC") as $application_tag) {
|
||||
echo "$application_tag[application_id] $application_tag[tag_id]\n";
|
||||
}
|
||||
$application->application_tag("tag_id", array(22, 23))->delete();
|
||||
?>
|
||||
--EXPECTF--
|
||||
3 23
|
||||
3 22
|
||||
3 21
|
20
vendor/notorm/tests/21-simple-union.phpt
vendored
Normal file
20
vendor/notorm/tests/21-simple-union.phpt
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
--TEST--
|
||||
Simple UNION
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
$applications = $software->application()->select("id");
|
||||
$tags = $software->tag()->select("id");
|
||||
foreach ($applications->union($tags)->order("id DESC") as $row) {
|
||||
echo "$row[id]\n";
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
23
|
||||
22
|
||||
21
|
||||
4
|
||||
3
|
||||
2
|
||||
1
|
17
vendor/notorm/tests/22-insert-update.phpt
vendored
Normal file
17
vendor/notorm/tests/22-insert-update.phpt
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
--TEST--
|
||||
INSERT or UPDATE
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
for ($i=0; $i < 2; $i++) {
|
||||
echo $software->application()->insert_update(array("id" => 5), array("author_id" => 12, "title" => "Texy", "web" => "", "slogan" => "$i")) . "\n";
|
||||
}
|
||||
$application = $software->application[5];
|
||||
echo $application->application_tag()->insert_update(array("tag_id" => 21), array()) . "\n";
|
||||
$software->application("id", 5)->delete();
|
||||
?>
|
||||
--EXPECTF--
|
||||
1
|
||||
2
|
||||
1
|
12
vendor/notorm/tests/23-prefix.phpt
vendored
Normal file
12
vendor/notorm/tests/23-prefix.phpt
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
--TEST--
|
||||
Table prefix
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
$prefix = new NotORM($connection, new NotORM_Structure_Convention('id', '%s_id', '%s', 'prefix_'));
|
||||
$applications = $prefix->application("author.name", "Jakub Vrana");
|
||||
echo "$applications\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
SELECT prefix_application.* FROM prefix_application LEFT JOIN prefix_author AS author ON prefix_application.author_id = author.id WHERE (author.name = 'Jakub Vrana')
|
10
vendor/notorm/tests/24-lock.phpt
vendored
Normal file
10
vendor/notorm/tests/24-lock.phpt
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
--TEST--
|
||||
Select locking
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
echo $software->application()->lock() . "\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
SELECT * FROM application FOR UPDATE
|
13
vendor/notorm/tests/25-backjoin.phpt
vendored
Normal file
13
vendor/notorm/tests/25-backjoin.phpt
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
--TEST--
|
||||
Backwards join
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
foreach ($software->author()->select("author.*, COUNT(DISTINCT application:application_tag:tag_id) AS tags")->group("author.id")->order("tags DESC") as $autor) {
|
||||
echo "$autor[name]: $autor[tags]\n";
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Jakub Vrana: 3
|
||||
David Grudl: 2
|
16
vendor/notorm/tests/26-in.phpt
vendored
Normal file
16
vendor/notorm/tests/26-in.phpt
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
--TEST--
|
||||
IN operator
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
echo $software->application("maintainer_id", array())->count("*") . "\n";
|
||||
echo $software->application("maintainer_id", array(11))->count("*") . "\n";
|
||||
echo $software->application("NOT maintainer_id", array(11))->count("*") . "\n";
|
||||
echo $software->application("NOT maintainer_id", array())->count("*") . "\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
0
|
||||
1
|
||||
2
|
||||
3
|
19
vendor/notorm/tests/27-in-multi.phpt
vendored
Normal file
19
vendor/notorm/tests/27-in-multi.phpt
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
--TEST--
|
||||
IN operator with MultiResult
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
foreach ($software->author()->order("id") as $author) {
|
||||
foreach ($software->application_tag("application_id", $author->application())->order("application_id, tag_id") as $application_tag) {
|
||||
echo "$author: $application_tag[application_id]: $application_tag[tag_id]\n";
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
11: 1: 21
|
||||
11: 1: 22
|
||||
11: 2: 23
|
||||
12: 3: 21
|
||||
12: 4: 21
|
||||
12: 4: 22
|
12
vendor/notorm/tests/28-literal.phpt
vendored
Normal file
12
vendor/notorm/tests/28-literal.phpt
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
--TEST--
|
||||
Literal value with parameters
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
foreach ($software->author()->select(new NotORM_Literal("? + ?", 1, 2))->fetch() as $val) {
|
||||
echo "$val\n";
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
3
|
13
vendor/notorm/tests/29-row-set.phpt
vendored
Normal file
13
vendor/notorm/tests/29-row-set.phpt
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
--TEST--
|
||||
Update row through property
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
$application = $software->application[1];
|
||||
$application->author = $software->author[12];
|
||||
echo $application->update() . "\n";
|
||||
$application->update(array("author_id" => 11));
|
||||
?>
|
||||
--EXPECTF--
|
||||
1
|
14
vendor/notorm/tests/3-search-order.phpt
vendored
Normal file
14
vendor/notorm/tests/3-search-order.phpt
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
--TEST--
|
||||
Search and order items
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
foreach ($software->application("web LIKE ?", "http://%")->order("title")->limit(3) as $application) {
|
||||
echo "$application[title]\n";
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Adminer
|
||||
Dibi
|
||||
JUSH
|
29
vendor/notorm/tests/30-rowclass.phpt
vendored
Normal file
29
vendor/notorm/tests/30-rowclass.phpt
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
--TEST--
|
||||
Custom row class
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
class TestRow extends NotORM_Row {
|
||||
|
||||
function offsetExists($key) {
|
||||
return parent::offsetExists(preg_replace('~^test_~', '', $key));
|
||||
}
|
||||
|
||||
function offsetGet($key) {
|
||||
return parent::offsetGet(preg_replace('~^test_~', '', $key));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$software->rowClass = 'TestRow';
|
||||
|
||||
$application = $software->application[1];
|
||||
echo "$application[test_title]\n";
|
||||
echo $application->author["test_name"] . "\n";
|
||||
|
||||
$software->rowClass = 'NotORM_Row';
|
||||
?>
|
||||
--EXPECTF--
|
||||
Adminer
|
||||
Jakub Vrana
|
21
vendor/notorm/tests/31-datetime.phpt
vendored
Normal file
21
vendor/notorm/tests/31-datetime.phpt
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
--TEST--
|
||||
DateTime processing
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
$date = new DateTime("2011-08-30");
|
||||
|
||||
$software->application()->insert(array(
|
||||
"id" => 5,
|
||||
"author_id" => 11,
|
||||
"title" => $date,
|
||||
"slogan" => new NotORM_Literal("?", $date),
|
||||
));
|
||||
|
||||
$application = $software->application()->where("title = ?", $date)->fetch();
|
||||
echo "$application[slogan]\n";
|
||||
$application->delete();
|
||||
?>
|
||||
--EXPECTF--
|
||||
2011-08-30 00:00:00
|
13
vendor/notorm/tests/32-in-null.phpt
vendored
Normal file
13
vendor/notorm/tests/32-in-null.phpt
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
--TEST--
|
||||
IN with NULL value
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
foreach ($software->application("maintainer_id", array(11, null)) as $application) {
|
||||
echo "$application[id]\n";
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
1
|
||||
2
|
25
vendor/notorm/tests/33-structure.phpt
vendored
Normal file
25
vendor/notorm/tests/33-structure.phpt
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
--TEST--
|
||||
Structure for non-conventional column
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
class SoftwareConvention extends NotORM_Structure_Convention {
|
||||
function getReferencedTable($name, $table) {
|
||||
switch ($name) {
|
||||
case 'maintainer': return parent::getReferencedTable('author', $table);
|
||||
}
|
||||
return parent::getReferencedTable($name, $table);
|
||||
}
|
||||
}
|
||||
|
||||
$convention = new NotORM($connection, new SoftwareConvention);
|
||||
$maintainer = $convention->application[1]->maintainer;
|
||||
echo $maintainer['name'] . "\n";
|
||||
foreach ($maintainer->application()->via('maintainer_id') as $application) {
|
||||
echo "\t$application[title]\n";
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Jakub Vrana
|
||||
Adminer
|
18
vendor/notorm/tests/34-update-primary.phpt
vendored
Normal file
18
vendor/notorm/tests/34-update-primary.phpt
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
--TEST--
|
||||
Update primary key of a row
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
$application = $software->tag()->insert(array('id' => 24, 'name' => 'HTML'));
|
||||
echo "$application[id]\n";
|
||||
$application['id'] = 25;
|
||||
echo "$application[id]\n";
|
||||
echo $application->update() . "\n";
|
||||
echo $application->delete() . "\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
24
|
||||
25
|
||||
1
|
||||
1
|
16
vendor/notorm/tests/35-multiresult-loop.phpt
vendored
Normal file
16
vendor/notorm/tests/35-multiresult-loop.phpt
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
--TEST--
|
||||
Using the same MultiResult several times
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
$application = $software->application[1];
|
||||
for ($i = 0; $i < 4; $i++) {
|
||||
echo count($application->application_tag()) . "\n";
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
2
|
||||
2
|
||||
2
|
||||
2
|
12
vendor/notorm/tests/36-and.phpt
vendored
Normal file
12
vendor/notorm/tests/36-and.phpt
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
--TEST--
|
||||
Calling and()
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
foreach ($software->application("author_id", 11)->and("maintainer_id", 11) as $application) {
|
||||
echo "$application[title]\n";
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Adminer
|
14
vendor/notorm/tests/37-or.phpt
vendored
Normal file
14
vendor/notorm/tests/37-or.phpt
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
--TEST--
|
||||
Calling or()
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
foreach ($software->application("author_id", 12)->or("maintainer_id", 11)->order("title") as $application) {
|
||||
echo "$application[title]\n";
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Adminer
|
||||
Dibi
|
||||
Nette
|
19
vendor/notorm/tests/38-parens.phpt
vendored
Normal file
19
vendor/notorm/tests/38-parens.phpt
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
--TEST--
|
||||
Calling or()
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
$applications = $software->application()
|
||||
->where("(author_id", 11)->and("maintainer_id", 11)->where(")")
|
||||
->or("(author_id", 12)->and("maintainer_id", 12)->where(")")
|
||||
;
|
||||
|
||||
foreach ($applications->order("title") as $application) {
|
||||
echo "$application[title]\n";
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Adminer
|
||||
Dibi
|
||||
Nette
|
15
vendor/notorm/tests/4-findone.phpt
vendored
Normal file
15
vendor/notorm/tests/4-findone.phpt
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
--TEST--
|
||||
Find one item by title
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
$application = $software->application("title", "Adminer")->fetch();
|
||||
foreach ($application->application_tag("tag_id", 21) as $application_tag) {
|
||||
echo $application_tag->tag["name"] . "\n";
|
||||
}
|
||||
echo $software->application("title", "Adminer")->fetch("slogan") . "\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
PHP
|
||||
Database management in single PHP file
|
15
vendor/notorm/tests/5-tostring.phpt
vendored
Normal file
15
vendor/notorm/tests/5-tostring.phpt
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
--TEST--
|
||||
Calling __toString()
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
foreach ($software->application() as $application) {
|
||||
echo "$application\n";
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
19
vendor/notorm/tests/6-aggregation.phpt
vendored
Normal file
19
vendor/notorm/tests/6-aggregation.phpt
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
--TEST--
|
||||
Aggregation functions
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
$count = $software->application()->count("*");
|
||||
echo "$count applications\n";
|
||||
foreach ($software->application() as $application) {
|
||||
$count = $application->application_tag()->count("*");
|
||||
echo "$application[title]: $count tag(s)\n";
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
4 applications
|
||||
Adminer: 2 tag(s)
|
||||
JUSH: 1 tag(s)
|
||||
Nette: 1 tag(s)
|
||||
Dibi: 2 tag(s)
|
16
vendor/notorm/tests/7-subquery.phpt
vendored
Normal file
16
vendor/notorm/tests/7-subquery.phpt
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
--TEST--
|
||||
Subqueries
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
|
||||
$unknownBorn = $software->author("born", null); // authors with unknown date of born
|
||||
foreach ($software->application("author_id", $unknownBorn) as $application) { // their applications
|
||||
echo "$application[title]\n";
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Adminer
|
||||
JUSH
|
||||
Nette
|
||||
Dibi
|
25
vendor/notorm/tests/8-discovery.phpt
vendored
Normal file
25
vendor/notorm/tests/8-discovery.phpt
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
--TEST--
|
||||
Discovery test
|
||||
--FILE--
|
||||
<?php
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
$discovery = new NotORM($connection, new NotORM_Structure_Discovery($connection));
|
||||
|
||||
foreach ($discovery->application() as $application) {
|
||||
echo "$application[title] (" . $application->author_id["name"] . ")\n";
|
||||
foreach ($application->application_tag() as $application_tag) {
|
||||
echo "\t" . $application_tag->tag_id["name"] . "\n";
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Adminer (Jakub Vrana)
|
||||
PHP
|
||||
MySQL
|
||||
JUSH (Jakub Vrana)
|
||||
JavaScript
|
||||
Nette (David Grudl)
|
||||
PHP
|
||||
Dibi (David Grudl)
|
||||
PHP
|
||||
MySQL
|
31
vendor/notorm/tests/9-cache.phpt
vendored
Normal file
31
vendor/notorm/tests/9-cache.phpt
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
--TEST--
|
||||
Session cache
|
||||
--FILE--
|
||||
<?php
|
||||
$_SESSION = array(); // not session_start() - headers already sent
|
||||
include_once dirname(__FILE__) . "/connect.inc.php";
|
||||
$cache = new NotORM($connection, null, new NotORM_Cache_Session);
|
||||
|
||||
$applications = $cache->application();
|
||||
$application = $applications->fetch();
|
||||
$application["title"];
|
||||
$application->author["name"];
|
||||
echo "$applications\n"; // get all columns with no cache
|
||||
$applications->__destruct();
|
||||
|
||||
$applications = $cache->application();
|
||||
$application = $applications->fetch();
|
||||
echo "$applications\n"; // get only title and author_id
|
||||
$application["slogan"]; // script changed and now we want also slogan
|
||||
echo "$applications\n"; // all columns must have been retrieved to get slogan
|
||||
$applications->__destruct();
|
||||
|
||||
$applications = $cache->application();
|
||||
$applications->fetch();
|
||||
echo "$applications\n"; // next time, get only title, author_id and slogan
|
||||
?>
|
||||
--EXPECTF--
|
||||
SELECT * FROM application
|
||||
SELECT id, title, author_id FROM application
|
||||
SELECT * FROM application
|
||||
SELECT id, title, author_id, slogan FROM application
|
9
vendor/notorm/tests/connect.inc.php
vendored
Normal file
9
vendor/notorm/tests/connect.inc.php
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
include dirname(__FILE__) . "/../NotORM.php";
|
||||
|
||||
$connection = new PDO("mysql:dbname=software", "ODBC");
|
||||
$connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
|
||||
$connection->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
|
||||
$software = new NotORM($connection);
|
||||
//~ $software->debug = true;
|
18
vendor/notorm/tests/run-tests.php
vendored
Normal file
18
vendor/notorm/tests/run-tests.php
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
$start = microtime(true);
|
||||
|
||||
$tests = glob(dirname(__FILE__) . "/*.phpt", GLOB_NOSORT);
|
||||
natsort($tests);
|
||||
foreach ($tests as $filename) {
|
||||
ob_start();
|
||||
include $filename;
|
||||
if (!preg_match("~^--TEST--\n(.*?)\n(?:--SKIPIF--\n(.*\n)?)?--FILE--\n(.*\n)?--EXPECTF--\n(.*)~s", str_replace("\r\n", "\n", ob_get_clean()), $match)) {
|
||||
echo "wrong test in $filename\n";
|
||||
} elseif ($match[2]) {
|
||||
echo "skipped $filename ($match[1]): $match[2]";
|
||||
} elseif ($match[3] !== $match[4]) {
|
||||
echo "failed $filename ($match[1])\n";
|
||||
}
|
||||
}
|
||||
|
||||
printf("%.3F s, %d KiB\n", microtime(true) - $start, memory_get_peak_usage() / 1024);
|
57
vendor/notorm/tests/software.sql
vendored
Normal file
57
vendor/notorm/tests/software.sql
vendored
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*!40102 SET storage_engine = InnoDB */;
|
||||
|
||||
CREATE TABLE author (
|
||||
id int NOT NULL,
|
||||
name varchar(30) NOT NULL,
|
||||
web varchar(100) NOT NULL,
|
||||
born date DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
INSERT INTO author (id, name, web, born) VALUES (11, 'Jakub Vrana', 'http://www.vrana.cz/', NULL);
|
||||
INSERT INTO author (id, name, web, born) VALUES (12, 'David Grudl', 'http://davidgrudl.com/', NULL);
|
||||
|
||||
CREATE TABLE tag (
|
||||
id int NOT NULL,
|
||||
name varchar(20) NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
INSERT INTO tag (id, name) VALUES (21, 'PHP');
|
||||
INSERT INTO tag (id, name) VALUES (22, 'MySQL');
|
||||
INSERT INTO tag (id, name) VALUES (23, 'JavaScript');
|
||||
|
||||
CREATE TABLE application (
|
||||
id int NOT NULL,
|
||||
author_id int NOT NULL,
|
||||
maintainer_id int,
|
||||
title varchar(50) NOT NULL,
|
||||
web varchar(100),
|
||||
slogan varchar(100) NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
CONSTRAINT application_author FOREIGN KEY (author_id) REFERENCES author (id),
|
||||
CONSTRAINT application_maintainer FOREIGN KEY (maintainer_id) REFERENCES author (id)
|
||||
);
|
||||
|
||||
CREATE INDEX application_title ON application (title);
|
||||
|
||||
INSERT INTO application (id, author_id, maintainer_id, title, web, slogan) VALUES (1, 11, 11, 'Adminer', 'http://www.adminer.org/', 'Database management in single PHP file');
|
||||
INSERT INTO application (id, author_id, maintainer_id, title, web, slogan) VALUES (2, 11, NULL, 'JUSH', 'http://jush.sourceforge.net/', 'JavaScript Syntax Highlighter');
|
||||
INSERT INTO application (id, author_id, maintainer_id, title, web, slogan) VALUES (3, 12, 12, 'Nette', 'http://nettephp.com/', 'Nette Framework for PHP 5');
|
||||
INSERT INTO application (id, author_id, maintainer_id, title, web, slogan) VALUES (4, 12, 12, 'Dibi', 'http://dibiphp.com/', 'Database Abstraction Library for PHP 5');
|
||||
|
||||
CREATE TABLE application_tag (
|
||||
application_id int NOT NULL,
|
||||
tag_id int NOT NULL,
|
||||
PRIMARY KEY (application_id, tag_id),
|
||||
CONSTRAINT application_tag_tag FOREIGN KEY (tag_id) REFERENCES tag (id),
|
||||
CONSTRAINT application_tag_application FOREIGN KEY (application_id) REFERENCES application (id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
INSERT INTO application_tag (application_id, tag_id) VALUES (1, 21);
|
||||
INSERT INTO application_tag (application_id, tag_id) VALUES (3, 21);
|
||||
INSERT INTO application_tag (application_id, tag_id) VALUES (4, 21);
|
||||
INSERT INTO application_tag (application_id, tag_id) VALUES (1, 22);
|
||||
INSERT INTO application_tag (application_id, tag_id) VALUES (4, 22);
|
||||
INSERT INTO application_tag (application_id, tag_id) VALUES (2, 23);
|
||||
|
3
vendor/notorm/todo.txt
vendored
Normal file
3
vendor/notorm/todo.txt
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
multi-column primary key - Structure methods could return array
|
||||
Discovery for other drivers
|
||||
defer NotORM_Row creation to save memory
|
Loading…
Reference in a new issue