Aggiunta libreria notorm per collegarsi con pdo al db

This commit is contained in:
gine 2016-10-16 17:19:10 +02:00
parent 6ad9bc1954
commit bb6a3db435
51 changed files with 2530 additions and 0 deletions

104
vendor/notorm/NotORM.php vendored Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

View 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
View 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
View 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

View 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

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

View 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

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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