- Merge with Mssql repository bugfix
This commit is contained in:
parent
724ab250ab
commit
e1990e7cc0
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -247,6 +247,10 @@ class QueryBuilder implements Query\QueryBuilderInterface
|
|||
|
||||
$limit->set($value);
|
||||
|
||||
if ($value === 0) {
|
||||
$this->removeFragment(Query\Limit::class);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 !
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue