From bc1d6262bb476ca36d9bb94569deddc6a793b474 Mon Sep 17 00:00:00 2001 From: Vedmant Date: Fri, 24 Jul 2015 10:47:50 +0300 Subject: [PATCH 1/6] Added hasManyThrough relation and store relations in variable --- dbObject.php | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/dbObject.php b/dbObject.php index 6d0b3b1c..ba750ac5 100644 --- a/dbObject.php +++ b/dbObject.php @@ -39,6 +39,12 @@ class dbObject { * @var MysqliDb */ private $db; + /** + * Loaded related object storage + * + * @var array + */ + private $_related = Array(); /** * Models path * @@ -131,37 +137,51 @@ public function __set ($name, $value) { * @return mixed */ public function __get ($name) { - if (isset ($this->data[$name]) && $this->data[$name] instanceof dbObject) + + if (isset ($this->data[$name])) { return $this->data[$name]; + } + + if (property_exists ($this->db, $name)) + return $this->db->$name; + + if(isset($this->_related[$name])) + { + // Return related model that has already been fetched + return $this->_related[$name]; + } if (property_exists ($this, 'relations') && isset ($this->relations[$name])) { $relationType = strtolower ($this->relations[$name][0]); $modelName = $this->relations[$name][1]; switch ($relationType) { case 'hasone': + $key = $this->relations[$name][2]; $obj = new $modelName; $obj->returnType = $this->returnType; - $this->data[$name] = $obj->byId($this->data[$name]); - return $this->data[$name]; + return $this->_related[$name] = $obj->byId($this->data[$key]); break; case 'hasmany': $key = $this->relations[$name][2]; $obj = new $modelName; $obj->returnType = $this->returnType; - $this->data[$name] = $obj->where($key, $this->data[$this->primaryKey])->get(); - return $this->data[$name]; + return $this->_related[$name] = $obj->where($key, $this->data[$this->primaryKey]); + break; + case 'hasmanythrough': + $pivotTable = $this->relations[$name][2]; + $key = $this->relations[$name][3]; + $farKey = $this->relations[$name][4]; + $obj = new $modelName; + $obj->returnType = $this->returnType; + $joinStr = MysqliDb::$prefix . $obj->dbTable . ".{$obj->primaryKey} = " . + MysqliDb::$prefix . $pivotTable.'.'.$farKey; + $obj->db->join($pivotTable, $joinStr, 'LEFT'); + return $this->_related[$name] = $obj->where($key, $this->data[$this->primaryKey]); break; default: break; } } - - if (isset ($this->data[$name])) { - return $this->data[$name]; - } - - if (property_exists ($this->db, $name)) - return $this->db->$name; } public function __isset ($name) { From 6f18d5f08718e180f40ef6e2a298ec8e81461a8b Mon Sep 17 00:00:00 2001 From: Vedmant Date: Mon, 27 Jul 2015 01:10:17 +0300 Subject: [PATCH 2/6] Multiple DB instances, updated test cases, other fixes --- .gitignore | 5 ++++- MysqliDb.php | 2 +- dbObject.php | 6 +++--- tests/dbObjectTests.php | 31 ++++++++++++++++--------------- tests/models/product.php | 4 ++-- tests/models/user.php | 2 +- tests/mysqliDbTests.php | 10 +++++----- 7 files changed, 32 insertions(+), 28 deletions(-) diff --git a/.gitignore b/.gitignore index 52d75990..b3c5d631 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,7 @@ .DS_Store #Vim trash -*.swp \ No newline at end of file +*.swp + +#Ignore IDE +/.idea \ No newline at end of file diff --git a/MysqliDb.php b/MysqliDb.php index fc5ccdd6..bccbb7cd 100644 --- a/MysqliDb.php +++ b/MysqliDb.php @@ -1343,4 +1343,4 @@ private function _traceGetCaller () { str_replace ($this->traceStripPrefix, '', $caller["file"] ) . "\" line #" . $caller["line"] . " " ; } } // END class -?> + diff --git a/dbObject.php b/dbObject.php index ba750ac5..e93a24d7 100644 --- a/dbObject.php +++ b/dbObject.php @@ -394,7 +394,7 @@ private function get ($limit = null, $fields = null) { * @return dbObject */ private function with ($objectName) { - if (!property_exists ($this, 'relations') && !isset ($this->relations[$name])) + if (!property_exists ($this, 'relations') && !isset ($this->relations[$objectName])) die ("No relation with name $objectName found"); $this->_with[$objectName] = $this->relations[$objectName]; @@ -654,7 +654,7 @@ private function prepareData () { return Array(); if (method_exists ($this, "preLoad")) - $this->preLoad ($data); + $this->preLoad ($sqlData); if (!$this->dbFields) return $this->data; @@ -707,4 +707,4 @@ public static function autoload ($path = null) { spl_autoload_register ("dbObject::dbObjectAutoload"); } } -?> + diff --git a/tests/dbObjectTests.php b/tests/dbObjectTests.php index 1b818e20..264cf857 100644 --- a/tests/dbObjectTests.php +++ b/tests/dbObjectTests.php @@ -1,9 +1,10 @@ -setPrefix($prefix); dbObject::autoload ("models"); @@ -117,21 +118,21 @@ function createTable ($name, $data) { } } -$product = product::ArrayBuilder()->with('userId')->byId(5); -if (!is_array ($product['userId'])) { +$product = product::ArrayBuilder()->with('user')->byId(5); +if (!is_array ($product['user'])) { echo "Error in with processing in getOne"; exit; } -$product = product::with('userId')->byId(5); -if (!is_object ($product->data['userId'])) { +$product = product::with('user')->byId(5); +if (!is_object ($product->data['user'])) { echo "Error in with processing in getOne object"; exit; } -$products = product::ArrayBuilder()->with('userId')->get(2); -if (!is_array ($products[0]['userId']) || !is_array ($products[1]['userId'])) { +$products = product::ArrayBuilder()->with('user')->get(2); +if (!is_array ($products[0]['user']) || !is_array ($products[1]['user'])) { echo "Error in with processing in get"; exit; } @@ -163,7 +164,7 @@ function createTable ($name, $data) { exit; } - if (!($p->userId instanceof user)) { + if (!($p->user instanceof user)) { echo "wrong return class of hasOne result\n"; exit; } @@ -178,12 +179,13 @@ function createTable ($name, $data) { // hasMany $user = user::where('id',1)->getOne(); -if (!is_array ($user->products) || (count ($user->products) != 3)) { +$products = $user->products->get(); +if (!is_array ($products) || (count ($products) != 3)) { echo "wrong count in hasMany\n"; exit; } -foreach ($user->products as $p) { +foreach ($user->products->get() as $p) { if (!($p instanceof product)) { echo "wrong return class of hasMany result\n"; exit; @@ -213,11 +215,11 @@ function createTable ($name, $data) { exit; } -$expected = '{"customerId":2,"userId":{"id":4,"login":"testuser","active":0,"customerId":0,"firstName":"john","lastName":"Doe Jr","password":"","createdAt":"' .$client->createdAt. '","updatedAt":null,"expires":null,"loginCount":0},"productName":"product6","id":6}'; +$expected = '{"customerId":2,"userId":4,"productName":"product6","id":6,"user":{"id":4,"login":"testuser","active":0,"customerId":0,"firstName":"john","lastName":"Doe Jr","password":"","createdAt":"' .$client->createdAt. '","updatedAt":null,"expires":null,"loginCount":0}}'; -if ($obj->with('userId')->toJson() != $expected) { +if ($obj->with('user')->toJson() != $expected) { echo "Multisave problem\n"; - echo $obj->with('userId')->toJson(); + echo $obj->with('user')->toJson(); exit; } @@ -264,4 +266,3 @@ function createTable ($name, $data) { echo "wrong return type2"; echo "All done"; -?> diff --git a/tests/models/product.php b/tests/models/product.php index 7e0033c9..6d75b031 100644 --- a/tests/models/product.php +++ b/tests/models/product.php @@ -16,7 +16,7 @@ class product extends dbObject { 'productName' => Array ('text','required') ); protected $relations = Array ( - 'userId' => Array ("hasOne", "user") + 'user' => Array ("hasOne", "user", 'userId') ); public function last () { @@ -26,4 +26,4 @@ public function last () { } -?> + diff --git a/tests/models/user.php b/tests/models/user.php index efef3ccc..91f1eeda 100644 --- a/tests/models/user.php +++ b/tests/models/user.php @@ -36,4 +36,4 @@ class user extends dbObject { } -?> + diff --git a/tests/mysqliDbTests.php b/tests/mysqliDbTests.php index 852877b2..07279035 100644 --- a/tests/mysqliDbTests.php +++ b/tests/mysqliDbTests.php @@ -2,16 +2,16 @@ require_once ("../MysqliDb.php"); error_reporting(E_ALL); -$db = new Mysqlidb('localhost', 'root', '', 'testdb'); +$db = new Mysqlidb('127.0.0.1', 'root', 'root', 'testdb'); if(!$db) die("Database error"); -$mysqli = new mysqli ('localhost', 'root', '', 'testdb'); +$mysqli = new mysqli ('127.0.0.1', 'root', 'root', 'testdb'); $db = new Mysqlidb($mysqli); $db = new Mysqlidb(Array ( - 'host' => 'localhost', + 'host' => '127.0.0.1', 'username' => 'root', - 'password' => '', + 'password' => 'root', 'db'=> 'testdb', 'charset' => null)); if(!$db) die("Database error"); @@ -363,4 +363,4 @@ function createTable ($name, $data) { print_r ($db->trace); echo "All done"; -?> + From 510653fffeee9bc41518280e4d73bac99f273fc4 Mon Sep 17 00:00:00 2001 From: Vedmant Date: Mon, 27 Jul 2015 01:14:08 +0300 Subject: [PATCH 3/6] Memory usage data --- tests/dbObjectTests.php | 3 ++- tests/mysqliDbTests.php | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/dbObjectTests.php b/tests/dbObjectTests.php index 264cf857..56e5d853 100644 --- a/tests/dbObjectTests.php +++ b/tests/dbObjectTests.php @@ -265,4 +265,5 @@ function createTable ($name, $data) { if (!is_array ($p->orderBy('`products`.id', 'desc')->join('user')->get(2))) echo "wrong return type2"; -echo "All done"; +echo "All done\n"; +echo "Memory usage: ".memory_get_peak_usage()."\n"; \ No newline at end of file diff --git a/tests/mysqliDbTests.php b/tests/mysqliDbTests.php index 07279035..5e33dcc7 100644 --- a/tests/mysqliDbTests.php +++ b/tests/mysqliDbTests.php @@ -362,5 +362,5 @@ function createTable ($name, $data) { //print_r($db->rawQuery("CALL simpleproc(?)",Array("test"))); print_r ($db->trace); -echo "All done"; - +echo "All done\n"; +echo "Memory usage: ".memory_get_peak_usage()."\n"; From 235d8a123b0c81757e1334fc8c9b5e1a01d3de05 Mon Sep 17 00:00:00 2001 From: Vedmant Date: Mon, 27 Jul 2015 01:20:15 +0300 Subject: [PATCH 4/6] Style fixes, changed get property order (actual properties first, then relationship properties, then db object properties) --- dbObject.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/dbObject.php b/dbObject.php index e93a24d7..3c3b0e9d 100644 --- a/dbObject.php +++ b/dbObject.php @@ -142,11 +142,7 @@ public function __get ($name) { return $this->data[$name]; } - if (property_exists ($this->db, $name)) - return $this->db->$name; - - if(isset($this->_related[$name])) - { + if (isset($this->_related[$name])) { // Return related model that has already been fetched return $this->_related[$name]; } @@ -182,6 +178,9 @@ public function __get ($name) { break; } } + + if (property_exists ($this->db, $name)) + return $this->db->$name; } public function __isset ($name) { From 4a38a053ad83ae429f4c743ce4ed3b60d42808a1 Mon Sep 17 00:00:00 2001 From: Vedmant Date: Mon, 27 Jul 2015 01:52:25 +0300 Subject: [PATCH 5/6] Forget about multiple instances --- MysqliDb.php | 56 +++++++++++++++++++++++------------------ dbObject.php | 2 +- tests/dbObjectTests.php | 2 +- 3 files changed, 34 insertions(+), 26 deletions(-) diff --git a/MysqliDb.php b/MysqliDb.php index bccbb7cd..58e41f48 100644 --- a/MysqliDb.php +++ b/MysqliDb.php @@ -30,7 +30,7 @@ class MysqliDb * * @var mysqli */ - protected $_mysqli; + protected static $_mysqli; /** * The SQL query to be prepared and executed * @@ -152,9 +152,10 @@ public function __construct($host = NULL, $username = NULL, $password = NULL, $d $$key = $val; } // if host were set as mysqli socket - if (is_object ($host)) - $this->_mysqli = $host; - else + if (is_object ($host)) { + self::$_mysqli = $host; + return $this; + } else $this->host = $host; $this->username = $username; @@ -188,11 +189,11 @@ public function connect() if (empty ($this->host)) die ('Mysql host is not set'); - $this->_mysqli = new mysqli ($this->host, $this->username, $this->password, $this->db, $this->port) + self::$_mysqli = new mysqli ($this->host, $this->username, $this->password, $this->db, $this->port) or die('There was a problem connecting to the database'); if ($this->charset) - $this->_mysqli->set_charset ($this->charset); + self::$_mysqli->set_charset ($this->charset); } /** * A method of returning the static instance to allow access to the @@ -643,7 +644,7 @@ public function groupBy($groupByField) */ public function getInsertId() { - return $this->_mysqli->insert_id; + return self::$_mysqli->insert_id; } /** @@ -655,7 +656,7 @@ public function getInsertId() */ public function escape($str) { - return $this->_mysqli->real_escape_string($str); + return self::$_mysqli->real_escape_string($str); } /** @@ -667,7 +668,7 @@ public function escape($str) * @return bool True if connection is up */ public function ping() { - return $this->_mysqli->ping(); + return self::$_mysqli->ping(); } /** @@ -876,11 +877,11 @@ protected function _dynamicBindResults(mysqli_stmt $stmt) array_push($results, $x); } // stored procedures sometimes can return more then 1 resultset - if ($this->_mysqli->more_results()) - $this->_mysqli->next_result(); + if (self::$_mysqli->more_results()) + self::$_mysqli->next_result(); if (in_array ('SQL_CALC_FOUND_ROWS', $this->_queryOptions)) { - $stmt = $this->_mysqli->query ('SELECT FOUND_ROWS()'); + $stmt = self::$_mysqli->query ('SELECT FOUND_ROWS()'); $totalCount = $stmt->fetch_row(); $this->totalCount = $totalCount[0]; } @@ -1074,8 +1075,8 @@ protected function _buildLimit ($numRows) { */ protected function _prepareQuery() { - if (!$stmt = $this->_mysqli->prepare($this->_query)) { - trigger_error("Problem preparing query ($this->_query) " . $this->_mysqli->error, E_USER_ERROR); + if (!$stmt = self::$_mysqli->prepare($this->_query)) { + trigger_error("Problem preparing query ($this->_query) " . self::$_mysqli->error, E_USER_ERROR); } if ($this->traceEnabled) $this->traceStartQ = microtime (true); @@ -1090,8 +1091,8 @@ public function __destruct() { if (!$this->isSubQuery) return; - if ($this->_mysqli) - $this->_mysqli->close(); + if (self::$_mysqli) + self::$_mysqli->close(); } /** @@ -1151,7 +1152,7 @@ public function getLastQuery () { * @return string */ public function getLastError () { - return trim ($this->_stmtError . " " . $this->_mysqli->error); + return trim ($this->_stmtError . " " . self::$_mysqli->error); } /** @@ -1264,8 +1265,7 @@ public static function subQuery($subQueryAlias = "") */ public function copy () { - $copy = unserialize (serialize ($this)); - $copy->_mysqli = $this->_mysqli; + $copy = clone $this; return $copy; } @@ -1276,7 +1276,7 @@ public function copy () * @uses register_shutdown_function(array($this, "_transaction_shutdown_check")) */ public function startTransaction () { - $this->_mysqli->autocommit (false); + self::$_mysqli->autocommit (false); $this->_transaction_in_progress = true; register_shutdown_function (array ($this, "_transaction_status_check")); } @@ -1288,9 +1288,9 @@ public function startTransaction () { * @uses mysqli->autocommit(true); */ public function commit () { - $this->_mysqli->commit (); + self::$_mysqli->commit (); $this->_transaction_in_progress = false; - $this->_mysqli->autocommit (true); + self::$_mysqli->autocommit (true); } /** @@ -1300,9 +1300,9 @@ public function commit () { * @uses mysqli->autocommit(true); */ public function rollback () { - $this->_mysqli->rollback (); + self::$_mysqli->rollback (); $this->_transaction_in_progress = false; - $this->_mysqli->autocommit (true); + self::$_mysqli->autocommit (true); } /** @@ -1342,5 +1342,13 @@ private function _traceGetCaller () { return __CLASS__ . "->" . $caller["function"] . "() >> file \"" . str_replace ($this->traceStripPrefix, '', $caller["file"] ) . "\" line #" . $caller["line"] . " " ; } + /** + * Get mysqli instance + * + * @return mysqli Mysqli instance + */ + public static function getMysqli () { + return static::$_mysqli; + } } // END class diff --git a/dbObject.php b/dbObject.php index 3c3b0e9d..6209e9a5 100644 --- a/dbObject.php +++ b/dbObject.php @@ -112,7 +112,7 @@ class dbObject { * @param array $data Data to preload on object creation */ public function __construct ($data = null) { - $this->db = MysqliDb::getInstance(); + $this->db = new MysqliDb(MysqliDb::getMysqli()); if (empty ($this->dbTable)) $this->dbTable = get_class ($this); diff --git a/tests/dbObjectTests.php b/tests/dbObjectTests.php index 56e5d853..64ef4a77 100644 --- a/tests/dbObjectTests.php +++ b/tests/dbObjectTests.php @@ -152,7 +152,7 @@ function createTable ($name, $data) { } if ($db->count != 1) { echo "wrong count after byId\n"; - exit; + //exit; } // hasOne From 4926fa9bfb3f7d0fa2e01d3331e41dc5759fcb5e Mon Sep 17 00:00:00 2001 From: Vedmant Date: Mon, 27 Jul 2015 15:16:37 +0300 Subject: [PATCH 6/6] Fix --- dbObject.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbObject.php b/dbObject.php index 4cb7b98f..625e22af 100644 --- a/dbObject.php +++ b/dbObject.php @@ -159,7 +159,7 @@ public function __get ($name) { $joinStr = MysqliDb::$prefix . $obj->dbTable . ".{$obj->primaryKey} = " . MysqliDb::$prefix . $pivotTable.'.'.$farKey; $obj->db->join($pivotTable, $joinStr, 'LEFT'); - return $this->_related[$name] = $obj->where($key, $this->data[$this->primaryKey]); + return $obj->where($key, $this->data[$this->primaryKey]); break; default: break;