Skip to content

Commit

Permalink
Divide one() method in two. (#239)
Browse files Browse the repository at this point in the history
  • Loading branch information
terabytesoftw committed Feb 26, 2023
1 parent 60ec3d8 commit 352915a
Show file tree
Hide file tree
Showing 12 changed files with 110 additions and 95 deletions.
48 changes: 18 additions & 30 deletions src/ActiveQuery.php
Expand Up @@ -115,24 +115,6 @@ public function __construct(
parent::__construct($db);
}

/**
* Executes query and returns all results as an array.
*
* If null, the DB connection returned by {@see arClass} will be used.
*
* @throws Exception
* @throws InvalidConfigException
* @throws Throwable
*
* @return array the query results. If the query results in nothing, an empty array will be returned.
*
* @psalm-return ActiveRecord[]|array
*/
public function all(): array
{
return parent::all();
}

public function prepare(QueryBuilderInterface $builder): QueryInterface
{
/**
Expand Down Expand Up @@ -197,11 +179,11 @@ public function prepare(QueryBuilderInterface $builder): QueryInterface
}
} else {
if ($viaCallableUsed) {
$model = $viaQuery->one();
$model = $viaQuery->onePopulate();
} elseif ($this->primaryModel->isRelationPopulated($viaName)) {
$model = $this->primaryModel->$viaName;
} else {
$model = $viaQuery->one();
$model = $viaQuery->onePopulate();
$this->primaryModel->populateRelation($viaName, $model);
}
$viaModels = $model === null ? [] : [$model];
Expand Down Expand Up @@ -344,12 +326,20 @@ private function removeDuplicatedModels(array $models): array
return array_values($models);
}

/**
* @psalm-suppress NullableReturnStatement
*/
public function one(): array|null|object
public function allPopulate(): array
{
$rows = $this->all();

if ($rows !== []) {
$rows = $this->populate($rows);
}

return $rows;
}

public function onePopulate(): array|ActiveRecordInterface|null
{
$row = parent::one();
$row = $this->one();

if ($row !== null) {
$activeRecord = $this->populate([$row]);
Expand Down Expand Up @@ -1031,7 +1021,7 @@ public function getARClass(): string|null
*/
public function findOne(mixed $condition): array|ActiveRecordInterface|null
{
return $this->findByCondition($condition)->one();
return $this->findByCondition($condition)->onePopulate();
}

/**
Expand Down Expand Up @@ -1063,7 +1053,7 @@ public function findAll(mixed $condition): array
* @throws NotFoundException
* @throws NotInstantiableException
*/
protected function findByCondition(mixed $condition): QueryInterface
protected function findByCondition(mixed $condition): static
{
$arInstance = $this->getARInstance();

Expand Down Expand Up @@ -1114,10 +1104,8 @@ protected function findByCondition(mixed $condition): QueryInterface
*
* @param string $sql the SQL statement to be executed.
* @param array $params parameters to be bound to the SQL statement during execution.
*
* @return QueryInterface the newly created {@see ActiveQuery} instance
*/
public function findBySql(string $sql, array $params = []): QueryInterface
public function findBySql(string $sql, array $params = []): self
{
return $this->sql($sql)->params($params);
}
Expand Down
12 changes: 12 additions & 0 deletions src/ActiveQueryInterface.php
Expand Up @@ -277,4 +277,16 @@ public function link(array $value): self;
* If false, only the first row of the results will be retrieved using {@see Query::one()|one()}.
*/
public function multiple(bool $value): self;

/**
* Executes the query and returns ActiveRecord instances populated with the query result.
*
* @return array the query results. If the query results in nothing, an empty array will be returned.
*/
public function allPopulate(): array|ActiveRecordInterface|null;

/**
* Executes the query and returns ActiveRecord instances populated with the query result.
*/
public function onePopulate(): array|ActiveRecordInterface|null;
}
2 changes: 1 addition & 1 deletion src/ActiveRecord.php
Expand Up @@ -298,7 +298,7 @@ public function refresh(): bool

$query->where($pk);

return $this->refreshInternal($query->one());
return $this->refreshInternal($query->onePopulate());
}

/**
Expand Down
8 changes: 4 additions & 4 deletions src/ActiveRelationTrait.php
Expand Up @@ -199,7 +199,7 @@ public function findFor(string $name, ActiveRecordInterface $model): array|null|
}
}

return $this->multiple ? $this->all() : $this->one();
return $this->multiple ? $this->all() : $this->onePopulate();
}

/**
Expand Down Expand Up @@ -271,7 +271,7 @@ public function populateRelation(string $name, array &$primaryModels): array
}

if (!$this->multiple && count($primaryModels) === 1) {
$model = $this->one();
$model = $this->onePopulate();
$primaryModel = reset($primaryModels);

if ($primaryModel instanceof ActiveRecordInterface) {
Expand Down Expand Up @@ -714,8 +714,8 @@ public function getLink(): array
}

/**
* @return ActiveQueryInterface|array|null the query associated with the junction table. Please call {@see (via)()} to
* set this property instead of directly setting it.
* @return ActiveQueryInterface|array|null the query associated with the junction table.
* Please call {@see (via)()} to set this property instead of directly setting it.
*
* This property is only used in relational context.
*
Expand Down
50 changes: 26 additions & 24 deletions tests/ActiveQueryFindTest.php
Expand Up @@ -77,17 +77,19 @@ public function testFindBySql(): void

$customerQuery = new ActiveQuery(Customer::class, $this->db);

/** find one */
$customers = $customerQuery->findBySql('SELECT * FROM {{customer}} ORDER BY [[id]] DESC')->one();
/** find onePopulate */
$customers = $customerQuery->findBySql('SELECT * FROM {{customer}} ORDER BY [[id]] DESC')->onePopulate();
$this->assertInstanceOf(Customer::class, $customers);
$this->assertEquals('user3', $customers->getAttribute('name'));

/** find all */
$customers = $customerQuery->findBySql('SELECT * FROM {{customer}}')->all();
/** find allPopulate */
$customers = $customerQuery->findBySql('SELECT * FROM {{customer}}')->allPopulate();
$this->assertCount(3, $customers);

/** find with parameter binding */
$customers = $customerQuery->findBySql('SELECT * FROM {{customer}} WHERE [[id]]=:id', [':id' => 2])->one();
$customers = $customerQuery
->findBySql('SELECT * FROM {{customer}} WHERE [[id]]=:id', [':id' => 2])
->onePopulate();
$this->assertInstanceOf(Customer::class, $customers);
$this->assertEquals('user2', $customers->getAttribute('name'));
}
Expand Down Expand Up @@ -208,12 +210,12 @@ public function testFind(): void
$this->assertInstanceOf(ActiveQueryInterface::class, $customerQuery);

/** find one */
$customer = $customerQuery->one();
$customer = $customerQuery->onePopulate();
$this->assertInstanceOf(Customer::class, $customer);

/** find all */
$customerQuery = new ActiveQuery(Customer::class, $this->db);
$customers = $customerQuery->all();
$customers = $customerQuery->allPopulate();
$this->assertCount(3, $customers);
$this->assertInstanceOf(Customer::class, $customers[0]);
$this->assertInstanceOf(Customer::class, $customers[1]);
Expand Down Expand Up @@ -252,13 +254,13 @@ public function testFind(): void

/** find by attributes */
$customerQuery = new ActiveQuery(Customer::class, $this->db);
$customer = $customerQuery->where(['name' => 'user2'])->one();
$customer = $customerQuery->where(['name' => 'user2'])->onePopulate();
$this->assertInstanceOf(Customer::class, $customer);
$this->assertEquals(2, $customer->id);

/** scope */
$customerQuery = new CustomerQuery(Customer::class, $this->db);
$this->assertCount(2, $customerQuery->active()->all());
$this->assertCount(2, $customerQuery->active()->allPopulate());
$this->assertEquals(2, $customerQuery->active()->count());
}

Expand Down Expand Up @@ -391,48 +393,48 @@ public function testFindLimit(): void

/** one */
$customerQuery = new ActiveQuery(Customer::class, $this->db);
$customer = $customerQuery->orderBy('id')->one();
$customer = $customerQuery->orderBy('id')->onePopulate();
$this->assertEquals('user1', $customer->name);

/** all */
$customerQuery = new ActiveQuery(Customer::class, $this->db);
$customers = $customerQuery->all();
$customers = $customerQuery->allPopulate();
$this->assertCount(3, $customers);

/** limit */
$customerQuery = new ActiveQuery(Customer::class, $this->db);
$customers = $customerQuery->orderBy('id')->limit(1)->all();
$customers = $customerQuery->orderBy('id')->limit(1)->allPopulate();
$this->assertCount(1, $customers);
$this->assertEquals('user1', $customers[0]->name);

$customers = $customerQuery->orderBy('id')->limit(1)->offset(1)->all();
$customers = $customerQuery->orderBy('id')->limit(1)->offset(1)->allPopulate();
$this->assertCount(1, $customers);
$this->assertEquals('user2', $customers[0]->name);

$customers = $customerQuery->orderBy('id')->limit(1)->offset(2)->all();
$customers = $customerQuery->orderBy('id')->limit(1)->offset(2)->allPopulate();
$this->assertCount(1, $customers);
$this->assertEquals('user3', $customers[0]->name);

$customers = $customerQuery->orderBy('id')->limit(2)->offset(1)->all();
$customers = $customerQuery->orderBy('id')->limit(2)->offset(1)->allPopulate();
$this->assertCount(2, $customers);
$this->assertEquals('user2', $customers[0]->name);
$this->assertEquals('user3', $customers[1]->name);

$customers = $customerQuery->limit(2)->offset(3)->all();
$customers = $customerQuery->limit(2)->offset(3)->allPopulate();
$this->assertCount(0, $customers);

/** offset */
$customerQuery = new ActiveQuery(Customer::class, $this->db);
$customer = $customerQuery->orderBy('id')->offset(0)->one();
$customer = $customerQuery->orderBy('id')->offset(0)->onePopulate();
$this->assertEquals('user1', $customer->name);

$customer = $customerQuery->orderBy('id')->offset(1)->one();
$customer = $customerQuery->orderBy('id')->offset(1)->onePopulate();
$this->assertEquals('user2', $customer->name);

$customer = $customerQuery->orderBy('id')->offset(2)->one();
$customer = $customerQuery->orderBy('id')->offset(2)->onePopulate();
$this->assertEquals('user3', $customer->name);

$customer = $customerQuery->offset(3)->one();
$customer = $customerQuery->offset(3)->onePopulate();
$this->assertNull($customer);
}

Expand Down Expand Up @@ -507,7 +509,7 @@ public function testFindEager(): void
unset($customers[1]->orders);
$this->assertFalse($customers[1]->isRelationPopulated('orders'));

$customer = $customerQuery->where(['id' => 1])->with('orders')->one();
$customer = $customerQuery->where(['id' => 1])->with('orders')->onePopulate();
$this->assertTrue($customer->isRelationPopulated('orders'));
$this->assertCount(1, $customer->orders);
$this->assertCount(1, $customer->relatedRecords);
Expand Down Expand Up @@ -563,7 +565,7 @@ public function testFindNestedRelation(): void
$this->assertCount(3, $customers[2]->orders[0]->items);
$this->assertCount(1, $customers[2]->orders[1]->items);

$customers = $customerQuery->where(['id' => 1])->with('ordersWithItems')->one();
$customers = $customerQuery->where(['id' => 1])->with('ordersWithItems')->onePopulate();
$this->assertTrue($customers->isRelationPopulated('ordersWithItems'));
$this->assertCount(1, $customers->ordersWithItems);

Expand Down Expand Up @@ -661,15 +663,15 @@ public function testFindEagerIndexBy(): void
$this->checkFixture($this->db, 'order');

$orderQuery = new ActiveQuery(Order::class, $this->db);
$order = $orderQuery->with('itemsIndexed')->where(['id' => 1])->one();
$order = $orderQuery->with('itemsIndexed')->where(['id' => 1])->onePopulate();
$this->assertTrue($order->isRelationPopulated('itemsIndexed'));

$items = $order->itemsIndexed;
$this->assertCount(2, $items);
$this->assertTrue(isset($items[1]));
$this->assertTrue(isset($items[2]));

$order = $orderQuery->with('itemsIndexed')->where(['id' => 2])->one();
$order = $orderQuery->with('itemsIndexed')->where(['id' => 2])->onePopulate();
$this->assertTrue($order->isRelationPopulated('itemsIndexed'));

$items = $order->itemsIndexed;
Expand Down

0 comments on commit 352915a

Please sign in to comment.