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>
*/
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);
}
}

View file

@ -1,4 +1,5 @@
<?
use Safe\DateTime;
use function Safe\preg_match;
class DbConnection{
@ -70,7 +71,7 @@ class DbConnection{
/**
* @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){
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<mixed>
*/
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();

View file

@ -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;
}