From 58c0d301dd60e46f23d187d3413eef06257a3725 Mon Sep 17 00:00:00 2001 From: Alex Cabal Date: Tue, 22 Feb 2022 10:49:54 -0600 Subject: [PATCH] Add auto-detected types from DB in ORM --- lib/Db.php | 4 +-- lib/DbConnection.php | 70 ++++++++++++++++++++++++++++++++++++++++---- lib/OrmBase.php | 10 +------ 3 files changed, 67 insertions(+), 17 deletions(-) diff --git a/lib/Db.php b/lib/Db.php index 0a9f93a1..bc65593c 100644 --- a/lib/Db.php +++ b/lib/Db.php @@ -8,7 +8,7 @@ class Db{ /** * @return Array */ - public static function Query(string $query, array $args = []): array{ + public static function Query(string $query, array $args = [], string $class = 'stdClass'): array{ if(!isset($GLOBALS['DbConnection'])){ $GLOBALS['DbConnection'] = new DbConnection(DATABASE_DEFAULT_DATABASE, DATABASE_DEFAULT_HOST); } @@ -17,6 +17,6 @@ class Db{ $args = [$args]; } - return $GLOBALS['DbConnection']->Query($query, $args); + return $GLOBALS['DbConnection']->Query($query, $args, $class); } } diff --git a/lib/DbConnection.php b/lib/DbConnection.php index f4edb8a0..583b28fb 100644 --- a/lib/DbConnection.php +++ b/lib/DbConnection.php @@ -1,4 +1,5 @@ */ - public function Query(string $sql, array $params = []): array{ + public function Query(string $sql, array $params = [], string $class = 'stdClass'): array{ if(!$this->IsConnected){ return []; } @@ -115,7 +116,7 @@ class DbConnection{ $done = false; while(!$done){ try{ - $result = $this->ExecuteQuery($handle); + $result = $this->ExecuteQuery($handle, $class); $done = true; } catch(\PDOException $ex){ @@ -154,14 +155,71 @@ class DbConnection{ /** * @return Array */ - private function ExecuteQuery(PDOStatement $handle): array{ + private function ExecuteQuery(PDOStatement $handle, string $class = 'stdClass'): array{ $handle->execute(); $result = []; do{ try{ - if($handle->columnCount() > 0){ - $result[] = $handle->fetchAll(\PDO::FETCH_OBJ); + $columnCount = $handle->columnCount(); + if($columnCount > 0){ + + $metadata = []; + + for($i = 0; $i < $columnCount; $i++){ + $metadata[$i] = $handle->getColumnMeta($i); + if(preg_match('/^(Is|Has|Can)[A-Z]/u', $metadata[$i]['name']) === 1){ + // MySQL doesn't have a native boolean type, so fake it here if the column + // name starts with Is, Has, or Can and is followed by an uppercase letter + $metadata[$i]['native_type'] = 'BOOL'; + } + } + + $rows = $handle->fetchAll(\PDO::FETCH_NUM); + + if(!is_array($rows)){ + continue; + } + + foreach($rows as $row){ + $object = new $class(); + + for($i = 0; $i < $handle->columnCount(); $i++){ + if($row[$i] === null){ + $object->{$metadata[$i]['name']} = null; + } + else{ + switch($metadata[$i]['native_type']){ + case 'DATETIME': + $object->{$metadata[$i]['name']} = new DateTime($row[$i], new DateTimeZone('UTC')); + break; + + case 'LONG': + case 'TINY': + case 'SHORT': + case 'INT24': + case 'LONGLONG': + $object->{$metadata[$i]['name']} = intval($row[$i]); + break; + + case 'FLOAT': + case 'DOUBLE': + $object->{$metadata[$i]['name']} = floatval($row[$i]); + break; + + case 'BOOL': + $object->{$metadata[$i]['name']} = $row[$i] == 1 ? true : false; + break; + + default: + $object->{$metadata[$i]['name']} = $row[$i]; + break; + } + } + } + + $result[] = $object; + } } } catch(\PDOException $ex){ @@ -176,7 +234,7 @@ class DbConnection{ return $result; } - // Gets the last AUTO-INCREMENT id + // Gets the last auto-increment id public function GetLastInsertedId(): ?int{ $id = $this->_link->lastInsertId(); diff --git a/lib/OrmBase.php b/lib/OrmBase.php index 1aaac458..23089e28 100644 --- a/lib/OrmBase.php +++ b/lib/OrmBase.php @@ -9,15 +9,7 @@ abstract class OrmBase{ public static function FillObject(Object $object, array $row): Object{ foreach($row as $property => $value){ - if(substr($property, strlen($property) - 9) == 'Timestamp'){ - if($value !== null){ - $object->$property = new DateTime($value, new DateTimeZone('UTC')); - } - else{ - $object->$property = null; - } - } - elseif(substr($property, strlen($property) - 5) == 'Cache'){ + if(substr($property, strlen($property) - 5) == 'Cache'){ $property = substr($property, 0, strlen($property) - 5); $object->$property = $value; }