Skip to content

Commit bfd18e2

Browse files
authored
Add ConnectionInterface::select() method (#984)
1 parent cc8dea8 commit bfd18e2

6 files changed

Lines changed: 97 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
- Chg #980: Add constructor with DB connection to `AbstractCommand` (@vjik)
9696
- Enh #979: Allow `ExpressionInterface` for column definitions when create table (@Tigrov)
9797
- Enh #982: Reduce binding parameters (@Tigrov)
98+
- New #984: Add `createQuery()` and `select()` methods to `ConnectionInterface` (@Tigrov)
9899
- Chg #985: Rename `insertWithReturningPks()` to `insertReturningPks()` in `CommandInterface` and `DMLQueryBuilderInterface` (@Tigrov)
99100

100101
## 1.3.0 March 21, 2024

UPGRADE.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ Each table column has its own class in the `Yiisoft\Db\Schema\Column` namespace
130130
- `QueryPartsInterface::setHaving()` - overwrites the `HAVING` part of the query;
131131
- `ConnectionInterface::getColumnFactory()` - returns the column factory object for concrete DBMS;
132132
- `ConnectionInterface::getServerInfo()` - returns `ServerInfoInterface` instance which provides server information;
133+
- `ConnectionInterface::createQuery()` - creates a `Query` object;
134+
- `ConnectionInterface::select()` - creates a `Query` object with the specified columns to be selected;
133135
- `QueryBuilderInterface::buildColumnDefinition()` - builds column definition for `CREATE TABLE` statement;
134136
- `QueryBuilderInterface::buildValue()` - converts a value to its SQL representation with binding parameters if necessary;
135137
- `QueryBuilderInterface::prepareParam()` - converts a `ParamInterface` object to its SQL representation;

src/Connection/AbstractConnection.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66

77
use Closure;
88
use Throwable;
9+
use Yiisoft\Db\Expression\ExpressionInterface;
910
use Yiisoft\Db\Query\BatchQueryResult;
1011
use Yiisoft\Db\Query\BatchQueryResultInterface;
12+
use Yiisoft\Db\Query\Query;
1113
use Yiisoft\Db\Query\QueryInterface;
1214
use Yiisoft\Db\Schema\TableSchemaInterface;
1315
use Yiisoft\Db\Transaction\TransactionInterface;
@@ -43,6 +45,11 @@ public function createBatchQueryResult(QueryInterface $query): BatchQueryResultI
4345
return new BatchQueryResult($query);
4446
}
4547

48+
public function createQuery(): QueryInterface
49+
{
50+
return new Query($this);
51+
}
52+
4653
public function getTablePrefix(): string
4754
{
4855
return $this->tablePrefix;
@@ -68,6 +75,13 @@ public function setEnableSavepoint(bool $value): void
6875
$this->enableSavepoint = $value;
6976
}
7077

78+
public function select(
79+
array|bool|float|int|string|ExpressionInterface $columns = [],
80+
?string $option = null,
81+
): QueryInterface {
82+
return $this->createQuery()->select($columns, $option);
83+
}
84+
7185
public function setTablePrefix(string $value): void
7286
{
7387
$this->tablePrefix = $value;

src/Connection/ConnectionInterface.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111
use Yiisoft\Db\Exception\InvalidCallException;
1212
use Yiisoft\Db\Exception\InvalidConfigException;
1313
use Yiisoft\Db\Exception\NotSupportedException;
14+
use Yiisoft\Db\Expression\ExpressionInterface;
1415
use Yiisoft\Db\Query\BatchQueryResultInterface;
1516
use Yiisoft\Db\Query\QueryInterface;
17+
use Yiisoft\Db\Query\QueryPartsInterface;
1618
use Yiisoft\Db\QueryBuilder\QueryBuilderInterface;
1719
use Yiisoft\Db\Schema\Column\ColumnFactoryInterface;
1820
use Yiisoft\Db\Schema\QuoterInterface;
@@ -28,6 +30,7 @@
2830
* different database systems without having to worry about the specific details of each one.
2931
*
3032
* @psalm-type ParamsType = array<non-empty-string, mixed>|list<mixed>
33+
* @psalm-import-type SelectValue from QueryPartsInterface
3134
*/
3235
interface ConnectionInterface
3336
{
@@ -71,6 +74,13 @@ public function createBatchQueryResult(QueryInterface $query): BatchQueryResultI
7174
*/
7275
public function createCommand(?string $sql = null, array $params = []): CommandInterface;
7376

77+
/**
78+
* Creates a query instance.
79+
*
80+
* @return QueryInterface The query instance.
81+
*/
82+
public function createQuery(): QueryInterface;
83+
7484
/**
7585
* Create a transaction instance.
7686
*
@@ -203,6 +213,30 @@ public function quoteValue(mixed $value): mixed;
203213
*/
204214
public function setEnableSavepoint(bool $value): void;
205215

216+
/**
217+
* Creates a new {@see Query} instance with the specified columns to be selected.
218+
*
219+
* @param array|ExpressionInterface|scalar $columns The columns to be selected.
220+
* Columns can be specified in either a string (for example `id, name`) or an array (such as `['id', 'name']`).
221+
* Columns can be prefixed with table names (such as `user.id`) and/or contain column aliases
222+
* (for example `user.id AS user_id`).
223+
* The method will automatically quote the column names unless a column has some parenthesis (which means the
224+
* column has a DB expression).
225+
* A DB expression may also be passed in form of an {@see ExpressionInterface} object.
226+
* Note that if you are selecting an expression like `CONCAT(first_name, ' ', last_name)`, you should use an array
227+
* to specify the columns. Otherwise, the expression may be incorrectly split into several parts.
228+
* When the columns are specified as an array, you may also use array keys as the column aliases (if a column
229+
* doesn't need alias, don't use a string key).
230+
* @param string|null $option More option that should be appended to the 'SELECT' keyword. For example, in MySQL,
231+
* the option 'SQL_CALC_FOUND_ROWS' can be used.
232+
*
233+
* @psalm-param SelectValue|scalar|ExpressionInterface $columns
234+
*/
235+
public function select(
236+
array|bool|float|int|string|ExpressionInterface $columns = [],
237+
?string $option = null,
238+
): QueryInterface;
239+
206240
/**
207241
* The common prefix or suffix for table names.
208242
* If a table name is `{{%TableName}}`, then the percentage

src/Debug/ConnectionInterfaceProxy.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Yiisoft\Db\Command\CommandInterface;
99
use Yiisoft\Db\Connection\ConnectionInterface;
1010
use Yiisoft\Db\Connection\ServerInfoInterface;
11+
use Yiisoft\Db\Expression\ExpressionInterface;
1112
use Yiisoft\Db\Query\BatchQueryResultInterface;
1213
use Yiisoft\Db\Query\QueryInterface;
1314
use Yiisoft\Db\QueryBuilder\QueryBuilderInterface;
@@ -51,6 +52,11 @@ public function createCommand(?string $sql = null, array $params = []): CommandI
5152
);
5253
}
5354

55+
public function createQuery(): QueryInterface
56+
{
57+
return $this->connection->createQuery();
58+
}
59+
5460
public function createTransaction(): TransactionInterface
5561
{
5662
return new TransactionInterfaceDecorator(
@@ -141,6 +147,13 @@ public function setEnableSavepoint(bool $value): void
141147
$this->connection->setEnableSavepoint($value);
142148
}
143149

150+
public function select(
151+
array|bool|float|int|string|ExpressionInterface $columns = [],
152+
?string $option = null,
153+
): QueryInterface {
154+
return $this->connection->select($columns, $option);
155+
}
156+
144157
public function setTablePrefix(string $value): void
145158
{
146159
$this->connection->setTablePrefix($value);

tests/Db/Connection/ConnectionTest.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,13 @@
44

55
namespace Yiisoft\Db\Tests\Db\Connection;
66

7+
use PHPUnit\Framework\Attributes\TestWith;
78
use Yiisoft\Db\Exception\NotSupportedException;
9+
use Yiisoft\Db\Expression\Expression;
10+
use Yiisoft\Db\Expression\ExpressionInterface;
11+
use Yiisoft\Db\Query\Query;
812
use Yiisoft\Db\Tests\AbstractConnectionTest;
13+
use Yiisoft\Db\Tests\Support\Assert;
914
use Yiisoft\Db\Tests\Support\DbHelper;
1015
use Yiisoft\Db\Tests\Support\Stub\ColumnFactory;
1116
use Yiisoft\Db\Tests\Support\Stub\Connection;
@@ -45,4 +50,32 @@ public function testConstructColumnFactory(): void
4550

4651
$this->assertSame($columnFactory, $db->getColumnFactory());
4752
}
53+
54+
public function testCreateQuery(): void
55+
{
56+
$db = $this->getConnection();
57+
58+
$this->assertInstanceOf(Query::class, $db->createQuery());
59+
}
60+
61+
#[TestWith(['columns' => 'column1'])]
62+
#[TestWith(['columns' => 'now()'])]
63+
#[TestWith(['columns' => true])]
64+
#[TestWith(['columns' => 1])]
65+
#[TestWith(['columns' => 1.2])]
66+
#[TestWith(['columns' => new Expression('now()')])]
67+
#[TestWith(['columns' => ['column1', 'now()', new Expression('now()')]])]
68+
public function testSelect(array|bool|float|int|string|ExpressionInterface $columns, ?string $option = null): void
69+
{
70+
$db = $this->getConnection();
71+
72+
Assert::objectsEquals($db->select($columns, $option), $db->createQuery()->select($columns, $option));
73+
}
74+
75+
public function testSelectWithoutParams(): void
76+
{
77+
$db = $this->getConnection();
78+
79+
Assert::objectsEquals($db->select(), $db->createQuery());
80+
}
4881
}

0 commit comments

Comments
 (0)