Add auto-detected types from DB in ORM

This commit is contained in:
Alex Cabal 2022-02-22 10:49:54 -06:00
parent 7a11cacf6d
commit 58c0d301dd
3 changed files with 67 additions and 17 deletions

View file

@ -8,7 +8,7 @@ class Db{
/** /**
* @return Array<mixed> * @return Array<mixed>
*/ */
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'])){ if(!isset($GLOBALS['DbConnection'])){
$GLOBALS['DbConnection'] = new DbConnection(DATABASE_DEFAULT_DATABASE, DATABASE_DEFAULT_HOST); $GLOBALS['DbConnection'] = new DbConnection(DATABASE_DEFAULT_DATABASE, DATABASE_DEFAULT_HOST);
} }
@ -17,6 +17,6 @@ class Db{
$args = [$args]; $args = [$args];
} }
return $GLOBALS['DbConnection']->Query($query, $args); return $GLOBALS['DbConnection']->Query($query, $args, $class);
} }
} }

View file

@ -1,4 +1,5 @@
<? <?
use Safe\DateTime;
use function Safe\preg_match; use function Safe\preg_match;
class DbConnection{ class DbConnection{
@ -70,7 +71,7 @@ class DbConnection{
/** /**
* @return Array<mixed> * @return Array<mixed>
*/ */
public function Query(string $sql, array $params = []): array{ public function Query(string $sql, array $params = [], string $class = 'stdClass'): array{
if(!$this->IsConnected){ if(!$this->IsConnected){
return []; return [];
} }
@ -115,7 +116,7 @@ class DbConnection{
$done = false; $done = false;
while(!$done){ while(!$done){
try{ try{
$result = $this->ExecuteQuery($handle); $result = $this->ExecuteQuery($handle, $class);
$done = true; $done = true;
} }
catch(\PDOException $ex){ catch(\PDOException $ex){
@ -154,14 +155,71 @@ class DbConnection{
/** /**
* @return Array<mixed> * @return Array<mixed>
*/ */
private function ExecuteQuery(PDOStatement $handle): array{ private function ExecuteQuery(PDOStatement $handle, string $class = 'stdClass'): array{
$handle->execute(); $handle->execute();
$result = []; $result = [];
do{ do{
try{ try{
if($handle->columnCount() > 0){ $columnCount = $handle->columnCount();
$result[] = $handle->fetchAll(\PDO::FETCH_OBJ); 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){ catch(\PDOException $ex){
@ -176,7 +234,7 @@ class DbConnection{
return $result; return $result;
} }
// Gets the last AUTO-INCREMENT id // Gets the last auto-increment id
public function GetLastInsertedId(): ?int{ public function GetLastInsertedId(): ?int{
$id = $this->_link->lastInsertId(); $id = $this->_link->lastInsertId();

View file

@ -9,15 +9,7 @@ abstract class OrmBase{
public static function FillObject(Object $object, array $row): Object{ public static function FillObject(Object $object, array $row): Object{
foreach($row as $property => $value){ foreach($row as $property => $value){
if(substr($property, strlen($property) - 9) == 'Timestamp'){ if(substr($property, strlen($property) - 5) == 'Cache'){
if($value !== null){
$object->$property = new DateTime($value, new DateTimeZone('UTC'));
}
else{
$object->$property = null;
}
}
elseif(substr($property, strlen($property) - 5) == 'Cache'){
$property = substr($property, 0, strlen($property) - 5); $property = substr($property, 0, strlen($property) - 5);
$object->$property = $value; $object->$property = $value;
} }