Skip to content

Refactor ColumnSchemaBuilder::class, add shortcuts for generator columns, add new type column auto_increment, add more test. #76

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 33 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
e361773
Refactor `ColumnSchemaBuilder::class`, add shortcuts for generator co…
terabytesoftw Aug 20, 2024
5b3f6e4
Remove unsed tests.
terabytesoftw Aug 20, 2024
d2b4c0e
Refactor `getTypeCategory()` method in `ColumnSchemaBuilder.php` to r…
terabytesoftw Aug 20, 2024
f642c09
Refactor `ColumnSchemaBuilder.php` to use static property for `typeCa…
terabytesoftw Aug 20, 2024
9284635
Fix tests `ColumnSchemaBuilderTest.php`.
terabytesoftw Aug 20, 2024
ec143eb
Refactor `ColumnSchemaBuilder.php` to handle default type in switch s…
terabytesoftw Aug 20, 2024
b43182f
Refactor `createColumnSchemaBuilder()` method in `Schema.php` to remo…
terabytesoftw Aug 20, 2024
e8fc328
Refactor `ColumnSchemaBuilder.php` to handle default type in switch s…
terabytesoftw Aug 20, 2024
4e71a89
Refactor `ColumnSchemaBuilder.php` to handle nullable `CHECK` constra…
terabytesoftw Aug 20, 2024
b503024
Refactor `ColumnSchemaBuilder.php` to handle nullable `COMMENT` in bu…
terabytesoftw Aug 20, 2024
f22e36d
Refactor `ColumnSchemaBuilder.php` to handle nullable `after` propert…
terabytesoftw Aug 20, 2024
3ccca1a
Refactor `Schema.php` to use nullable type for defaultSchema property.
terabytesoftw Aug 20, 2024
d768358
Refactor `Schema.php` to use nullable type for defaultSchema property.
terabytesoftw Aug 20, 2024
0d938e7
Refactor `ColumnSchemaBuilder.php` to handle nullable `after` propert…
terabytesoftw Aug 20, 2024
d17fb76
Refactor `ColumnSchemaBuilder.php` to handle nullable `after` propert…
terabytesoftw Aug 20, 2024
e8e0ecd
Refactor ColumnSchemaBuilder.php to handle nullable after property in…
terabytesoftw Aug 21, 2024
72e757d
Rever change visibility comment property in `ColumnSchemaBuilder::cla…
terabytesoftw Aug 21, 2024
2359892
Refactor Oracle query builder to remove unnecessary primary key type …
terabytesoftw Aug 21, 2024
4f0d0bb
Refactor column type mappings in QueryBuilder classes for primary keys.
terabytesoftw Aug 21, 2024
e8d0dbb
Refactor SQLite primary key type mapping in QueryBuilderTest.php.
terabytesoftw Aug 21, 2024
8360d73
Refactor column type mappings for auto-incremental primary keys in My…
terabytesoftw Aug 21, 2024
7d40efe
Remove const for unsigned, only use in `mysql`, `sqlite`.
terabytesoftw Aug 21, 2024
7f332d0
Merge branch 'main' into refactor-colum-schema-builder
terabytesoftw Aug 22, 2024
0fa2a37
Merge branch 'main' into refactor-colum-schema-builder
terabytesoftw Aug 22, 2024
54d13f2
Refactor column type mappings for auto-incremental and primary keys i…
terabytesoftw Aug 23, 2024
245e935
Add more tests.
terabytesoftw Aug 23, 2024
c72f314
Raise code coverage `MSSQL` 100%.
terabytesoftw Aug 23, 2024
0330ae5
Refactor column type mappings for auto-incremental and primary keys.
terabytesoftw Aug 23, 2024
66b6fb2
Better structure tests.
terabytesoftw Aug 23, 2024
7892648
Refactor column type mappings for auto-incremental and primary keys f…
terabytesoftw Aug 24, 2024
6eaf095
Refactor column type mappings for auto-incremental and primary keys i…
terabytesoftw Aug 25, 2024
06ee89f
Refactor tearDown method in test classes to close database connection.
terabytesoftw Aug 25, 2024
259b2e8
Refactor column type mappings for auto-incremental and primary keys i…
terabytesoftw Aug 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
535 changes: 257 additions & 278 deletions src/db/ColumnSchemaBuilder.php

Large diffs are not rendered by default.

36 changes: 20 additions & 16 deletions src/db/Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -651,33 +651,37 @@ public function delete($table, $condition = '', $params = [])
/**
* Creates a SQL command for creating a new DB table.
*
* The columns in the new table should be specified as name-definition pairs (e.g. 'name' => 'string'),
* where name stands for a column name which will be properly quoted by the method, and definition
* stands for the column type which must contain an abstract DB type.
* The columns in the new table should be specified as name-definition pairs (e.g. 'name' => 'string'), where name
* stands for a column name which will be properly quoted by the method, and definition stands for the column type
* which must contain an abstract DB type.
*
* The method [[QueryBuilder::getColumnType()]] will be called
* to convert the abstract column types to physical ones. For example, `string` will be converted
* as `varchar(255)`, and `string not null` becomes `varchar(255) not null`.
* The method [[QueryBuilder::getColumnType()]] will be called to convert the abstract column types to physical
* ones. For example, `string` will be converted as `varchar(255)`, and `string not null` becomes
* `varchar(255) not null`.
*
* If a column is specified with definition only (e.g. 'PRIMARY KEY (name, type)'), it will be directly
* inserted into the generated SQL.
* If a column is specified with definition only (e.g. 'PRIMARY KEY (name, type)'), it will be directly inserted
* into the generated SQL.
*
* Example usage:
* ```php
* Yii::$app->db->createCommand()->createTable('post', [
* 'id' => 'pk',
* 'title' => 'string',
* 'text' => 'text',
* 'column_name double precision null default null',
* ]);
* Yii::$app->db->createCommand()->createTable(
* 'post',
* [
* 'id' => 'pk',
* 'title' => 'string',
* 'text' => 'text',
* 'column_name double precision null default null',
* ],
* );
* ```
*
* @param string $table the name of the table to be created. The name will be properly quoted by the method.
* @param array $columns the columns (name => definition) in the new table.
* @param string|null $options additional SQL fragment that will be appended to the generated SQL.
* @return $this the command object itself
*
* @return static the command object itself.
*/
public function createTable($table, $columns, $options = null)
public function createTable(string $table, array $columns, string|null $options = null): static
{
$sql = $this->db->getQueryBuilder()->createTable($table, $columns, $options);

Expand Down
71 changes: 46 additions & 25 deletions src/db/QueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -783,40 +783,47 @@ public function delete($table, $condition, &$params)
/**
* Builds a SQL statement for creating a new DB table.
*
* The columns in the new table should be specified as name-definition pairs (e.g. 'name' => 'string'),
* where name stands for a column name which will be properly quoted by the method, and definition
* stands for the column type which must contain an abstract DB type.
* The columns in the new table should be specified as name-definition pairs (e.g. 'name' => 'string'), where name
* stands for a column name which will be properly quoted by the method, and definition stands for the column type
* which must contain an abstract DB type.
*
* The [[getColumnType()]] method will be invoked to convert any abstract type into a physical one.
*
* If a column is specified with definition only (e.g. 'PRIMARY KEY (name, type)'), it will be directly
* inserted into the generated SQL.
* If a column is specified with definition only (e.g. 'PRIMARY KEY (name, type)'), it will be directly inserted
* into the generated SQL.
*
* For example,
*
* ```php
* $sql = $queryBuilder->createTable('user', [
* 'id' => 'pk',
* 'name' => 'string',
* 'age' => 'integer',
* 'column_name double precision null default null', # definition only example
* ]);
* $sql = $queryBuilder->createTable(
* 'user',
* [
* 'id' => 'pk',
* 'name' => 'string',
* 'age' => 'integer',
* 'column_name double precision null default null', # definition only example
* ],
* );
* ```
*
* @param string $table the name of the table to be created. The name will be properly quoted by the method.
* @param array $columns the columns (name => definition) in the new table.
* @param string|null $options additional SQL fragment that will be appended to the generated SQL.
*
* @return string the SQL statement for creating a new DB table.
*/
public function createTable($table, $columns, $options = null)
public function createTable(string $table, array $columns, string|null $options = null): string
{
$cols = [];

foreach ($columns as $name => $type) {
if (is_string($name)) {
$cols[] = "\t" . $this->db->quoteColumnName($name) . ' ' . $this->getColumnType($type);
} else {
$cols[] = "\t" . $type;
}
}

$sql = 'CREATE TABLE ' . $this->db->quoteTableName($table) . " (\n" . implode(",\n", $cols) . "\n)";

return $options === null ? $sql : $sql . ' ' . $options;
Expand Down Expand Up @@ -1264,9 +1271,12 @@ public function dropView($viewName)
* The following abstract column types are supported (using MySQL as an example to explain the corresponding
* physical types):
*
* - `pk`: an auto-incremental primary key type, will be converted into "int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY"
* - `bigpk`: an auto-incremental primary key type, will be converted into "bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY"
* - `upk`: an unsigned auto-incremental primary key type, will be converted into "int(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY"
* - `pk`: an auto-incremental primary key type, will be converted into
* "int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY"
* - `bigpk`: an auto-incremental primary key type, will be converted into
* "bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY"
* - `upk`: an unsigned auto-incremental primary key type, will be converted into
* "int(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY"
* - `char`: char type, will be converted into "char(1)"
* - `string`: string type, will be converted into "varchar(255)"
* - `text`: a long string type, will be converted into "text"
Expand All @@ -1283,31 +1293,42 @@ public function dropView($viewName)
* - `money`: money type, will be converted into "decimal(19,4)"
* - `binary`: binary data type, will be converted into "blob"
*
* If the abstract type contains two or more parts separated by spaces (e.g. "string NOT NULL"), then only
* the first part will be converted, and the rest of the parts will be appended to the converted result.
* If the abstract type contains two or more parts separated by spaces (e.g. "string NOT NULL"), then only the first
* part will be converted, and the rest of the parts will be appended to the converted result.
*
* For example, 'string NOT NULL' is converted to 'varchar(255) NOT NULL'.
*
* For some of the abstract types you can also specify a length or precision constraint
* by appending it in round brackets directly to the type.
* For some of the abstract types you can also specify a length or precision constraint by appending it in round
* brackets directly to the type.
*
* For example `string(32)` will be converted into "varchar(32)" on a MySQL database.
*
* If the underlying DBMS does not support these kind of constraints for a type it will
* be ignored.
*
* If a type cannot be found in [[typeMap]], it will be returned without any change.
* @param string|ColumnSchemaBuilder $type abstract column type
*
* @param string|ColumnSchemaBuilder $type abstract column type.
*
* @return string physical column type.
*/
public function getColumnType($type)
public function getColumnType(string|ColumnSchemaBuilder $type): string
{
if ($type instanceof ColumnSchemaBuilder) {
$type = $type->__toString();
if (is_string($type) === false) {
$type = (string) $type;
}

if (isset($this->typeMap[$type])) {
return $this->typeMap[$type];
} elseif (preg_match('/^(\w+)\((.+?)\)(.*)$/', $type, $matches)) {
}

if (preg_match('/^(\w+)\((.+?)\)(.*)$/', $type, $matches)) {
if (isset($this->typeMap[$matches[1]])) {
return preg_replace('/\(.+\)/', '(' . $matches[2] . ')', $this->typeMap[$matches[1]]) . $matches[3];
return preg_replace(
'/\(.+\)/',
'(' . $matches[2] . ')',
$this->typeMap[$matches[1]]
) . $matches[3];
}
} elseif (preg_match('/^(\w+)\s+/', $type, $matches)) {
if (isset($this->typeMap[$matches[1]])) {
Expand Down
Loading