- A lot of work done on bug fixing. Added a new SQLite adapter

This commit is contained in:
mcndave committed 2022-01-28 16:37:35 +00:00
1 parent 667df92e52
commit c14644cdda
28 files changed
+727 -234

No files matched your search

+75 -118
View File
@@ -7,7 +7,7 @@ use Ulmus\Common\EntityResolver;
class Repository
{
use EventTrait, Repository\ConditionTrait;
use EventTrait, Repository\ConditionTrait, Repository\EscapeTrait;
const DEFAULT_ALIAS = "this";
@@ -28,9 +28,9 @@ class Repository
$this->alias = $alias;
$this->entityResolver = Ulmus::resolveEntity($entity);
$this->adapter = $adapter ?? $this->entityResolver->databaseAdapter();
$this->queryBuilder = new QueryBuilder();
$this->queryBuilder = Ulmus::queryBuilder($entity);
}
public function __clone()
{
#$this->queryBuilder = clone $this->queryBuilder;
@@ -148,9 +148,9 @@ class Repository
# $dataset = array_filter($dataset, fn($item, $field) => ! ($this->entityResolver->searchFieldAnnotation($field, new Field, false)->readonly ?? false), \ARRAY_FILTER_USE_BOTH);
$statement = $this->insertSqlQuery($fieldsAndValue ?? $dataset, $replace)->runInsertQuery();
if ( ( 0 !== $statement->lastInsertId ) &&
( null !== $primaryKeyDefinition )) {
if ( ( 0 !== $statement->lastInsertId ) &&
( null !== $primaryKeyDefinition )) {
$pkField = key($primaryKeyDefinition);
$dataset[$pkField] = $statement->lastInsertId;
@@ -195,74 +195,20 @@ class Repository
}
public function loadCollectionRelation(EntityCollection $collection, /*array|string*/ $fields) : void
{
foreach ((array)$fields as $name) {
if (null !== ($relation = $this->entityResolver->searchFieldAnnotation($name, new Annotation\Property\Relation()))) {
$relationType = strtolower(str_replace(['-', '_', ' '], '', $relation->type));
$order = $this->entityResolver->searchFieldAnnotationList($name, new Annotation\Property\OrderBy());
$where = $this->entityResolver->searchFieldAnnotationList($name, new Annotation\Property\Where());
$baseEntity = $relation->entity ?? $relation->bridge ?? $this->entityResolver->properties[$name]['type'];
$baseEntityResolver = $baseEntity::resolveEntity();
$property = ($baseEntityResolver->field($relation->foreignKey, 01, false) ?: $baseEntityResolver->field($relation->foreignKey, 02))['name'];
$entityProperty = ($this->entityResolver->field($relation->key, 01, false) ?: $this->entityResolver->field($relation->key, 02))['name'];
$repository = $baseEntity::repository();
foreach ($where as $condition) {
$repository->where($condition->field, is_callable($condition->value) ? call_user_func_array($condition->value, [$this]) : $condition->value, $condition->operator, $condition->condition);
}
foreach ($order as $item) {
$repository->orderBy($item->field, $item->order);
}
$field = $relation->key;
$values = [];
$key = is_object($relation->foreignKey) ? $relation->foreignKey : $baseEntity::field($relation->foreignKey);
foreach ($collection as $item) {
$values[] = is_callable($field) ? $field($item) : $item->$entityProperty;
}
$repository->where($key, $values);
switch ($relationType) {
case 'onetoone':
$results = call_user_func([$repository, "loadOne"]);
$item->$name = $results ?: new $baseEntity();
break;
case 'onetomany':
$results = call_user_func([$repository, $relation->function]);
foreach ($collection as $item) {
$item->$name = $baseEntity::entityCollection();
$item->$name->mergeWith($results->filtersCollection(fn($e) => $e->$property === $item->$entityProperty));
}
break;
}
}
}
}
public function replace(/*object|array*/ $entity, ? array $fieldsAndValue = null) : bool
{
return $this->save($entity, $fieldsAndValue, true);
}
public function replaceAll(/*EntityCollection|array*/ $collection) : void
public function replaceAll(/*EntityCollection|array*/ $collection) : int
{
$changed = 0;
foreach($collection as $entity) {
$this->replace($entity);
$this->replace($entity) && $changed++;
}
return $changed;
}
public function truncate(? string $table = null, ? string $alias = null, ? string $schema = null) : self
@@ -489,10 +435,10 @@ class Repository
public function randomizeOrder() : self
{
$this->queryBuilder->orderBy(Common\Sql::function('RAND', Sql::identifier('CURDATE()+0')));
return $this;
}
public function orders(array $orderList) : self
{
foreach($orderList as $field => $direction) {
@@ -678,6 +624,64 @@ class Repository
return $this;
}
public function loadCollectionRelation(EntityCollection $collection, /*array|string*/ $fields) : void
{
foreach ((array)$fields as $name) {
if (null !== ($relation = $this->entityResolver->searchFieldAnnotation($name, new Annotation\Property\Relation()))) {
$relationType = strtolower(str_replace(['-', '_', ' '], '', $relation->type));
$order = $this->entityResolver->searchFieldAnnotationList($name, new Annotation\Property\OrderBy());
$where = $this->entityResolver->searchFieldAnnotationList($name, new Annotation\Property\Where());
$baseEntity = $relation->entity ?? $relation->bridge ?? $this->entityResolver->properties[$name]['type'];
$baseEntityResolver = $baseEntity::resolveEntity();
$property = ($baseEntityResolver->field($relation->foreignKey, 01, false) ?: $baseEntityResolver->field($relation->foreignKey, 02))['name'];
$entityProperty = ($this->entityResolver->field($relation->key, 01, false) ?: $this->entityResolver->field($relation->key, 02))['name'];
$repository = $baseEntity::repository();
foreach ($where as $condition) {
$repository->where($condition->field, is_callable($condition->value) ? call_user_func_array($condition->value, [$this]) : $condition->value, $condition->operator, $condition->condition);
}
foreach ($order as $item) {
$repository->orderBy($item->field, $item->order);
}
$field = $relation->key;
$values = [];
$key = is_object($relation->foreignKey) ? $relation->foreignKey : $baseEntity::field($relation->foreignKey);
foreach ($collection as $item) {
$values[] = is_callable($field) ? $field($item) : $item->$entityProperty;
}
$repository->where($key, $values);
switch ($relationType) {
case 'onetoone':
$results = call_user_func([$repository, "loadOne"]);
$item->$name = $results ?: new $baseEntity();
break;
case 'onetomany':
$results = call_user_func([$repository, $relation->function]);
foreach ($collection as $item) {
$item->$name = $baseEntity::entityCollection();
$item->$name->mergeWith($results->filtersCollection(fn($e) => $e->$property === $item->$entityProperty));
}
break;
}
}
}
}
public function filterServerRequest(SearchRequest\SearchRequestInterface $searchRequest, bool $count = true) : self
{
if ($count) {
@@ -819,13 +823,7 @@ class Repository
public function createSqlQuery() : self
{
if ( null === $this->queryBuilder->getFragment(Query\Create::class) ) {
$this->queryBuilder->create($this->escapeFieldList($this->entityResolver->fieldList(EntityResolver::KEY_ENTITY_NAME, true)), $this->escapeTable($this->entityResolver->tableName()), $this->entityResolver->schemaName());
}
if ( null === $this->queryBuilder->getFragment(Query\Engine::class) ) {
if ( $engine = $this->entityResolver->tableAnnotation()->engine ?? $this->entityResolver->databaseAdapter()->adapter()->defaultEngine() ) {
$this->queryBuilder->engine($engine);
}
$this->queryBuilder->create($this->adapter->adapter(), $this->escapeFieldList($this->entityResolver->fieldList(EntityResolver::KEY_ENTITY_NAME, true)), $this->escapeTable($this->entityResolver->tableName()), $this->entityResolver->schemaName());
}
return $this;
@@ -834,7 +832,7 @@ class Repository
public function alterSqlQuery(array $fields) : self
{
if ( null === $this->queryBuilder->getFragment(Query\Alter::class) ) {
$this->queryBuilder->create($this->escapeFieldList($this->entityResolver->fieldList(EntityResolver::KEY_ENTITY_NAME, true)), $this->escapeTable($this->entityResolver->tableName()), $this->entityResolver->schemaName());
$this->queryBuilder->create($this->adapter->adapter(), $this->escapeFieldList($this->entityResolver->fieldList(EntityResolver::KEY_ENTITY_NAME, true)), $this->escapeTable($this->entityResolver->tableName()), $this->entityResolver->schemaName());
}
@@ -859,7 +857,7 @@ class Repository
return $result;
}
public function instanciateEntityCollection(...$arguments) : EntityCollection
{
return $this->entityClass::entityCollection(...$arguments);
@@ -870,47 +868,6 @@ class Repository
return new $this->entityClass();
}
public function escapeField(string $identifier) : string
{
return $this->adapter->adapter()->escapeIdentifier($identifier, Adapter\AdapterInterface::IDENTIFIER_FIELD);
}
public function escapeFieldList(array $fieldList) : array
{
foreach($fieldList as &$list) {
$list['name'] = $this->escapeField($list['name']);
$fieldTag = array_filter($list['tags'] ?? [], fn($item) => $item['object'] instanceof Field)[0]['object'] ?? null;
if ( $fieldTag && isset($fieldTag->name) ) {
$fieldTag->name = $this->escapeField($fieldTag->name);
}
}
return $fieldList;
}
public function escapeTable(string $identifier) : string
{
return $this->adapter->adapter()->escapeIdentifier($identifier, Adapter\AdapterInterface::IDENTIFIER_TABLE);
}
public function escapeDatabase(string $identifier) : string
{
return $this->adapter->adapter()->escapeIdentifier($identifier, Adapter\AdapterInterface::IDENTIFIER_DATABASE);
}
public function escapedDatabase() : ? string
{
$name = $this->entityResolver->tableAnnotation()->database ?? $this->adapter->adapter()->database ?? null;
return $name ? static::escapeDatabase($name) : null;
}
public function escapeSchema(string $identifier) : string
{
return $this->adapter->adapter()->escapeIdentifier($identifier, Adapter\AdapterInterface::IDENTIFIER_SCHEMA);
}
public function hasFilters() : bool
{