- Merge with Mssql repository bugfix

This commit is contained in:
Dave M. 2022-06-21 15:38:06 +00:00
parent 724ab250ab
commit e1990e7cc0
11 changed files with 95 additions and 87 deletions

View File

@ -100,8 +100,11 @@ class MsSQL implements AdapterInterface {
if ( $this->encrypt ?? false ) {
$parts[] = "Encrypt=1";
}
else {
$parts[] = "Encrypt=0";
}
if ( $this->failoverPartner ?? false ) {
if ( $this->failoverPartner ?? false ) {
$parts[] = "Failover_Partner={$this->failoverPartner}";
}
@ -130,7 +133,7 @@ class MsSQL implements AdapterInterface {
}
if ( $this->trustServerCertificate ?? false ) {
$parts[] = "TrustServerCertificate=1";
$parts[] = "TrustServerCertificate=yes";
}
if ( $this->WSID ?? false ) {
@ -235,4 +238,8 @@ class MsSQL implements AdapterInterface {
return Repository\MssqlRepository::class;
}
public function queryBuilderClass() : string
{
return QueryBuilder\MssqlQueryBuilder::class;
}
}

View File

@ -137,4 +137,14 @@ class SQLite implements AdapterInterface {
'unsigned' => "",
];
}
public function repositoryClass() : string
{
return Repository\SqliteRepository::class;
}
public function queryBuilderClass() : string
{
return QueryBuilder\SqliteQueryBuilder::class;
}
}

View File

@ -44,6 +44,11 @@ class EntityCollection extends \ArrayObject {
}
}
public function filtersArray(Callable $callback) : array
{
return $this->filtersCollection($callback, true, false)->toArray();
}
public function filtersOne(Callable $callback) : ? object
{
foreach($this->filters($callback, true) as $item) {

View File

@ -204,6 +204,10 @@ trait EntityTrait {
*/
public function isLoaded() : bool
{
if (empty($this->entityLoadedDataset)) {
return false;
}
if ( null === $pkField = $this->resolveEntity()->getPrimaryKeyField($this) ) {
throw new Exception\EntityPrimaryKeyUnknown(sprintf("Entity %s has no field containing attributes 'primary_key'", static::class));
}
@ -315,7 +319,7 @@ trait EntityTrait {
*/
public static function field($name, ? string $alias = null) : EntityField
{
return new EntityField(static::class, $name, $alias ?: Repository::DEFAULT_ALIAS, Ulmus::resolveEntity(static::class));
return new EntityField(static::class, $name, $alias ? Ulmus::repository(static::class)->adapter->adapter()->escapeIdentifier($alias, Adapter\AdapterInterface::IDENTIFIER_FIELD) : Repository::DEFAULT_ALIAS, Ulmus::resolveEntity(static::class));
}
/**

View File

@ -247,6 +247,10 @@ class QueryBuilder implements Query\QueryBuilderInterface
$limit->set($value);
if ($value === 0) {
$this->removeFragment(Query\Limit::class);
}
return $this;
}

View File

@ -2,11 +2,9 @@
namespace Ulmus\QueryBuilder;
use Ulmus\QueryBuilder;
use Ulmus\{Query, QueryBuilder };
use Ulmus\Query;
class MssqlQueryBuilder extends QueryBuilder implements Ulmus\Query\QueryBuilderInterface
class MssqlQueryBuilder extends QueryBuilder implements Query\QueryBuilderInterface
{
public function limit(int $value) : self
{
@ -17,6 +15,10 @@ class MssqlQueryBuilder extends QueryBuilder implements Ulmus\Query\QueryBuilder
$offset->limit = $value;
if ($value === 0) {
$this->removeFragment(Query\MsSQL\Offset::class);
}
return $this;
}

View File

@ -68,7 +68,7 @@ class Repository
public function count() : int
{
$this->removeQueryFragment(Query\Select::class);
$this->removeQueryFragment([ Query\Select::class, Query\OrderBy::class, ]);
if ( $this->queryBuilder->getFragment(Query\GroupBy::class) ) {
$this->select( "DISTINCT COUNT(*) OVER ()" );
@ -149,16 +149,20 @@ class Repository
$statement = $this->insertSqlQuery($fieldsAndValue ?? $dataset, $replace)->runInsertQuery();
if ( ( 0 !== $statement->lastInsertId ) &&
( null !== $primaryKeyDefinition )) {
if ( null !== $primaryKeyDefinition ) {
$pkField = key($primaryKeyDefinition);
$dataset[$pkField] = $statement->lastInsertId;
if ($statement->lastInsertId ) {
$dataset[$pkField] = $statement->lastInsertId;
}
elseif ($replace) {
$pkValue = $dataset[$pkField];
}
}
$entity->entityFillFromDataset($dataset, true);
return (bool) $statement->lastInsertId;
return (bool) ($pkValue ?? $statement->lastInsertId);
}
else {
if ( $primaryKeyDefinition === null ) {
@ -270,7 +274,7 @@ class Repository
{
$schema = $schema ?: $this->entityResolver->schemaName();
$this->queryBuilder->truncate($this->escapeTable($table ?: $this->entityResolver->tableName()), $alias ?: $this->alias, $this->escapedDatabase(), $schema ? $this->escapeSchema($schema) : null);
$this->queryBuilder->truncate($this->escapeTable($table ?: $this->entityResolver->tableName()), $this->escapeIdentifier($alias ?: $this->alias), $this->escapedDatabase(), $schema ? $this->escapeSchema($schema) : null);
$this->finalizeQuery();
@ -336,7 +340,7 @@ class Repository
foreach ($entity::resolveEntity()->fieldList(Common\EntityResolver::KEY_COLUMN_NAME, true) as $key => $field) {
if (null === $entity::resolveEntity()->searchFieldAnnotation($field['name'], new RelationIgnore)) {
$this->select("$alias.$key as {$prependField}{$field['name']}");
$this->select(sprintf("%s.$key as {$prependField}{$field['name']}", $this->escapeIdentifier($alias)));
}
}
@ -350,7 +354,7 @@ class Repository
foreach ($entity::resolveEntity()->fieldList(Common\EntityResolver::KEY_COLUMN_NAME, true) as $key => $field) {
if (null === $entity::resolveEntity()->searchFieldAnnotation($field['name'], new RelationIgnore)) {
$fieldlist[] = $key;
$fieldlist[] = $entity::field($field['name'], $alias);
$fieldlist[] = $entity::field($field['name'], $this->escapeIdentifier($alias));
}
}
@ -380,7 +384,7 @@ class Repository
public function insert(array $fieldlist, string $table, string $alias, ? string $schema, bool $replace = false) : self
{
$this->queryBuilder->insert($fieldlist, $this->escapeTable($table), $alias, $this->escapedDatabase(), $schema, $replace);
$this->queryBuilder->insert($fieldlist, $this->escapeTable($table), $this->escapeIdentifier($alias), $this->escapedDatabase(), $schema, $replace);
return $this;
}
@ -394,7 +398,7 @@ class Repository
public function update(string $table, string $alias, ? string $schema) : self
{
$this->queryBuilder->update($this->escapeTable($table), $alias, $this->escapedDatabase(), $schema);
$this->queryBuilder->update($this->escapeTable($table), $this->escapeIdentifier($alias), $this->escapedDatabase(), $schema);
return $this;
}
@ -418,13 +422,13 @@ class Repository
public function from(string $table, ? string $alias, ? string $schema) : self
{
$this->queryBuilder->from($this->escapeTable($table), $alias, $this->escapedDatabase(), $schema ? $this->escapeSchema($schema) : null);
$this->queryBuilder->from($this->escapeTable($table), $this->escapeIdentifier($alias), $this->escapedDatabase(), $schema ? $this->escapeSchema($schema) : null);
return $this;
}
public function join(string $type, $table, $field, $value, ? string $alias = null, ? callable $callback = null) : self
{
$join = $this->queryBuilder->withJoin($type, $this->escapeTable($table), $field, $value, false, $alias);
$join = $this->queryBuilder->withJoin($type, $this->escapeTable($table), $field, $value, false, $this->escapeIdentifier($alias));
if ( $callback ) {
$callback($join);
@ -435,7 +439,7 @@ class Repository
public function outerJoin(string $type, $table, $field, $value, ? string $alias = null, ? callable $callback = null) : self
{
$join = $this->queryBuilder->withJoin($type, $this->escapeTable($table), $field, $value, true, $alias);
$join = $this->queryBuilder->withJoin($type, $this->escapeTable($table), $field, $value, true, $this->escapeIdentifier($alias));
if ( $callback ) {
$callback($join);
@ -563,7 +567,9 @@ class Repository
foreach($entity::resolveEntity()->fieldList(Common\EntityResolver::KEY_COLUMN_NAME, true) as $key => $field) {
if ( null === $entity::resolveEntity()->searchFieldAnnotation($field['name'], new RelationIgnore) ) {
$this->select("$alias.$key as {$alias}\${$field['name']}");
$escAlias = $this->escapeIdentifier($alias);
$this->select("$escAlias.$key as $alias\${$field['name']}");
}
}
@ -626,7 +632,7 @@ class Repository
}
if ( null === $this->queryBuilder->getFragment(Query\Select::class) ) {
$this->select("{$this->alias}.*");
$this->select($this->escapeIdentifier($this->alias) . ".*");
}
# Apply FILTER annotation to this too !

View File

@ -7,6 +7,11 @@ use Ulmus\Annotation\Property\Field;
trait EscapeTrait
{
public function escapeIdentifier(string $identifier) : string
{
return $this->escapeField($identifier);
}
public function escapeField(string $identifier) : string
{
return $this->adapter->adapter()->escapeIdentifier($identifier, Adapter\AdapterInterface::IDENTIFIER_FIELD);

View File

@ -5,66 +5,11 @@ namespace Ulmus\Repository;
use Ulmus\{Repository, Query, Ulmus, Common};
class MssqlRepository extends Repository {
/*
protected function finalizeQuery() : void
{
if ( null !== $offset = $this->queryBuilder->getFragment(Query\Offset::class) ) {
if ( null === $limit = $this->queryBuilder->getFragment(Query\Limit::class) ) {
throw new \Exception("Your offset query fragment is missing a LIMIT value.");
}
# an order by is mandatory for mssql offset/limit
if ( null === $order = $this->queryBuilder->getFragment(Query\OrderBy::class) ) {
$this->orderBy("(SELECT 0)");
}
$mssqlOffset = new \Ulmus\Query\MsSQL\Offset();
$mssqlOffset->set($offset->offset, $limit->limit);
$this->queryBuilder->removeFragment($offset);
$this->queryBuilder->removeFragment($limit);
$this->queryBuilder->push($mssqlOffset);
}
elseif ( null !== $limit = $this->queryBuilder->getFragment(Query\Limit::class) ) {
if ( null !== $select = $this->queryBuilder->getFragment(Query\Select::class) ) {
$select->top = $limit->limit;
}
elseif ( null !== $delete = $this->queryBuilder->getFragment(Query\Delete::class) ) {
$delete->top = $limit->limit;
}
$this->queryBuilder->removeFragment($limit);
}
}
*/
protected function finalizeQuery() : void
{
if ( null !== $offset = $this->queryBuilder->getFragment(Query\Offset::class) ) {
# an order by is mandatory for mssql offset/limit
if ( null === $order = $this->queryBuilder->getFragment(Query\OrderBy::class) ) {
$this->orderBy("(SELECT 0)");
}
if ( empty ($offset->offset ) ) {
if ( null !== $select = $this->queryBuilder->getFragment(Query\Select::class) ) {
$select->top = $offset->limit;
}
elseif ( null !== $delete = $this->queryBuilder->getFragment(Query\Delete::class) ) {
$delete->top = $offset->limit;
}
$this->queryBuilder->removeFragment($offset);
}
elseif ( empty($offset->limit) ) {
throw new \Exception("Your offset query fragment is missing a LIMIT value.");
}
}
if ( null !== $limit = $this->queryBuilder->getFragment(Query\Limit::class) ) {
$this->queryBuilder->removeFragment($limit);
if ( null === $order = $this->queryBuilder->getFragment(Query\OrderBy::class) ) {
$this->orderBy("(SELECT 0)");
}
}

View File

@ -47,9 +47,11 @@ class RelationBuilder
return $this->resolveRelation($name) ?: $this->resolveVirtual($name);
}
else {
return $this->instanciateEmptyObject($name, $this->resolver->searchFieldAnnotation($name, new Relation() ));
elseif ( $relation = $this->resolver->searchFieldAnnotation($name, new Relation() ) ) {
return $this->instanciateEmptyObject($name, $relation);
}
return false;
}
protected function resolveVirtual(string $name) /* : bool|object|EntityCollection */

View File

@ -16,6 +16,16 @@ trait SearchRequestPaginationTrait {
public ? array $columns = null;
public function count(): int
{
return $this->count;
}
public function page(): int
{
return $this->page;
}
public function limit(): int
{
return $this->limit;
@ -23,7 +33,7 @@ trait SearchRequestPaginationTrait {
public function offset(): int
{
return (int) ( abs( ( $this->page - 1 ) * $this->limit() ) );
return (int) ( abs( ( $this->page() - 1 ) * $this->limit() ) );
}
public function pagination(int $page, int $itemCount) : void
@ -34,17 +44,25 @@ trait SearchRequestPaginationTrait {
public function pageCount() : int
{
return ceil($this->count / $this->limit());
return ceil($this->count() / $this->limit());
}
public function hasPagination() : int
{
return $this->pageCount() > 1;
}
public function skipCount(bool $value) : self
{
$this->skipCount = $value;
return $this;
}
public function resultShown() : int
{
$total = $this->page() * $this->limit();
return $total <= $this->count() ? $total : $this->count();
}
}