Browse Source

QueryBuilder: allow adding raw SQL WHERE expressions

phpdevcommunity 4 tuần trước cách đây
mục cha
commit
cd563cf35d

+ 6 - 1
src/Command/Migration/MigrationDiffCommand.php

@@ -84,10 +84,12 @@ class MigrationDiffCommand implements CommandInterface
             $io->listKeyValues(array_merge($normalEntities, $systemEntities));
         }
 
+        $executed = false;
         $fileApp = $this->paperMigration->generateMigrationFromEntities($normalEntities);
         if ($fileApp === null) {
             $io->info('No application migration file was generated — schema already in sync.');
         } else {
+            $executed = true;
             $io->success('✔ Application migration file generated: ' . $fileApp);
         }
 
@@ -95,6 +97,7 @@ class MigrationDiffCommand implements CommandInterface
         if ($fileSystem === null) {
             $io->info('No system migration changes detected.');
         } else {
+            $executed = true;
             $io->success('✔ System migration file generated: ' . $fileSystem);
         }
 
@@ -114,6 +117,8 @@ class MigrationDiffCommand implements CommandInterface
                 $io->listKeyValues($lines);
             }
         }
-        $io->success('Migration diff process completed successfully.');
+        if ($executed) {
+            $io->success('Migration diff process completed successfully.');
+        }
     }
 }

+ 48 - 5
src/Query/QueryBuilder.php

@@ -27,17 +27,15 @@ final class QueryBuilder
     private PlatformInterface $platform;
     private SchemaInterface $schema;
     private EntityMemcachedCache $cache;
-
     private AliasGenerator $aliasGenerator;
     private array $select = [];
     private array $where = [];
+    private array $rawWhere = [];
     private array $orderBy = [];
-
     private array $joins = [];
     private array $joinsAlreadyAdded = [];
     private ?int $firstResult = null;
     private ?int $maxResults = null;
-
     private array $params = [];
 
     public function __construct(EntityManagerInterface $em)
@@ -55,6 +53,11 @@ final class QueryBuilder
         }
     }
 
+    public function getArrayResult(): array
+    {
+        return $this->getResult(self::HYDRATE_ARRAY);
+    }
+
     public function getResult(string $hydrationMode = self::HYDRATE_OBJECT): array
     {
         return $this->hydrate($this->buildSqlQuery()->getResult(), $hydrationMode);
@@ -110,6 +113,16 @@ final class QueryBuilder
         return $this;
     }
 
+    public function rawWhere(string $sql): self
+    {
+        if (empty($this->select)) {
+            throw new LogicException('Select must be called before rawWhere()');
+        }
+
+        $this->rawWhere[] = $sql;
+        return $this;
+    }
+
     public function orderBy(string $sort, string $order = 'ASC'): self
     {
         $this->orderBy[] = [
@@ -134,6 +147,7 @@ final class QueryBuilder
     public function resetWhere(): self
     {
         $this->where = [];
+        $this->rawWhere = [];
         return $this;
     }
 
@@ -159,6 +173,18 @@ final class QueryBuilder
         return $this->join('INNER', $fromAliasOrEntityName, $targetEntityName, $property);
     }
 
+    public function joinSelect(string ...$columns): self
+    {
+        if (empty($this->joins)) {
+            throw new LogicException(
+                'You must call the innerJoin() or leftJoin() method first to define columns to select'
+            );
+        }
+        $index = \array_key_last($this->joins);
+        $this->joins[$index]['columnsToSelect'] = $columns;
+        return $this;
+    }
+
     public function setFirstResult(?int $firstResult): self
     {
         if ($this->select === []) {
@@ -209,6 +235,7 @@ final class QueryBuilder
                     'alias' => $alias,
                     'targetEntity' => $targetEntityName,
                     'targetTable' => $this->getTableName($targetEntityName),
+                    'columnsToSelect' => null,
                     'fromEntityName' => $fromEntityName,
                     'fromTable' => $this->getTableName($fromEntityName),
                     'fromAlias' => $fromAlias,
@@ -327,6 +354,7 @@ final class QueryBuilder
             $fromAlias = $join['fromAlias'];
             $targetTable = $join['targetTable'];
             $targetEntity = $join['targetEntity'];
+            $columnsToSelect = $join['columnsToSelect'];
             $alias = $join['alias'];
             /**
              * @var JoinColumn|OneToMany $column
@@ -336,8 +364,19 @@ final class QueryBuilder
             $type = $join['type'];
             $name = null;
 
-            $columns = $this->convertPropertiesToColumns($targetEntity, ColumnMapper::getColumns($targetEntity));
-            $joinQl->addSelect($alias, $columns);
+            $columns = [];
+
+
+            if ($join['columnsToSelect'] === null) {
+                $columns = $this->convertPropertiesToColumns($targetEntity, ColumnMapper::getColumns($targetEntity));
+            }elseif (!empty($columnsToSelect)) {
+                $columns = $this->convertPropertiesToColumns($targetEntity, $columnsToSelect);
+            }
+
+            if (!empty($columns)) {
+                $joinQl->addSelect($alias, $columns);
+            }
+
             $criteria = [];
             if ($column instanceof JoinColumn) {
                 $criteria = [$column->getName() => $column->getReferencedColumnName()];
@@ -371,6 +410,10 @@ final class QueryBuilder
             $joinQl->where($this->resolveExpression($where));
         }
 
+        foreach ($this->rawWhere as $rawWhere) {
+            $joinQl->where($rawWhere);
+        }
+
         foreach ($this->orderBy as $orderBy) {
             $joinQl->orderBy($this->resolveExpression($orderBy['sort']), $orderBy['order']);
         }

+ 2 - 2
tests/Common/OrmTestMemory.php

@@ -25,12 +25,12 @@ class OrmTestMemory extends TestCase
     {
         foreach (DataBaseHelperTest::drivers() as  $params) {
             $em = EntityManager::createFromConfig(PaperConfiguration::fromArray($params));
-            DataBaseHelperTest::init($em, 1000, false);
+            DataBaseHelperTest::init($em, 5000, false);
             $memory = memory_get_usage();
             $users = $em->getRepository(UserTest::class)
                 ->findBy()
                 ->toObject();
-            $this->assertStrictEquals(1000, count($users));
+            $this->assertStrictEquals(5000, count($users));
             foreach ($users as $user) {
                 $this->assertInstanceOf(UserTest::class, $user);
                 $this->assertNotEmpty($user);