diff --git a/src/Common/EntityResolver.php b/src/Common/EntityResolver.php index e006602..2d27d77 100644 --- a/src/Common/EntityResolver.php +++ b/src/Common/EntityResolver.php @@ -63,7 +63,7 @@ class EntityResolver { break; case static::KEY_COLUMN_NAME: - $key = $tag['object']->name ?? $item['name']; + $key = strtolower($tag['object']->name ?? $item['name']); break; default: diff --git a/src/Common/PdoObject.php b/src/Common/PdoObject.php index b874e7a..fa3c3c9 100644 --- a/src/Common/PdoObject.php +++ b/src/Common/PdoObject.php @@ -22,8 +22,8 @@ class PdoObject extends PDO { } } - public function runQuery(string $sql, array $parameters = []): PDOStatement { - # var_dump($sql, $parameters); die(); + public function runQuery(string $sql, array $parameters = []): ? PDOStatement { + var_dump($sql, $parameters);die(); try { if (false !== ( $statement = $this->prepare($sql) )) { @@ -32,9 +32,11 @@ class PdoObject extends PDO { } catch (\PDOException $e) { throw $e; } + + return null; } - public function execute(PDOStatement $statement, array $parameters = [], bool $commit = true): ?PDOStatement { + public function execute(PDOStatement $statement, array $parameters = [], bool $commit = true): ? PDOStatement { try { if ( ! $this->inTransaction() ) { $this->beginTransaction(); diff --git a/src/ConnectionAdapter.php b/src/ConnectionAdapter.php index 83235a6..a4e6013 100644 --- a/src/ConnectionAdapter.php +++ b/src/ConnectionAdapter.php @@ -14,7 +14,7 @@ class ConnectionAdapter protected AdapterInterface $adapter; - public PdoObject $pdo; + protected PdoObject $pdo; public function __construct(string $name = "default", array $configuration = [], bool $default = false) { @@ -54,6 +54,11 @@ class ConnectionAdapter { return $this->adapter; } + + public function pdo() : PdoObject + { + return $this->pdo ?? $this->pdo = $this->connect()->pdo; + } /** * Instanciate an adapter which interact with the data source diff --git a/src/EntityCollection.php b/src/EntityCollection.php index 1fdfcec..5c3ffe0 100644 --- a/src/EntityCollection.php +++ b/src/EntityCollection.php @@ -18,6 +18,17 @@ class EntityCollection extends \ArrayObject { } } } + + public function filtersCollection(Callable $callback) : self + { + $collection = new static(); + + foreach($this->filters($callback) as $item) { + $collection->append($item); + } + + return $collection; + } public function searchOne($value, string $field) : object { @@ -53,4 +64,4 @@ class EntityCollection extends \ArrayObject { return $list; } -} \ No newline at end of file +} diff --git a/src/EntityTrait.php b/src/EntityTrait.php index d68b20a..0c33a76 100644 --- a/src/EntityTrait.php +++ b/src/EntityTrait.php @@ -15,7 +15,7 @@ trait EntityTrait { /** * @Ignore */ - protected bool $strictEntityFieldsDeclaration = true; + protected bool $strictEntityFieldsDeclaration = false; /** * @Ignore @@ -80,6 +80,11 @@ trait EntityTrait { throw new \Exception(sprintf("[%s] - Undefined variable: %s", static::class, $name)); } + public function __isset(string $name) : bool + { + return isset($this->$name); + } + /** * @Ignore */ diff --git a/src/Query/Join.php b/src/Query/Join.php index c72de34..7420e70 100644 --- a/src/Query/Join.php +++ b/src/Query/Join.php @@ -11,18 +11,27 @@ class Join extends Fragment { const TYPE_CROSS = "CROSS"; const TYPE_NATURAL = "NATURAL"; - public string $type = self::TYPE_INNER; - public bool $outer = false; + + public array $joins = []; + public function add(string $side, string $table, string $field, $value) + { + $this->joins[] = [ + 'side' => $side, + 'table' => $table, + 'field' => $field, + 'value' => $value, + ]; + } + public function render() : string { return $this->renderSegments([ - $this->side, - 'JOIN', - /* table here! */, - 'ON', - /* WHERE ! */ + #'JOIN', + # table, + # 'ON', + # WHERE ! , ]); } } diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php index 0b271a1..42865b5 100644 --- a/src/QueryBuilder.php +++ b/src/QueryBuilder.php @@ -39,15 +39,15 @@ class QueryBuilder public function insert(array $fieldlist, string $table, ? string $alias = null, ? string $database = null, ? string $schema = null) : self { - if ( null === $this->getFragment(Query\Insert::class) ) { - if ( $database ) { - $table = "\"$database\".$table"; - } - + if ( null === $this->getFragment(Query\Insert::class) ) { if ( $schema ) { $table = "\"$schema\".$table"; } + if ( $database ) { + $table = "\"$database\".$table"; + } + $insert = new Query\Insert(); $this->push($insert); @@ -73,14 +73,14 @@ class QueryBuilder public function update(string $table, ? string $alias = null, ? string $database = null, ? string $schema = null) : self { - if ( ! $this->getFragment(Query\Update::class) ) { - if ( $database ) { - $table = "\"$database\".$table"; - } - + if ( ! $this->getFragment(Query\Update::class) ) { if ( $schema ) { $table = "\"$schema\".$table"; } + + if ( $database ) { + $table = "\"$database\".$table"; + } $update = new Query\Update(); $this->push($update); @@ -95,7 +95,7 @@ class QueryBuilder public function set(array $dataset) : self { - if ( null === ( $values = $this->getFragment(Query\Set::class) ) ) { + if ( null === ( $set = $this->getFragment(Query\Set::class) ) ) { $set = new Query\Set($this); $this->push($set); } @@ -116,13 +116,13 @@ class QueryBuilder public function from(string $table, ? string $alias = null, ? string $database = null, ? string $schema = null) : self { - if ( $database ) { - $table = "$database.$table"; - } - if ( $schema ) { $table = "\"$schema\".$table"; } + + if ( $database ) { + $table = "$database.$table"; + } if ( null !== ( $from = $this->getFragment(Query\From::class) ) ) { $from->add($alias ? [ $alias => $table ] : $table); @@ -219,6 +219,28 @@ class QueryBuilder return $this; } + public function join(string $type, $table, $field, $value, bool $outer = false) : self + { + if ( null === $join = $this->getFragment(Query\Join::class) ) { + $join = new Query\Join(); + $this->push($join); + } + + $join->add($type, $table, $field, $value); + + $join->outer = $outer; + + return $this; + } + /* + "LEFT JOIN PAI_DOS ON PAI_DOS.MATR = PAI_DOS_EMPL.MATR" + "LEFT JOIN PAI_DOS_2 ON PAI_DOS_2.MATR = PAI_DOS.MATR" + "LEFT JOIN PAI_CAND ON PAI_CAND.MATR = PAI_DOS.MATR" + + "LEFT JOIN PAI_TAB_CORP_EMPL ON PAI_TAB_CORP_EMPL.CORP_EMPL = PAI_DOS_EMPL.CORP_EMPL", + "LEFT JOIN PAI_TAB_LIEU_TRAV ON PAI_TAB_LIEU_TRAV.LIEU_TRAV = PAI_DOS_EMPL.LIEU_TRAV", + "LEFT JOIN PAI_TAB_BAT ON PAI_TAB_BAT.BAT = PAI_TAB_LIEU_TRAV.BAT" + */ public function push(Query\Fragment $queryFragment) : self { $this->queryStack[] = $queryFragment; @@ -240,6 +262,15 @@ class QueryBuilder return implode(" ", $sql); } + + public function reset() : void + { + $this->parameters = $this->values = $this->queryStack = []; + $this->conditionOperator = Query\Where::CONDITION_AND; + $this->parameterIndex = 0; + + unset($this->where); + } public function getFragment(string $class) : ? Query\Fragment { diff --git a/src/Repository.php b/src/Repository.php index 9975b94..cca915f 100644 --- a/src/Repository.php +++ b/src/Repository.php @@ -31,9 +31,14 @@ class Repository return $this->limit(1)->collectionFromQuery()[0] ?? null; } + public function loadOneFromField($field, $value) : ? object + { + return $this->where($field, $value)->loadOne(); + } + public function loadFromPk($value, $primaryKey = "id") : ? object { - return $this->where($primaryKey, $value)->loadOne(); + return $this->loadOneFromField($primaryKey, $value); } public function loadAll() : EntityCollection @@ -99,24 +104,24 @@ class Repository if ( $primaryKeyDefinition === null ) { throw new \Exception(sprintf("No primary key found for entity %s", $this->entityClass)); } - - $pkField = key($primaryKeyDefinition); - $pkFieldName = $primaryKeyDefinition[$pkField]->name ?? $pkField; - $this->where($pkFieldName, $dataset[$pkFieldName]); - + $diff = array_diff_assoc($dataset, $entity->entityGetDataset(true)); if ( [] !== $diff ) { + $pkField = key($primaryKeyDefinition); + $pkFieldName = $primaryKeyDefinition[$pkField]->name ?? $pkField; + $this->where($pkFieldName, $dataset[$pkFieldName]); + $update = $this->updateSqlQuery($diff)->runQuery(); - return (bool) $update->rowCount(); - } + return $update ? (bool) $update->rowCount() : false; + } } return false; } - public function saveAll(EntityCollection $collection) : bool + public function saveAll(EntityCollection $collection) : void { foreach($collection as $entity) { $this->save($entity); @@ -179,6 +184,8 @@ class Repository public function join(string $type, $table, $field, $value) : self { + $this->queryBuilder->join($type, $table, $field, $value); + return $this; } @@ -370,7 +377,7 @@ class Repository return $entityCollection; } - public function runQuery() : \PDOStatement + public function runQuery() : ? \PDOStatement { $this->finalizeQuery(); diff --git a/src/Ulmus.php b/src/Ulmus.php index d97bd9a..18396a4 100644 --- a/src/Ulmus.php +++ b/src/Ulmus.php @@ -21,14 +21,16 @@ abstract class Ulmus public static function iterateQueryBuilder(QueryBuilder $queryBuilder, ? ConnectionAdapter $adapter = null) : Generator { $sql = $queryBuilder->render(); - $statement = ( $adapter ?: static::$defaultAdapter )->pdo->select($sql, $queryBuilder->parameters ?? []); + + $statement = ( $adapter ?: static::$defaultAdapter )->pdo()->select($sql, $queryBuilder->parameters ?? []); while ( $row = $statement->fetch() ) { yield $row; } $statement->closeCursor(); - + $queryBuilder->reset(); + return [ 'count' => $statement->rowCount(), ]; @@ -36,12 +38,15 @@ abstract class Ulmus public static function pdo(? ConnectionAdapter $adapter = null) : Common\PdoObject { - return ( $adapter ?: static::$defaultAdapter )->pdo; + return ( $adapter ?: static::$defaultAdapter )->pdo(); } public static function runQuery(QueryBuilder $queryBuilder, ? ConnectionAdapter $adapter = null) { - return static::pdo($adapter)->runQuery($queryBuilder->render(), array_merge($queryBuilder->values ?? [], $queryBuilder->parameters ?? [])); + $result = static::pdo($adapter)->runQuery($queryBuilder->render(), array_merge($queryBuilder->values ?? [], $queryBuilder->parameters ?? [])); + $queryBuilder->reset(); + + return $result; } public static function resolveEntity(string $entityClass) : Common\EntityResolver @@ -80,6 +85,9 @@ abstract class Ulmus protected static function fetchQueryBuilder(QueryBuilder $queryBuilder, ? ConnectionAdapter $adapter = null) : array { - return ( $adapter ?: static::$defaultAdapter )->pdo->select($queryBuilder->render(), $queryBuilder->parameters ?? [])->fetchAll(); + $result = ( $adapter ?: static::$defaultAdapter )->pdo->select($queryBuilder->render(), $queryBuilder->parameters ?? [])->fetchAll(); + $queryBuilder->reset(); + + return $result; } }