diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 2dff7dfc9..a750bff39 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -22,16 +22,16 @@ If you are only going to make a pull request in a single repository, simply crea if you are going to make a pull request in multiple repositories, create a **new branch with the same name in all repositories**, this allows our github actions workflow to sync all branches, and tests to run correctly. -5. [Check your changes](/docs/en/testing.md). +5. [Check your changes](/docs/guide/en/testing.md). ## Reporting issues Please follow the guidelines below when creating an issue so that your issue can be more promptly resolved: -* Provide information including: the version of PHP, dbms and the type of operating system. -* Provide the **complete** error call stack if available. A screenshot to explain the issue is very welcome. -* Describe the steps for reproducing the issue. It would be even better if you could provide code to reproduce the issue. -* If possible you may even create a failing unit test and [send it as a pull request](#git-workflow). +- Provide information including: the version of PHP, dbms and the type of operating system. +- Provide the **complete** error call stack if available. A screenshot to explain the issue is very welcome. +- Describe the steps for reproducing the issue. It would be even better if you could provide code to reproduce the issue. +- If possible you may even create a failing unit test and [send it as a pull request](#git-workflow). If the issue is related to one of the dbms packages, please report it to the corresponding repository. @@ -39,8 +39,8 @@ If you are unsure, [report it to the main repository](https://github.com/yiisoft **Do not report an issue if** -* you are asking how to use some **Yii DB** feature. You should use [the forum](https://forum.yiiframework.com/c/yii-3-0/63) or [telegram](https://t.me/yii3en) for this purpose. -* your issue is about security. Please [contact us directly](https://www.yiiframework.com/security/) to report security issues. +- you are asking how to use some **Yii DB** feature. You should use [the forum](https://forum.yiiframework.com/c/yii-3-0/63) or [telegram](https://t.me/yii3en) for this purpose. +- your issue is about security. Please [contact us directly](https://www.yiiframework.com/security/) to report security issues. **Avoid duplicated issues** diff --git a/LICENSE.md b/LICENSE.md index bc5674fe4..6a920d605 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,17 +1,17 @@ -Copyright © 2008 by Yii Software (https://www.yiiframework.com/) +Copyright © 2008 by Yii Software () All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Yii Software nor the names of its +* Neither the name of Yii Software nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. diff --git a/README.md b/README.md index a9f1b3f1f..bb365cd40 100644 --- a/README.md +++ b/README.md @@ -42,18 +42,26 @@ similar to the way you would use ORM (Object-Relational Mapping) frameworks like [![static analysis](https://github.com/yiisoft/db/actions/workflows/static.yml/badge.svg?branch=dev)](https://github.com/yiisoft/db/actions/workflows/static.yml) [![type-coverage](https://shepherd.dev/github/yiisoft/db/coverage.svg)](https://shepherd.dev/github/yiisoft/db) -## Usage +## Requirements -[Check the documentation](/docs/en/README.md) to learn about usage. +- PHP 8.0 or higher. -## Support +## Documentation -If you need help or have a question, the [Yii Forum](https://forum.yiiframework.com/c/yii-3-0/db/68) is a good place for that. -You may also check out other [Yii Community Resources](https://www.yiiframework.com/community). +- [English](docs/guide/en/README.md) +- [Português - Brasil](docs/guide/pt-BR/readme.md) + +Testing: + +- [English](docs/guide/en/testing.md) +- [Português - Brasil](docs/guide/pt-BR/testing.md) -## Testing +- [Internals](docs/internals.md) -[Check the testing instructions](/docs/en/testing.md) to learn about testing. +## Support + +If you need help or have a question, the [Yii Forum](https://forum.yiiframework.com/c/yii-3-0/63) is a good place for that. +You may also check out other [Yii Community Resources](https://www.yiiframework.com/community). ## Support the project @@ -69,7 +77,7 @@ You may also check out other [Yii Community Resources](https://www.yiiframework. ## License -The Yii DataBase Library is free software. It's released under the terms of the BSD License. +The Yii Access is free software. It is released under the terms of the BSD License. Please see [`LICENSE`](./LICENSE.md) for more information. Maintained by [Yii Software](https://www.yiiframework.com/). diff --git a/docs/en/query-builder/building-queries.md b/docs/en/query-builder/building-queries.md deleted file mode 100644 index c873e8bbb..000000000 --- a/docs/en/query-builder/building-queries.md +++ /dev/null @@ -1,39 +0,0 @@ -# Building queries - -To build a `Yiisoft\Db\Query\Query` object, you call various query building methods to specify different parts -of a SQL query. - -The names of these methods resemble the **SQL keywords** used in the corresponding parts of the **SQL statement**. -For example, to specify the `FROM` part of a **SQL query**, you would call the `Yiisoft\Db\Query\Query::from()` method. -All the query building methods return the query object itself, which allows you to chain many calls together. - -- [Select](/docs/en/query/select.md) -- [From](/docs/en/query/from.md) -- [Where](/docs/en/query/where.md) - - [String format](/docs/en/query/where.md#string-format) - - [Hash format](/docs/en/query/where.md#hash-format) - - [Operator format](/docs/en/query/where.md#operator-format) - - [and](/docs/en/query/where.md#and) - - [or](/docs/en/query/where.md#or) - - [not](/docs/en/query/where.md#not) - - [between](/docs/en/query/where.md#between) - - [not between](/docs/en/query/where.md#not-between) - - [in](/docs/en/query/where.md#in) - - [not in](/docs/en/query/where.md#not-in) - - [like](/docs/en/query/where.md#like) - - [or like](/docs/en/query/where.md#or-like) - - [not like](/docs/en/query/where.md#not-like) - - [or not like](/docs/en/query/where.md#or-not-like) - - [exists](/docs/en/query/where.md#exists) - - [not exists](/docs/en/query/where.md#not-exists) - - [comparison](/docs/en/query/where.md#comparison) - - [Object format](/docs/en/query/where.md#object-format) - - [Appending conditions](/docs/en/query/where.md#appending-conditions) - - [Filter conditions](/docs/en/query/where.md#filter-conditions) -- [OrderBy](/docs/en/query/order-by.md) -- [GroupBy](/docs/en/query/group-by.md) -- [Having](/docs/en/query/having.md) -- [Limit and Offset](/docs/en/query/limit-and-offset.md) -- [Join](/docs/en/query/join.md) -- [Union](/docs/en/query/union.md) -- [WithQuery](/docs/en/query/with-query.md) diff --git a/docs/en/README.md b/docs/guide/en/README.md similarity index 97% rename from docs/en/README.md rename to docs/guide/en/README.md index bc93b7e05..dfe593cc2 100644 --- a/docs/en/README.md +++ b/docs/guide/en/README.md @@ -20,8 +20,12 @@ Yii DB supports the following databases out of the box: - [MySQL](https://www.mysql.com/) of versions **5.7 - 8.0**. - [MariaDB](https://mariadb.org/) of versions **10.4 - 10.9**. - [Oracle](https://www.oracle.com/database/) of versions **12c - 21c**. -- [PostgreSQL](https://www.postgresql.org/) of versions **9.6 - 15**. -- [SQLite](https://www.sqlite.org/index.html) of version **3.3 and above**. +- [PostgreSQL](https://www.postgresql.org/) of versions **9.6 - 15**. +- [SQLite](https://www.sqlite.org/) of version **3.3 and above**. + +## Requirements + +- PHP 8.0 or higher. ## Installation @@ -29,31 +33,31 @@ To install Yii DB, you must select the driver you want to use and install it wit For [MSSQL](https://github.com/yiisoft/db-mssql): -```bash +```shell composer require yiisoft/db-mssql ``` For [MySQL/MariaDB](https://github.com/yiisoft/db-mysql): -```bash +```shell composer require yiisoft/db-mysql ``` For [Oracle](https://github.com/yiisoft/db-oracle): -```bash +```shell composer require yiisoft/db-oracle ``` For [PostgreSQL](https://github.com/yiisoft/db-pgsql): -```bash +```shell composer require yiisoft/db-pgsql ``` For [SQLite](https://github.com/yiisoft/db-sqlite): -```bash +```shell composer require yiisoft/db-sqlite ``` @@ -108,10 +112,6 @@ Yii DB will automatically convert such constructs into the corresponding quoted For example, the following code will generate an SQL statement that's valid for all supported databases: ```php -createCommand()->dropTable('{{%customer}}')->execute(); ### Truncate a table -To clear just the data of a table without removing schema declaration, you can use the +To clear just the data of a table without removing schema declaration, you can use the `Yiisoft\Db\Command\CommandInterface::truncateTable()` method: ```php -createCommand()->truncateTable('{{%customer}}')->execute(); To add a new column to an existing table, you can use the `Yiisoft\Db\Command\CommandInterface::addColumn()` method: ```php -createCommand()->addColumn( To change an existing column, you can use the `Yiisoft\Db\Command\CommandInterface::alterColumn()` method: ```php -createCommand()->alterColumn( To rename an existing column, you can use the `Yiisoft\Db\Command\CommandInterface::renameColumn()` method: ```php -createCommand()->renameColumn('{{%customer}}', 'profile_id', 'profile_id_ne To drop an existing column, you can use the `Yiisoft\Db\Command\CommandInterface::dropColumn()` method: ```php -createCommand()->dropDefaultValue('{{%customer}}', 'df-customer-name')->exe To add a primary key to an existing table, you can use the `Yiisoft\Db\Command\CommandInterface::addPrimaryKey()` method: ```php -createCommand()->addForeignKey( To drop an existing primary key, you can use the `Yiisoft\Db\Command\CommandInterface::dropPrimaryKey()` method: ```php -createCommand()->dropPrimaryKey('{{%customer}}', 'pk-customer-id')->execute To drop an existing foreign key, you can use the `Yiisoft\Db\Command\CommandInterface::dropForeignKey()` method: ```php -createCommand()->dropForeignKey('{{%customer}}', 'fk-customer-profile_id')- To add an index to an existing table, you can use the `Yiisoft\Db\Command\CommandInterface::createIndex()` method: ```php -createCommand()->createIndex('{{%customer}}', 'idx-customer-name', 'name')- To drop an existing index, you can use the `Yiisoft\Db\Command\CommandInterface::dropIndex()` method: ```php -createCommand()->createIndex('test', 'idx_test_name', 'id', 'UNIQUE')->exec In MSSQL, you can create a clustered index by specifying the `CLUSTERED` option in the `$indexType` parameter: ```php -createCommand()->createIndex('test', 'idx_test_name', 'id', 'CLUSTERED')->e In MSSQL, you can create a non-clustered index by specifying the `NONCLUSTERED` option in the `$indexType` parameter: ```php -createCommand()->createIndex('test', 'idx_test_name', 'id', 'NONCLUSTERED') ``` > Info: A non-clustered index is also used to speed up search operations. Unlike a clustered index, a non-clustered index doesn’t -> physically define the order in which records are inserted into a table. In fact, a non-clustered index is stored in a +> physically define the order in which records are inserted into a table. In fact, a non-clustered index is stored in a > separate location from the data table. -> +> > A non-clustered index is like a book index, which is located separately from the main contents of the book. Since non-clustered > indexes are located in a separate location, there can be multiple non-clustered indexes per table. @@ -367,10 +295,6 @@ In MySQL and MariaDB, you can create a fulltext index by specifying the `FULLTEX parameter. ```php -createCommand()->createIndex('test', 'idx_test_name', 'name', 'FULLTEXT')-> ``` > Info: Full-text indexes are created on text-based columns (`CHAR`, `VARCHAR`, or `TEXT` columns) to speed up queries and DML operations -> on data contained within those columns. -> +> on data contained within those columns. +> > A full-text index is defined as part of a `CREATE TABLE` statement or added to an existing table using `ALTER TABLE` or `CREATE INDEX`. ### Add bitmap index @@ -387,10 +311,6 @@ $db->createCommand()->createIndex('test', 'idx_test_name', 'name', 'FULLTEXT')-> In `Oracle`, you can create a bitmap index by specifying the `BITMAP` option in the `$indexType` parameter: ```php -createCommand()->createIndex('test', 'idx_test_name', 'id', 'BITMAP')->exec > Info: A bitmap index is a special kind of database index which uses bitmaps or bit array. In a bitmap index, Oracle stores a > bitmap for each index key. -> +> > Each index key stores pointers to multiple rows. For example, if you create a bitmap index on the gender column of the members table. ## Constraints @@ -411,10 +331,6 @@ To add a unique constraint to an existing column, you can use the `Yiisoft\Db\Co method: ```php -createCommand()->addCheck('{{%customer}}', 'ck-customer-status', 'status > To drop an existing `CHECK` constraint, you can use the `Yiisoft\Db\Command\CommandInterface::dropCheck()` method: ```php -createCommand()->batchInsert( To delete rows from a table, you can use the `Yiisoft\Db\Command\CommandInterface::delete()` method: ```php -createCommand()->delete('{{%customer}}', ['id' => 1])->execute(); To reset the sequence of a table, you can use the `Yiisoft\Db\Command\CommandInterface::resetSequence()` method: ```php -createCommand()->resetSequence('{{%customer}}', 1)->execute(); To insert a row to a table, you can use the `Yiisoft\Db\Command\CommandInterface::insert()` method: ```php -createCommand()->insert('{{%customer}}', ['name' => 'John', 'age' => 18])->execute(); +$db->createCommand()->insert('{{%customer}}', ['name' => 'John Doe', 'age' => 18])->execute(); ``` ## Update @@ -84,10 +68,6 @@ $db->createCommand()->insert('{{%customer}}', ['name' => 'John', 'age' => 18])-> To update rows in a table, you can use the `Yiisoft\Db\Command\CommandInterface::update()` method: ```php - Info: In many places in higher abstraction layers, like **query builder**, you often specify an +> Note: In many places in higher abstraction layers, like **query builder**, you often specify an **array of values** and Yii DB does parameter binding for you, so there is no need to specify parameters manually. @@ -18,10 +18,6 @@ You can use `bindValue()` to bind a value to a parameter. For example, the following code binds the value `42` to the named placeholder `:id`. ```php - Note: To preserve precision, all data fetched from databases in the string type, even if the corresponding +> Note: To preserve precision, all data fetched from databases in the string type, even if the corresponding > database column types are different, numerical for example. > You may need to use type conversion to convert them into the corresponding PHP types. -### Query all +## Query all Returns an array of all rows in the result set. Each array element is an array representing a row of data, with the array keys as column names. @@ -34,10 +30,6 @@ It returns an empty array if the query results in nothing. For example, the following code fetches all rows from the `customer` table. ```php -createCommand("UPDATE {{%customer}} SET [[name]] = 'John' WHERE [[id]] = 1"); +$command = $db->createCommand("UPDATE {{%customer}} SET [[name]] = 'John Doe' WHERE [[id]] = 1"); $rowCount = $command->execute(); // 1 ``` This query however affects no rows, because no rows were found by the given condition in `WHERE` clause: ```php -createCommand("UPDATE {{%customer}} SET [[name]] = 'John' WHERE [[id]] = 1000"); +$command = $db->createCommand("UPDATE {{%customer}} SET [[name]] = 'John Doe' WHERE [[id]] = 1000"); $rowCount = $command->execute(); // 0 ``` In case of invalid SQL, the according exception will be thrown. ```php -transaction(function (ConnectionInterface $db) { When using transactions, you could specify isolation level as a second argument of `transaction()`, `beginTransaction()` or `createTransaction()`. - diff --git a/docs/en/query-builder.md b/docs/guide/en/query-builder.md similarity index 88% rename from docs/en/query-builder.md rename to docs/guide/en/query-builder.md index 90eb85a99..a3ca5ca20 100644 --- a/docs/en/query-builder.md +++ b/docs/guide/en/query-builder.md @@ -9,16 +9,12 @@ Using a query builder usually involves two steps: 1. Build a `Yiisoft\Db\Query\Query` class instance to represent different parts (such as `SELECT`, `FROM`) of a `SELECT` SQL statement. -2. Execute a **query method** for example, `all()`, `one()`, `scalar()`, `column()`, `query()` of +2. Execute a **query method**, for example, `all()`, `one()`, `scalar()`, `column()`, `query()` of `Yiisoft\Db\Query\Query` to retrieve data from the database. The following code shows a typical way of using a query builder. ```php - Note: For DBMS that don't support `LIMIT` and `OFFSET` such as `MSSQL`, query builder will generate a SQL +> Note: For DBMS that don't support `LIMIT` and `OFFSET` such as `MSSQL`, query builder will generate a SQL > statement that emulates this behavior. diff --git a/docs/en/query/order-by.md b/docs/guide/en/query/order-by.md similarity index 100% rename from docs/en/query/order-by.md rename to docs/guide/en/query/order-by.md diff --git a/docs/en/query/select.md b/docs/guide/en/query/select.md similarity index 94% rename from docs/en/query/select.md rename to docs/guide/en/query/select.md index c4b4845a0..7c4e64d8a 100644 --- a/docs/en/query/select.md +++ b/docs/guide/en/query/select.md @@ -47,7 +47,7 @@ If you don't call the `Yiisoft\Db\Query\Query::select()` method when building a it assumes to select `*` which means selecting all columns. Besides column names, you can also select DB expressions. -In this case, you must use the array format to avoid wrong automatic name quoting. +In this case, you must use the array format to avoid wrong automatic name quoting. For example, the following code will select columns `CONCAT(first_name, ' ', last_name)` with alias `full_name` and column `email`. @@ -64,10 +64,6 @@ You may also select sub-queries. You should specify each sub-query in terms of a For example, the following code will select count of users in each post. ```php -select('user_id')->distinct(); ``` -The relevant part of SQL is: +Which results in: ```sql SELECT DISTINCT `user_id` @@ -97,8 +93,8 @@ SELECT DISTINCT `user_id` You can call `Yiisoft\Db\Query\Query::addSelect()` to select more columns. -For example, the following code will select `email` column, additionally to `id` and `username` columns specified -initially: +For example, the following code will select `email` column, additionally to `id` and `username` columns specified +initially: ```php $query->select(['id', 'username'])->addSelect(['email']); diff --git a/docs/en/query/union.md b/docs/guide/en/query/union.md similarity index 94% rename from docs/en/query/union.md rename to docs/guide/en/query/union.md index 19b8e3d58..5374b356f 100644 --- a/docs/en/query/union.md +++ b/docs/guide/en/query/union.md @@ -5,10 +5,6 @@ The `Yiisoft\Db\Query\Query::union()` method specifies the `UNION` fragment of a For example: ```php -where([$column => $value]); ## Operator format -Operator format allows you to specify arbitrary conditions in a programmatic way. It takes the following format. +Operator format allows you to specify arbitrary conditions in a programmatic way. It has the following syntax: ```php ['operator', 'operand1', 'operand2', ...] @@ -151,10 +147,10 @@ you should use `Yiisoft\Db\QueryBuilder\Condition\BetweenColumnsCondition`. Similar to `between` except the `BETWEEN` is replaced with `NOT BETWEEN` in the generated condition. -### in +### in Operand 1 should be a column or DB expression. -Operand 2 can be either an array or a `Yiisoft\Db\Query\Query`. +Operand 2 can be either an array or a `Yiisoft\Db\Query\Query`. It will generate an `IN` condition. If Operand 2 is an array, it will represent the range of the values that the column or DB expression should be; @@ -168,7 +164,7 @@ The in operator also supports composite columns. In this case, operand 1 should be an array of the columns, while operand 2 should be an array of arrays or a `Yiisoft\Db\Query\Query` object representing the range of the columns. -For example, `['in', ['id', 'name'], [['id' => 1, 'name' => 'oy']]]` will generate `(id, name) IN ((1, 'oy'))`. +For example, `['in', ['id', 'name'], [['id' => 1, 'name' => 'John Doe']]]` will generate `(id, name) IN ((1, 'John Doe'))`. ### not in @@ -192,7 +188,7 @@ If this operand isn't provided, a default escape mapping will be used. You may use false or an empty array to indicate the values are already escaped and no escape should be applied. -> Note: That when using an escape mapping (or the third operand isn't provided), +> Note: That when using an escape mapping (or the third operand isn't provided), > the values will be automatically inside within a pair of percentage characters. > Note: When using PostgreSQL, you may also use `ilike` instead of `like` for case-insensitive matching. @@ -231,9 +227,7 @@ However, note that Yii DB never escapes column names, so if you pass a variable likely become vulnerable to SQL injection attack. To keep application secure, either don't use variables as column names or filter variables against allow-list. -In case you need to get a column name from user. - -For example, the following code is vulnerable. +In case you need to get a column name from user, for example, the following code is vulnerable. ```php // Vulnerable code: @@ -257,10 +251,6 @@ Internally, the formats described are implicitly converted to object format befo so it's possible to combine formats in a single condition: ```php -filterWhere(['username' => $username, 'email' => $email]); ``` @@ -331,7 +321,7 @@ is that the former will ignore empty values provided in the condition in hash fo So, if `$email` is empty while `$username` isn't, the above code will result in the SQL condition `WHERE username=:username`. -> Note: A value is considered empty if it's either `null`, an empty array, an empty string or a string containing +> Note: A value is considered empty if it's either `null`, an empty array, an empty string or a string containing > whitespaces only. Like with `Yiisoft\Db\Query\Query::andWhere()` and `Yiisoft\Db\Query\Query::orWhere()`, diff --git a/docs/en/query/with-query.md b/docs/guide/en/query/with-query.md similarity index 97% rename from docs/en/query/with-query.md rename to docs/guide/en/query/with-query.md index bce695d21..02a06c8f9 100644 --- a/docs/en/query/with-query.md +++ b/docs/guide/en/query/with-query.md @@ -7,10 +7,6 @@ You can use it instead of subquery for more readability and some unique features For example, this query will select all nested permissions of admin with their children recursively. ```php -getTableSchema('customer'); ``` -If no table exists, the method returns `null` so to check if table exists you can do: +If no table exists, the method returns `null`. So, to check if table exists you can do: ```php -getTableSchema('customer') === null) { Having a table schema, you can get various info about the table: ```php -getDbType() . ')'; In either case you get instance or instances or `ColumnSchemaInterface` that you can use to get all the information about the column. - diff --git a/docs/en/testing.md b/docs/guide/en/testing.md similarity index 58% rename from docs/en/testing.md rename to docs/guide/en/testing.md index 99774a57d..462fc3634 100644 --- a/docs/en/testing.md +++ b/docs/guide/en/testing.md @@ -30,10 +30,6 @@ For running the Docker containers you can use the following command: docker compose up -d ``` -## Unit testing - -The package is tested with [PHPUnit](https://phpunit.de/). - ### Global testing The following steps are required to run the tests. @@ -59,34 +55,37 @@ vendor/bin/phpunit --testsuite=Pgsql ``` Suites available: + - Mssql - Mysql - Oracle - Pgsql - Sqlite -## Static analysis +## Documentation -The code is statically analyzed with [Psalm](https://psalm.dev/). To run static analysis: +- [Internals](docs/internals.md) -```shell -./vendor/bin/psalm -``` +## Support -## Rector +If you need help or have a question, the [Yii Forum](https://forum.yiiframework.com/c/yii-3-0/63) is a good place for that. +You may also check out other [Yii Community Resources](https://www.yiiframework.com/community). -Use [Rector](https://github.com/rectorphp/rector) to make codebase follow some specific rules or use either newest or any specific version of PHP: +## Support the project -```shell -./vendor/bin/rector -``` +[![Open Collective](https://img.shields.io/badge/Open%20Collective-sponsor-7eadf1?logo=open%20collective&logoColor=7eadf1&labelColor=555555)](https://opencollective.com/yiisoft) -## Composer require checker +## Follow updates -This package uses [composer-require-checker](https://github.com/maglnet/ComposerRequireChecker) to check if all dependencies are correctly defined in `composer.json`. +[![Official website](https://img.shields.io/badge/Powered_by-Yii_Framework-green.svg?style=flat)](https://www.yiiframework.com/) +[![Twitter](https://img.shields.io/badge/twitter-follow-1DA1F2?logo=twitter&logoColor=1DA1F2&labelColor=555555?style=flat)](https://twitter.com/yiiframework) +[![Telegram](https://img.shields.io/badge/telegram-join-1DA1F2?style=flat&logo=telegram)](https://t.me/yii3en) +[![Facebook](https://img.shields.io/badge/facebook-join-1DA1F2?style=flat&logo=facebook&logoColor=ffffff)](https://www.facebook.com/groups/yiitalk) +[![Slack](https://img.shields.io/badge/slack-join-1DA1F2?style=flat&logo=slack)](https://yiiframework.com/go/slack) -To run the checker, execute the following command: +## License -```shell -./vendor/bin/composer-require-checker -``` +The Yii Access is free software. It is released under the terms of the BSD License. +Please see [`LICENSE`](./LICENSE.md) for more information. + +Maintained by [Yii Software](https://www.yiiframework.com/). diff --git a/docs/guide/pt-BR/README.md b/docs/guide/pt-BR/README.md new file mode 100644 index 000000000..b5c3dc7e9 --- /dev/null +++ b/docs/guide/pt-BR/README.md @@ -0,0 +1,155 @@ +# Começando + +Yii DB é uma camada DAO (Data Access Object) para aplicações que usam [PHP](https://www.php.net/). +Ele fornece um conjunto de classes que ajudam você a acessar bancos de dados relacionais. +Ele foi projetado para ser flexível e extensível, +para que possa ser usado com diferentes bancos de dados e diferentes esquemas de banco de dados. +Sua natureza independente de banco de dados facilita a mudança de um banco de dados para outro. + +Yii DB fornece uma API orientada a objetos para acessar bancos de dados relacionais. +É a base para outros métodos mais avançados de acesso ao banco de dados, incluindo o [Query Builder](query-builder.md). + +Ao usar o Yii DB, você precisa lidar principalmente com SQLs simples e arrays PHP. +Como resultado, é a forma mais eficiente de acessar bancos de dados. +Entretanto, como a sintaxe SQL pode variar para diferentes bancos de dados, usar o Yii DB também significa que você terá que fazer um esforço extra para +criar um aplicativo independente de banco de dados. + +Yii DB suporta os seguintes bancos de dados prontos para uso: + +- [MSSQL](https://www.microsoft.com/en-us/sql-server/sql-server-2019) das versões **2017, 2019, 2022**. +- [MySQL](https://www.mysql.com/) das versões **5.7 - 8.0**. +- [MariaDB](https://mariadb.org/) das versões **10.4 - 10.9**. +- [Oracle](https://www.oracle.com/database/) das versões **12c - 21c**. +- [PostgreSQL](https://www.postgresql.org/) das versões **9.6 - 15**. +- [SQLite](https://www.sqlite.org/) da versão **3.3 e superior**. + +## Requerimentos + +- PHP 8.0 or higher. + +## Instalação + +Para instalar o Yii DB, você deve selecionar o driver que deseja usar e instalá-lo com o [Composer](https://getcomposer.org/). + +Para [MSSQL](https://github.com/yiisoft/db-mssql): + +```shell +composer require yiisoft/db-mssql +``` + +Para [MySQL/MariaDB](https://github.com/yiisoft/db-mysql): + +```shell +composer require yiisoft/db-mysql +``` + +Para [Oracle](https://github.com/yiisoft/db-oracle): + +```shell +composer require yiisoft/db-oracle +``` + +Para [PostgreSQL](https://github.com/yiisoft/db-pgsql): + +```shell +composer require yiisoft/db-pgsql +``` + +Para [SQLite](https://github.com/yiisoft/db-sqlite): + +```shell +composer require yiisoft/db-sqlite +``` + +## Pré-requisitos + +## Configurar cache de esquema + +Primeiro, você precisa [configurar o cache do esquema do banco de dados](schema/cache.md). + +## Criar conexão + +Você pode criar uma instância de conexão de banco de dados usando um [contêiner DI](https://github.com/yiisoft/di) ou sem ele. + +- [Servidor MSSQL](connection/mssql.md) +- [Servidor MySQL/MariaDB](connection/mysql.md) +- [Servidor Oracle](connection/oracle.md) +- [Servidor PostgreSQL](connection/pgsql.md) +- [Servidor SQLite](connection/sqlite.md) + +> Info: Quando você cria uma instância de conexão de banco de dados, a conexão real com o banco de dados não é estabelecida até +> você executar o primeiro SQL ou chamar o método `Yiisoft\Db\Connection\ConnectionInterface::open()` explicitamente. + +### Logger e profiler (criador de perfil) + +O Logger e o profiler são opcionais. Você pode usá-los se precisar registrar e criar um perfil de suas consultas. + +- [Logger](connection/logger.md) +- [profiler](connection/profiler.md) + +## Executar consultas SQL + +Depois de ter uma instância de conexão com o banco de dados, você pode executar uma consulta SQL seguindo as seguintes etapas: + +1. [Crie um comando e busque dados](queries/create-command-fetch-data.md) +2. [Parâmetros de vinculação (Bind parameters)](queries/bind-parameters.md) +3. [Executar um comando](queries/execute-command.md) +4. [Executar muitos comandos em uma transação](queries/transactions.md) + +## Citar nomes de tabelas e colunas + +Ao escrever um código independente de banco de dados, citar nomes de tabelas e colunas costuma ser uma dor de cabeça porque diferentes bancos de dados +têm nomes diferentes conforme suas regras. + +Para superar esse problema, você pode usar a seguinte sintaxe de nomeação introduzida pelo Yii DB: + +- `[[nome da coluna]]`: coloque o *nome da coluna* entre *colchetes duplos*. +- `{{%nome da tabela}}`: coloque o *nome da tabela* entre *colchetes duplos* e o caractere de porcentagem `%` + será substituído pelo *prefixo da tabela*. + +O Yii DB converterá automaticamente tais construções nas colunas ou nomes de tabelas entre aspas correspondentes usando a sintaxe específica do DBMS. + +Por exemplo, o código a seguir gerará uma instrução SQL válida para todos os bancos de dados suportados: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ + +$result = $db->createCommand('SELECT COUNT([[id]]) FROM {{%employee}}')->queryScalar() +``` + +## Construtor de consultas (Query Builder) + +Yii DB fornece um [Query Builder](query-builder.md) que ajuda você a criar instruções SQL de uma maneira mais conveniente. +É uma ferramenta poderosa para criar instruções SQL complexas de forma simples. + +## Comandos + +Yii DB fornece uma classe `Command` que representa uma instrução **SQL** a ser executada em um banco de dados. + +Você pode usá-lo para executar instruções **SQL** que não retornam nenhum conjunto de resultados, como `INSERT`, `UPDATE`, `DELETE`, +`CREATE TABLE`, `DROP TABLE`, `CREATE INDEX`, `DROP INDEX`, etc. + +- [comandos DDL](command/ddl.md) +- [comandos DML](command/dml.md) + +## Esquema + +Yii DB fornece uma maneira de inspecionar os metadados de um banco de dados, como nomes de tabelas, nomes de colunas, etc. +através do esquema: + +- [Leitura do esquema do banco de dados](schema/usage.md) +- [Configurando cache do esquema](schema/cache.md) + +## Extensões + +As seguintes extensões estão disponíveis para Yii DB. + +- [Active Record](https://github.com/yiisoft/active-record). +- [Cache DB](https://github.com/yiisoft/cache-db) +- [Data DB](https://github.com/yiisoft/data-db) +- [Log Target DB](https://github.com/yiisoft/log-target-db) +- [Rbac DB](https://github.com/yiisoft/rbac-db) +- [Translator Message DB](https://github.com/yiisoft/translator-message-db) +- [Yii DB Migration](https://github.com/yiisoft/yii-db-migration) diff --git a/docs/guide/pt-BR/command/ddl.md b/docs/guide/pt-BR/command/ddl.md new file mode 100644 index 000000000..84649806b --- /dev/null +++ b/docs/guide/pt-BR/command/ddl.md @@ -0,0 +1,411 @@ +# Comandos de linguagem de definição de dados (DDL) + +Linguagem de definição de dados (DDL) é um conjunto de instruções SQL para definir a estrutura do banco de dados. + +Instruções DDL são usadas para criar e alterar os objetos de banco de dados em um banco de dados. +Esses objetos podem ser tabelas, índices, visualizações, procedimentos armazenados, gatilhos e assim por diante. + +## Tabelas + +### Crie uma tabela + +Para criar uma tabela, você pode usar o método `Yiisoft\Db\Command\CommandInterface::createTable()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->createTable( + '{{%customer}}', + [ + 'id' => 'pk', + 'name' => 'string(255) NOT NULL', + 'email' => 'string(255) NOT NULL', + 'status' => 'integer NOT NULL', + 'created_at' => 'datetime NOT NULL', + ], +)->execute(); +``` + +A biblioteca criará e executará automaticamente o SQL adequado ao banco de dados utilizado. Por exemplo, a conexão MSSQL +executará o seguinte SQL: + +```sql +CREATE TABLE [customer] ( + [id] int IDENTITY PRIMARY KEY, + [name] nvarchar(255) NOT NULL, + [email] nvarchar(255) NOT NULL, + [status] int NOT NULL, + [created_at] datetime NOT NULL +) +``` + +E o seguinte SQL será executado no MySQL/MariaDB: + +```sql +CREATE TABLE `customer` ( + `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, + `name` varchar(255) NOT NULL, + `email` varchar(255) NOT NULL, + `status` int(11) NOT NULL, + `created_at` datetime(0) NOT NULL +) +``` + +### Apagar uma tabela + +Para eliminar uma tabela e todos os seus dados, você pode usar o +método `Yiisoft\Db\Command\CommandInterface::dropTable()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->dropTable('{{%customer}}')->execute(); +``` + +> Aviso: Todos os dados existentes serão excluídos. + +### Truncar uma tabela + +Para limpar apenas os dados de uma tabela sem remover a tabela você pode usar o +método `Yiisoft\Db\Command\CommandInterface::truncateTable()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->truncateTable('{{%customer}}')->execute(); +``` + +> Aviso: Todos os dados existentes serão excluídos. + +## Colunas + +### Adicione uma nova coluna + +Para adicionar uma nova coluna a uma tabela existente, você pode usar o método `Yiisoft\Db\Command\CommandInterface::addColumn()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; +use Yiisoft\Db\Mysql\Column; + +/** @var ConnectionInterface $db */ +$db->createCommand()->addColumn( + '{{%customer}}', + 'profile_id', + new Column('integer') +)->execute(); +``` + +### Alterar uma coluna + +Para alterar uma coluna existente, você pode usar o método `Yiisoft\Db\Command\CommandInterface::alterColumn()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; +use Yiisoft\Db\Mysql\Column; + +/** @var ConnectionInterface $db */ +$db->createCommand()->alterColumn( + '{{%customer}}', + 'profile_id', + new Column('integer')->notNull() +)->execute(); +``` + +### Renomear uma coluna + +Para renomear uma coluna existente, você pode usar o método `Yiisoft\Db\Command\CommandInterface::renameColumn()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->renameColumn('{{%customer}}', 'profile_id', 'profile_id_new')->execute(); +``` + +### Eliminar uma coluna + +Para eliminar uma coluna existente, você pode usar o método `Yiisoft\Db\Command\CommandInterface::dropColumn()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->dropColumn('{{%customer}}', 'profile_id')->execute(); +``` + +### Adicionar um valor padrão a uma coluna + +Para adicionar um valor padrão a uma coluna existente, você pode usar o método `Yiisoft\Db\Command\CommandInterface::addDefaultValue()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->addDefaultValue('{{%customer}}', 'df-customer-name', 'name', 'John Doe')->execute(); +``` + +### Remove o valor padrão de uma coluna + +Para eliminar um valor padrão de uma coluna existente, você pode usar o método `Yiisoft\Db\Command\CommandInterface::dropDefaultValue()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->dropDefaultValue('{{%customer}}', 'df-customer-name')->execute(); +``` + +## Chaves + +### Adicione uma chave primária + +Para adicionar uma chave primária a uma tabela existente, você pode usar o método `Yiisoft\Db\Command\CommandInterface::addPrimaryKey()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->addPrimaryKey('{{%customer}}', 'pk-customer-id', 'id')->execute(); +``` + +### Adicione uma chave estrangeira + +Para adicionar uma chave estrangeira a uma tabela existente, você pode usar o método `Yiisoft\Db\Command\CommandInterface::addForeignKey()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->addForeignKey( + '{{%customer}}', + 'fk-customer-profile_id', + 'profile_id', + '{{%profile}}', + 'id', + 'CASCADE', + 'CASCADE' +)->execute(); +``` + +### Remover uma chave primária + +Para remover uma chave primária existente, você pode usar o método `Yiisoft\Db\Command\CommandInterface::dropPrimaryKey()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->dropPrimaryKey('{{%customer}}', 'pk-customer-id')->execute(); +``` + +### Remover uma chave estrangeira + +Para remover uma chave estrangeira existente, você pode usar o método `Yiisoft\Db\Command\CommandInterface::dropForeignKey()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->dropForeignKey('{{%customer}}', 'fk-customer-profile_id')->execute(); +``` + +## Índices + +### Adicione um índice + +Para adicionar um índice a uma tabela existente, você pode usar o método `Yiisoft\Db\Command\CommandInterface::createIndex()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->createIndex('{{%customer}}', 'idx-customer-name', 'name')->execute(); +``` + +### Eliminar um índice + +Para eliminar um índice existente, você pode usar o método `Yiisoft\Db\Command\CommandInterface::dropIndex()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->dropIndex('{{%customer}}', 'idx-customer-name')->execute(); +``` + +### Adicionar índice exclusivo + +Você pode criar um índice único especificando a opção `UNIQUE` no parâmetro `$indexType`, é suportado por todos SGBDs: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->createIndex('test', 'idx_test_name', 'id', 'UNIQUE')->execute(); +``` + +> Info: índices exclusivos são índices que ajudam a manter a integridade dos dados, garantindo que nenhuma linha de dados em uma tabela tenha valores idênticos nos valores da chave. +> Quando você cria um índice exclusivo para uma tabela existente com dados, valores nas colunas ou expressões que compõem a +> chave de índice são verificadas quanto à exclusividade. + +### Adicionar índice clusterizado + +No MSSQL, você pode criar um índice clusterizado especificando a opção `CLUSTERED` no parâmetro `$indexType`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->createIndex('test', 'idx_test_name', 'id', 'CLUSTERED')->execute(); +``` + +> Info: Um índice clusterizado é um índice que define a ordem física na qual os registros da tabela são armazenados em um banco de dados. +> Como só pode haver uma maneira pela qual os registros são armazenados fisicamente em uma tabela de banco de dados, só pode haver um +> índice clusterizado por tabela. Por padrão, um índice clusterizado é criado em uma coluna de chave primária. + +### Adicionar índice não clusterizado + +No MSSQL, você pode criar um índice não clusterizado especificando a opção `NONCLUSTERED` no parâmetro `$indexType`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->createIndex('test', 'idx_test_name', 'id', 'NONCLUSTERED')->execute(); +``` + +> Info: Um índice não clusterizado também é usado para acelerar as operações de pesquisa. Ao contrário de um índice clusterizado, um índice não clusterizado não +> define fisicamente a ordem em que os registros são inseridos em uma tabela. Na verdade, um índice não clusterizado é armazenado em um +> local separado da tabela de dados. +> +> Um índice não clusterizado é como um índice de livro, localizado separadamente do conteúdo principal do livro. Como não está clusterizado +> os índices estão localizados em um local separado, pode haver vários índices não agrupados em cluster por tabela. + +### Adicionar índice de texto completo (fulltext) + +No MySQL e MariaDB, você pode criar um índice de texto completo especificando a opção `FULLTEXT` no parâmetro `$indexType`. + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->createIndex('test', 'idx_test_name', 'name', 'FULLTEXT')->execute(); +``` + +> Info: índices de texto completo são criados em colunas baseadas em texto (colunas `CHAR`, `VARCHAR` ou `TEXT`) para acelerar consultas e operações DML +> nos dados contidos nessas colunas. +> +> Um índice de texto completo é definido como parte de uma instrução `CREATE TABLE` ou adicionado a uma tabela existente usando `ALTER TABLE` ou `CREATE INDEX`. + +### Adicionar índice de bitmap + +No `Oracle`, você pode criar um índice de bitmap especificando a opção `BITMAP` no parâmetro `$indexType`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ + +$db->createCommand()->createIndex('test', 'idx_test_name', 'id', 'BITMAP')->execute(); +``` + +> Info: Um índice de bitmap é uma especificação +tipo especial de índice de banco de dados que usa bitmaps ou matriz de bits. No índice de bitmap, o Oracle armazena um +> bitmap para cada chave de índice. +> +> Cada chave de índice armazena ponteiros para várias linhas. Por exemplo, se você criar um índice de bitmap na coluna gênero da tabela de membros. + +## Restrições (Constraints) + +### Adicionar restrição `UNIQUE` + +Para adicionar uma restrição exclusiva a uma coluna existente, você pode usar o método `Yiisoft\Db\Command\CommandInterface::addUnique()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->addUnique('{{%customer}}', 'uq-customer-name', 'name')->execute(); +``` + +### Elimine a restrição `UNIQUE` + +Para eliminar uma restrição exclusiva de uma coluna existente, você pode usar o método `Yiisoft\Db\Command\CommandInterface::dropUnique()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->dropUnique('{{%customer}}', 'uq-customer-name')->execute(); +``` + +### Adicionar uma restrição `CHECK` + +Para adicionar uma restrição `CHECK` a uma tabela existente, você pode usar o método `Yiisoft\Db\Command\CommandInterface::addCheck()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->addCheck('{{%customer}}', 'ck-customer-status', 'status > 0')->execute(); +``` + +### Elimine a restrição `CHECK` + +Para eliminar uma restrição `CHECK` existente, você pode usar o método `Yiisoft\Db\Command\CommandInterface::dropCheck()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->dropCheck('{{%customer}}', 'ck-customer-status')->execute(); +``` + +## Comentários + +### Adicionar comentário a uma coluna + +Para adicionar um comentário a uma coluna existente, você pode usar o método `Yiisoft\Db\Command\CommandInterface::addCommentOnColumn()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->addCommentOnColumn('{{%customer}}', 'name', 'This is a customer name')->execute(); +``` + +### Adicionar comentário a uma tabela + +Para adicionar um comentário a uma tabela existente, você pode usar o método `Yiisoft\Db\Command\CommandInterface::addCommentOnTable()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->addCommentOnTable('{{%customer}}', 'This is a customer table')->execute(); +``` + +### Remover comentário de uma coluna + +Para remover um comentário de uma coluna existente, você pode usar o método `Yiisoft\Db\Command\CommandInterface::dropCommentFromColumn()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->dropCommentFromColumn('{{%customer}}', 'name')->execute(); +``` + +### Eliminar comentário de uma tabela + +Para eliminar um comentário de uma tabela existente, você pode usar o método `Yiisoft\Db\Command\CommandInterface::dropCommentFromTable()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->dropCommentFromTable('{{%customer}}')->execute(); +``` diff --git a/docs/guide/pt-BR/command/dml.md b/docs/guide/pt-BR/command/dml.md new file mode 100644 index 000000000..f4e3f23cf --- /dev/null +++ b/docs/guide/pt-BR/command/dml.md @@ -0,0 +1,99 @@ +# Comandos de linguagem de manipulação de dados (DML) + +DML é um conjunto de instruções SQL usadas para manipular dados em um banco de dados. + +Você pode usar o DML para realizar as seguintes operações: + +- [Inserção em lote](#inserção-em-lote) +- [Excluir linhas](#excluir-linhas) +- [Resetar uma sequência](#resetar-uma-sequência) +- [Inserir](#inserir) +- [Atualizar](#atualizar) +- [Upsert (Atualizar ou Inserir)](#upsert) + +## Inserção em lote + +Para inserir múltiplas linhas em uma tabela, você pode usar o método `Yiisoft\Db\Command\CommandInterface::batchInsert()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->batchInsert( + '{{%customer}}', + ['name', 'email'], + [ + ['user1', 'email1@email.com'], + ['user2', 'email2@email.com'], + ['user3', 'email3@email.com'], + ] +)->execute(); +``` + +## Excluir linhas + +Para excluir linhas de uma tabela, você pode usar o método `Yiisoft\Db\Command\CommandInterface::delete()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->delete('{{%customer}}', ['id' => 1])->execute(); +``` + +## Resetar uma sequência + +Para redefinir a sequência de uma tabela, você pode usar o método `Yiisoft\Db\Command\CommandInterface::resetSequence()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->resetSequence('{{%customer}}', 1)->execute(); +``` + +## Inserir + +Para inserir uma linha em uma tabela, você pode usar o método `Yiisoft\Db\Command\CommandInterface::insert()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->insert('{{%customer}}', ['name' => 'John Doe', 'age' => 18])->execute(); +``` + +## Atualizar + +Para atualizar linhas em uma tabela, você pode usar o método `Yiisoft\Db\Command\CommandInterface::update()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$db->createCommand()->update('{{%customer}}', ['status' => 2], ['id' > 1])->execute(); +``` + +## Upsert + +Para atualizar atomicamente linhas existentes e inserir linhas não existentes, +você pode usar o método `Yiisoft\Db\Command\CommandInterface::upsert()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; +use Yiisoft\Db\Expression\Expression; + +/** @var ConnectionInterface $db */ +$db->createCommand()->upsert( + 'pages', + [ + 'name' => 'Front page', + 'url' => 'https://example.com/', // URL is unique + 'visits' => 0, + ], + updateColumns: [ + 'visits' => new Expression('visits + 1'), + ], + params: $params, +)->execute(); +``` diff --git a/docs/guide/pt-BR/connection/logger.md b/docs/guide/pt-BR/connection/logger.md new file mode 100644 index 000000000..85ccc42c5 --- /dev/null +++ b/docs/guide/pt-BR/connection/logger.md @@ -0,0 +1,78 @@ +# Conectando com o logger + +Yii DB usa [PSR-3](https://www.php-fig.org/psr/psr-3/) para registro. +Você pode configurar um criador de logs que implemente `Psr\Log\LoggerInterface::class` no +[Contêiner DI](https://github.com/yiisoft/di). + +No exemplo a seguir, você configura [Yii Logging Library](https://github.com/yiisoft/log) com um +[arquivo como destino](https://github.com/yiisoft/log-target-file). + +Crie um arquivo `config/common/di/logger.php`: + +```php +use Psr\Log\LoggerInterface; +use Yiisoft\Definitions\ReferencesArray; +use Yiisoft\Log\Logger; +use Yiisoft\Log\Target\File\FileTarget; + +return [ + LoggerInterface::class => [ + 'class' => Logger::class, + '__construct()' => [ + 'targets' => ReferencesArray::from([FileTarget::class]), + ], + ], +]; +``` + +Dependendo do SGBD utilizado, crie um arquivo com configuração da conexão com o banco de dados. Por exemplo, ao usar PostgreSQL, +será `config/common/di/db-pgsql.php`: + +```php +use Psr\Log\LoggerInterface; +use Yiisoft\Db\Connection\ConnectionInterface; +use Yiisoft\Db\Pgsql\Connection; +use Yiisoft\Db\Pgsql\Driver; +use Yiisoft\Definitions\Reference; + +/** @var array $params */ + +return [ + ConnectionInterface::class => [ + 'class' => Connection::class, + '__construct()' => [ + 'driver' => new Driver( + $params['yiisoft/db-pgsql']['dsn'], + $params['yiisoft/db-pgsql']['username'], + $params['yiisoft/db-pgsql']['password'], + ), + ], + 'setLogger()' => [Reference::to(LoggerInterface::class)], + ], +]; +``` + +Para outros DBMS, consulte a seção ["Criar conexão"](/docs/guide/pt-BR/README.md#criar-conexão). + +## Uso avançado do Logger + +Se você precisar redefinir mensagens do logger ou aumentar/diminuir o nível de registro: + +1. Crie uma classe de logger personalizada +2. Use o contexto para detectar o tipo da mensagem no método “log” + +```php +use Yiisoft\Db\Driver\Pdo\LogType; + +class MyLogger extends ParentLoggerClass implements LoggerInterface +{ + public function log($level, string|\Stringable $message, array $context = []): void + { + if ($context['type'] === LogType::QUERY) { + ... your logic here + } + } + + // implements other methods of LoggerInterface without changes +} +``` diff --git a/docs/guide/pt-BR/connection/mssql.md b/docs/guide/pt-BR/connection/mssql.md new file mode 100644 index 000000000..5bd9f3d28 --- /dev/null +++ b/docs/guide/pt-BR/connection/mssql.md @@ -0,0 +1,67 @@ +# Conectando MSSQL + +Para configurar [Yii DB MSSQL](https://github.com/yiisoft/db-mssql) com [contêiner DI](https://github.com/yiisoft/di) +você precisa criar o arquivo de configuração `config/common/di/db-mssql.php`: + +```php +use Psr\Log\LoggerInterface; +use Yiisoft\Db\Connection\ConnectionInterface; +use Yiisoft\Db\Mssql\Connection; +use Yiisoft\Db\Mssql\Driver; +use Yiisoft\Profiler\ProfilerInterface; + +/** @var array $params */ + +return [ + ConnectionInterface::class => [ + 'class' => Connection::class, + '__construct()' => [ + 'driver' => new Driver( + $params['yiisoft/db-mssql']['dsn'], + $params['yiisoft/db-mssql']['username'], + $params['yiisoft/db-mssql']['password'], + ), + ], + ], +]; +``` + +Crie um arquivo `config/common/params.php` para parâmetros `common`. + +```php +use Yiisoft\Db\Mssql\Dsn; + +return [ + 'yiisoft/db-mssql' => [ + 'dsn' => (new Dsn('sqlsrv', 'localhost', 'yiitest'))->asString(), + 'username' => 'user', + 'password' => 'password', + ], +]; +``` + +Para configurar a conexão sem [contêiner DI](https://github.com/yiisoft/di), +você precisa seguir estas etapas: + +```php +use Yiisoft\Cache\ArrayCache; +use Yiisoft\Db\Cache\SchemaCache; +use Yiisoft\Db\Mssql\Connection; +use Yiisoft\Db\Mssql\Driver; +use Yiisoft\Db\Mssql\Dsn; + +// Dsn. +$dsn = (new Dsn('sqlsrv', 'localhost', 'yiitest'))->asString(); + +// PSR-16 cache implementation. +$arrayCache = new ArrayCache(); + +// Schema cache. +$schemaCache = new SchemaCache($cache); + +// PDO driver. +$pdoDriver = new Driver($dsn, 'user', 'password'); + +// Connection. +$db = new Connection($pdoDriver, $schemaCache); +``` diff --git a/docs/guide/pt-BR/connection/mysql.md b/docs/guide/pt-BR/connection/mysql.md new file mode 100644 index 000000000..88b729695 --- /dev/null +++ b/docs/guide/pt-BR/connection/mysql.md @@ -0,0 +1,78 @@ +# Conectando MySQL, MariaDB + +Para configurar [Yii DB MySQL/MariaDB](https://github.com/yiisoft/db-mysql) com +um [contêiner DI](https://github.com/yiisoft/di), você precisa criar o arquivo de configuração `config/common/di/db-mysql.php`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; +use Yiisoft\Db\Mysql\Connection; +use Yiisoft\Db\Mysql\Driver; + +/** @var array $params */ + +return [ + ConnectionInterface::class => [ + 'class' => Connection::class, + '__construct()' => [ + 'driver' => new Driver( + $params['yiisoft/db-mysql']['dsn'], + $params['yiisoft/db-mysql']['username'], + $params['yiisoft/db-mysql']['password'], + ), + ], + ], +]; +``` + +Crie um arquivo `config/common/params.php` para parâmetros `common`. + +```php +use Yiisoft\Db\Mysql\Dsn; + +return [ + 'yiisoft/db-mysql' => [ + 'dsn' => (new Dsn('mysql', '127.0.0.1', 'yiitest', '3306', ['charset' => 'utf8mb4']))->asString(), + 'username' => 'user', + 'password' => 'password', + ], +]; +``` + +Crie um arquivo `config/common/params.php` para parâmetros `common` com soquete unix DSN. + +```php +use Yiisoft\Db\Mysql\DsnSocket; + +return [ + 'yiisoft/db-mysql' => [ + 'dsn' => (new DsnSocket('mysql', '/var/run/mysqld/mysqld.sock', 'yiitest'))->asString(), + 'username' => 'user', + 'password' => 'password', + ], +]; +``` + +Para configurar sem [contêiner DI](https://github.com/yiisoft/di), você precisa seguir estas etapas: + +```php +use Yiisoft\Cache\ArrayCache; +use Yiisoft\Db\Cache\SchemaCache; +use Yiisoft\Db\Mysql\Connection; +use Yiisoft\Db\Mysql\Driver; +use Yiisoft\Db\Mysql\Dsn; + +// Dsn. +$dsn = (new Dsn('mysql', '127.0.0.1', 'yiitest', '3306', ['charset' => 'utf8mb4']))->asString(); + +// PSR-16 cache implementation. +$arrayCache = new ArrayCache(); + +// Schema cache. +$schemaCache = new SchemaCache($arrayCache); + +// PDO driver. +$pdoDriver = new Driver($dsn, 'user', 'password'); + +// Connection. +$db = new Connection($pdoDriver, $schemaCache); +``` diff --git a/docs/guide/pt-BR/connection/oracle.md b/docs/guide/pt-BR/connection/oracle.md new file mode 100644 index 000000000..b6e043ce5 --- /dev/null +++ b/docs/guide/pt-BR/connection/oracle.md @@ -0,0 +1,64 @@ +# Conectando Oracle + +Para configurar o [Yii DB Oracle](https://github.com/yiisoft/db-oracle) com o [container DI](https://github.com/yiisoft/di), +você precisa criar o arquivo de configuração `config/common/di/db-oracle.php`. + +```php +use Yiisoft\Db\Connection\ConnectionInterface; +use Yiisoft\Db\Oracle\Connection; +use Yiisoft\Db\Oracle\Driver; + +/** @var array $params */ + +return [ + ConnectionInterface::class => [ + 'class' => Connection::class, + '__construct()' => [ + 'driver' => new Driver( + $params['yiisoft/db-oracle']['dsn'], + $params['yiisoft/db-oracle']['username'], + $params['yiisoft/db-oracle']['password'], + ), + ], + ], +]; +``` + +Crie um arquivo `config/common/params.php` para parâmetros `common`. + +```php +use Yiisoft\Db\Oracle\Dsn; + +return [ + 'yiisoft/db-oracle' => [ + 'dsn' => (new Dsn('oci', 'localhost', 'XE', '1521', ['charset' => 'AL32UTF8']))->asString(), + 'username' => 'user', + 'password' => 'password', + ], +]; +``` + +Para configurar sem [contêiner DI](https://github.com/yiisoft/di), você precisa seguir estas etapas: + +```php +use Yiisoft\Cache\ArrayCache; +use Yiisoft\Db\Cache\SchemaCache; +use Yiisoft\Db\Oracle\Connection; +use Yiisoft\Db\Oracle\Driver; +use Yiisoft\Db\Oracle\Dsn; + +// Dsn. +$dsn = (new Dsn('oci', 'localhost', 'XE', '1521', ['charset' => 'AL32UTF8']))->asString(); + +// PSR-16 cache implementation. +$arrayCache = new ArrayCache(); + +// Schema cache. +$schemaCache = new SchemaCache($cache); + +// PDO driver. +$pdoDriver = new Driver($dsn, 'user', 'password'); + +// Connection. +$db = new Connection($pdoDriver, $schemaCache); +``` diff --git a/docs/guide/pt-BR/connection/pgsql.md b/docs/guide/pt-BR/connection/pgsql.md new file mode 100644 index 000000000..ef404b3f8 --- /dev/null +++ b/docs/guide/pt-BR/connection/pgsql.md @@ -0,0 +1,64 @@ +# Conectando PostgreSQL + +Para configurar o [Yii DB PostgreSQL](https://github.com/yiisoft/db-pgsql) com +um [contêiner DI](https://github.com/yiisoft/di), você precisa criar o arquivo de configuração `config/common/di/db-pgsql.php`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; +use Yiisoft\Db\Pgsql\Connection; +use Yiisoft\Db\Pgsql\Driver; + +/** @var array $params */ + +return [ + ConnectionInterface::class => [ + 'class' => Connection::class, + '__construct()' => [ + 'driver' => new Driver( + $params['yiisoft/db-pgsql']['dsn'], + $params['yiisoft/db-pgsql']['username'], + $params['yiisoft/db-pgsql']['password'], + ), + ], + ], +]; +``` + +Crie um arquivo `config/common/params.php` para parâmetros `common`. + +```php +use Yiisoft\Db\Pgsql\Dsn; + +return [ + 'yiisoft/db-pgsql' => [ + 'dsn' => (new Dsn('pgsql', '127.0.0.1', 'yiitest', '5432'))->asString(), + 'username' => 'user', + 'password' => 'password', + ], +]; +``` + +Para configurar sem um [contêiner DI](https://github.com/yiisoft/di), você precisa seguir estas etapas: + +```php +use Yiisoft\Cache\ArrayCache; +use Yiisoft\Db\Cache\SchemaCache; +use Yiisoft\Db\Pgsql\Connection; +use Yiisoft\Db\Pgsql\Driver; +use Yiisoft\Db\Pgsql\Dsn; + +// Dsn. +$dsn = (new Dsn('pgsql', '127.0.0.1', 'yiitest', '5432'))->asString(); + +// PSR-16 cache implementation. +$arrayCache = new ArrayCache(); + +// Schema cache. +$schemaCache = new SchemaCache($cache); + +// PDO driver. +$pdoDriver = new Driver($dsn, 'user', 'password'); + +// Connection. +$db = new Connection($pdoDriver, $schemaCache); +``` diff --git a/docs/guide/pt-BR/connection/profiler.md b/docs/guide/pt-BR/connection/profiler.md new file mode 100644 index 000000000..a7040b261 --- /dev/null +++ b/docs/guide/pt-BR/connection/profiler.md @@ -0,0 +1,57 @@ +# Conectando com o criador de perfil + +O Yii DB pode ser usado com o [Yii Profiler](https://github.com/yiisoft/profiler), uma ferramenta para coletar e analisar +consultas de banco de dados úteis para depuração e otimização do desempenho do banco de dados. + +Quando você instala o [Yii Profiler](https://github.com/yiisoft/profiler) ele é automaticamente configurado no +[Contêiner DI](https://github.com/yiisoft/di) para [Yii Config](https://github.com/yiisoft/config), +para que você possa usá-lo em seu aplicativo imediatamente. + +O seguinte descreve como configurá-lo manualmente. + +Crie um arquivo `config/common/di/profiler.php`. + +```php +use Psr\Log\LoggerInterface; +use Yiisoft\Definitions\Reference; +use Yiisoft\Profiler\Profiler; +use Yiisoft\Profiler\ProfilerInterface; + +return [ + ProfilerInterface::class => [ + 'class' => Profiler::class, + '__construct()' => [ + Reference::to(LoggerInterface::class), + ], + ], +]; +``` + +Dependendo do SGBD utilizado, crie um arquivo com configuração de conexão com o banco de dados. Por exemplo, ao usar PostgreSQL, +será `config/common/di/db-pgsql.php`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; +use Yiisoft\Db\Pgsql\Connection; +use Yiisoft\Db\Pgsql\Driver; +use Yiisoft\Definitions\Reference; +use Yiisoft\Profiler\ProfilerInterface; + +/** @var array $params */ + +return [ + ConnectionInterface::class => [ + 'class' => Connection::class, + '__construct()' => [ + 'driver' => new Driver( + $params['yiisoft/db-pgsql']['dsn'], + $params['yiisoft/db-pgsql']['username'], + $params['yiisoft/db-pgsql']['password'], + ), + ], + 'setProfiler()' => [Reference::to(ProfilerInterface::class)], + ], +]; +``` + +Para outros DBMS, consulte a seção ["Criar conexão"](/docs/guide/pt-BR/README.md#criar-conexão). diff --git a/docs/guide/pt-BR/connection/sqlite.md b/docs/guide/pt-BR/connection/sqlite.md new file mode 100644 index 000000000..89c0a6059 --- /dev/null +++ b/docs/guide/pt-BR/connection/sqlite.md @@ -0,0 +1,58 @@ +# Conectando SQLite + +Para configurar o [Yii DB SQLite](https://github.com/yiisoft/db-sqlite) com +um [contêiner DI](https://github.com/yiisoft/di), você precisa criar o arquivo de configuração `config/common/di/db-sqlite.php`. + +```php +use Yiisoft\Db\Connection\ConnectionInterface; +use Yiisoft\Db\Sqlite\Connection; +use Yiisoft\Db\Sqlite\Driver; + +/** @var array $params */ + +return [ + ConnectionInterface::class => [ + 'class' => Connection::class, + '__construct()' => [ + 'driver' => new Driver($params['yiisoft/db-sqlite']['dsn']), + ], + ], +]; +``` + +Crie um arquivo `config/common/params.php` para parâmetros `common`. + +```php +use Yiisoft\Db\Sqlite\Dsn; + +return [ + 'yiisoft/db-sqlite' => [ + 'dsn' => (new Dsn('sqlite', dirname(__DIR__, 2) . '/resources/database/sqlite.db'))->__toString(), + ], +]; +``` + +Para configurar sem [contêiner DI](https://github.com/yiisoft/di), você precisa seguir estas etapas: + +```php +use Yiisoft\Cache\ArrayCache; +use Yiisoft\Db\Cache\SchemaCache; +use Yiisoft\Db\Sqlite\Connection; +use Yiisoft\Db\Sqlite\Driver; +use Yiisoft\Db\Sqlite\Dsn; + +// Dsn. +$dsn = (new Dsn('sqlite', 'memory'))->asString(); + +// PSR-16 cache implementation. +$arrayCache = new ArrayCache(); + +// Schema cache. +$schemaCache = new SchemaCache($cache); + +// PDO driver. +$pdoDriver = new Driver($dsn); + +// Connection. +$db = new Connection($pdoDriver, $schemaCache); +``` diff --git a/docs/guide/pt-BR/queries/bind-parameters.md b/docs/guide/pt-BR/queries/bind-parameters.md new file mode 100644 index 000000000..c9f1c08a1 --- /dev/null +++ b/docs/guide/pt-BR/queries/bind-parameters.md @@ -0,0 +1,117 @@ +# Bind parameters (Vincular parâmetros) + +Existem dois casos de uso para vinculação de parâmetros: + +- Quando você faz a mesma consulta com dados diferentes muitas vezes. +- Quando você precisa inserir valores na string SQL para evitar **ataques de injeção de SQL**. + +Você pode fazer a vinculação usando espaços reservados nomeados (`:name`) ou espaços reservados posicionais (`?`) no lugar de valores e +passar valores como um argumento separado. + +> Nota: Em muitos lugares em camadas de abstração superiores, como **query builder**, você geralmente especifica uma +**matriz de valores** e o Yii DB faz ligação de parâmetros para você, então não há necessidade de especificar os +parâmetros manualmente. + +## Vincule um único valor + +Você pode usar `bindValue()` para vincular um valor a um parâmetro. +Por exemplo, o código a seguir vincula o valor `42` ao espaço reservado nomeado `:id`. + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ + +$command = $db->createCommand('SELECT * FROM {{%customer}} WHERE [[id]] = :id'); +$command->bindValue(':id', 42); +$command->queryOne(); +``` + +O resultado é: + +```php +[ + 'id' => '1', + 'email' => 'user1@example.com', + 'name' => 'user1', + 'address' => 'address1', + 'status' => '1', + 'profile_id' => '1', +] +``` + +## Vincule muitos valores de uma vez + +`bindValues()` vincula uma lista de valores aos espaços reservados nomeados correspondentes na instrução SQL. + +Por exemplo, o código a seguir vincula os valores `3` e `user3` aos espaços reservados nomeados `:id` e `:name`. + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ + +$command = $db->createCommand('SELECT * FROM {{%customer}} WHERE [[id]] = :id AND [[name]] = :name'); +$command->bindValues([':id' => 3, ':name' => 'user3']); +$command->queryOne(); +``` + +O resultado é: + +```php +[ + 'id' => '3', + 'email' => 'user3@example.com', + 'name' => 'user3', + 'address' => 'address3', + 'status' => '2', + 'profile_id' => '2', +] +``` + +## Vincular um parâmetro + +`bindParam()` vincula um parâmetro à **variável** especificada. +A diferença com `bindValue()` é que a variável pode mudar. + +Por exemplo, o código a seguir vincula o valor `2` e `user2` aos espaços reservados nomeados `:id` e `:name` e +então altera o valor: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ + +$command = $db->createCommand('SELECT * FROM {{%customer}} WHERE [[id]] = :id AND [[name]] = :name'); +$id = 2; +$name = 'user2'; +$command->bindParam(':id', $id); +$command->bindParam(':name', $name); +$user2 = $command->queryOne(); + +$id = 3; +$name = 'user3'; +$user3 = $command->queryOne(); +``` + +Os resultados são: + +```php +[ + 'id' => '2', + 'email' => 'user2@example.com', + 'name' => 'user2', + 'address' => 'address2', + 'status' => '1', + 'profile_id' => '1', +] + +[ + 'id' => '3', + 'email' => 'user3@example.com', + 'name' => 'user3', + 'address' => 'address3', + 'status' => '2', + 'profile_id' => '2', +] +``` diff --git a/docs/guide/pt-BR/queries/create-command-fetch-data.md b/docs/guide/pt-BR/queries/create-command-fetch-data.md new file mode 100644 index 000000000..9bec6cd6d --- /dev/null +++ b/docs/guide/pt-BR/queries/create-command-fetch-data.md @@ -0,0 +1,160 @@ +# Crie um comando e busque dados + +Para criar um comando, você pode usar o método `Yiisoft\Db\Connection\ConnectionInterface::createCommand()`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$command = $db->createCommand('SELECT * FROM {{%customer}}'); +``` + +Nos comandos, existem diferentes métodos para **buscar dados**: + +- [queryAll()](#query-all) +- [queryOne()](#query-one) +- [queryColumn()](#query-column) +- [queryScalar()](#query-scalar) +- [query()](#query) + +> Nota: Para preservar a precisão, todos os dados obtidos do bancos de dados retornam no tipo string, mesmo que os +> correspondentes tipos de colunas do banco de dados sejam diferentes, numéricos, por exemplo. +> Você pode precisar usar conversão de tipo para convertê-los nos tipos PHP correspondentes. + +## Query all + +Retorna uma array de todas as linhas do conjunto de resultados. +Cada elemento do array é um array que representa uma linha de dados, com as chaves do array com os nomes das colunas. +Ele retorna um array vazio se a consulta não retornar nada. + +Por exemplo, o código a seguir busca todas as linhas da tabela `customer`. + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$result = $db->createCommand('SELECT * FROM {{%customer}}')->queryAll(); +``` + +O resultado é: + +```php +[ + [ + 'id' => '1', + 'email' => 'user1@example.com', + 'name' => 'user1', + 'address' => 'address1', + 'status' => '1', + 'profile_id' => '1', + ], + [ + 'id' => '2', + 'email' => 'user2@example.com' + 'name' => 'user2', + 'address' => 'address2', + 'status' => '1', + 'profile_id' => null, + ], + [ + 'id' => '3', + 'email' => 'user3@example.com', + 'name' => 'user3', + 'address' => 'address3', + 'status' => '2', + 'profile_id' => '2', + ], +] +``` + +## Query one + +Retorna uma única linha de dados. +O valor de retorno é uma array que representa a primeira linha do resultado da consulta. +Ele retorna `null` se a consulta não retornar nada. + +Por exemplo, o código a seguir busca a primeira linha da tabela `customer`. + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$result = $db->createCommand('SELECT * FROM {{%customer}}')->queryOne(); +``` + +O resultado é: + +```php +[ + 'id' => '1', + 'email' => 'user1@example.com', + 'name' => 'user1', + 'address' => 'address1', + 'status' => '1', + 'profile_id' => '1', +] +``` + +## Query column + +Retorna os valores da primeira coluna do resultado da consulta. +Ele retorna um array vazio se a consulta não retornar nada. + +Por exemplo, o código a seguir busca os valores da primeira coluna da tabela `customer`. + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ + +$result = $db->createCommand('SELECT * FROM {{%customer}}')->queryColumn(); +``` + +O resultado é: + +```php +[ + '1', + '2', + '3', +] +``` + +## Query scalar + +Retorna o valor da primeira coluna da primeira linha do resultado da consulta. +Ele retorna `false` se não houver valor. + +Por exemplo, o código a seguir busca o valor da primeira coluna da primeira linha da tabela `customer`. + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ + +$result = $db->createCommand('SELECT * FROM {{%customer}}')->queryScalar(); +``` + +O resultado é: + +```php +'1' +``` + +## Query + +Retorna um objeto `Yiisoft\Db\DataReader\DataReaderInterface` para percorrer as linhas no conjunto de resultados. + +Por exemplo, o código a seguir busca todas as linhas da tabela `customer`. + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ + +$result = $db->createCommand('SELECT * FROM {{%customer}}')->query(); + +foreach ($result as $row) { + // do something with $row +} +``` diff --git a/docs/guide/pt-BR/queries/execute-command.md b/docs/guide/pt-BR/queries/execute-command.md new file mode 100644 index 000000000..4aec8ab93 --- /dev/null +++ b/docs/guide/pt-BR/queries/execute-command.md @@ -0,0 +1,46 @@ +# Executar um comando + +Todos os métodos introduzidos em [Criar um comando e buscar dados](create-command-fetch-data.md) lidam com +consultas `SELECT` que buscam dados de bancos de dados. + +Para consultas que não retornam nenhum dado, você deve chamar o método `Yiisoft\Db\Command\CommandInterface::execute()`: + +- Se a consulta for bem-sucedida, `Yiisoft\Db\Command\CommandInterface::execute()` retornará o número de linhas afetadas +pela execução do comando. +- Se nenhuma linha foi afetada pela execução do comando retornará `0`. +- Se a consulta falhar, ela lançará um `Yiisoft\Db\Exception\Exception`. + +Digamos que haja uma tabela de clientes, com uma linha com id `1` presente e uma linha com id `1000` ausente. E +consultas não `SELECT` estão sendo executadas para ambos. + +Então, no código a seguir, a contagem de linhas afetadas será `1`, porque a linha foi encontrada e atualizada com sucesso: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ + +$command = $db->createCommand("UPDATE {{%customer}} SET [[name]] = 'John Doe' WHERE [[id]] = 1"); +$rowCount = $command->execute(); // 1 +``` + +Esta consulta, entretanto, não afeta nenhuma linha, porque nenhuma linha foi encontrada pela condição fornecida na cláusula `WHERE`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ + +$command = $db->createCommand("UPDATE {{%customer}} SET [[name]] = 'John Doe' WHERE [[id]] = 1000"); +$rowCount = $command->execute(); // 0 +``` + +No caso de SQL inválido, a exceção correspondente será lançada. + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ + +$db->createCommand('bad SQL')->execute(); +``` diff --git a/docs/guide/pt-BR/queries/transactions.md b/docs/guide/pt-BR/queries/transactions.md new file mode 100644 index 000000000..011e58ad9 --- /dev/null +++ b/docs/guide/pt-BR/queries/transactions.md @@ -0,0 +1,89 @@ +# Executar muitos comandos em uma transação + +Para que os dados sejam consistentes quando vários comandos estiverem envolvidos, você pode usar transações. + +```php +use Yiisoft\Db\Connection\ConnectionInterface; +use Yiisoft\Db\Query\Query; +use Yiisoft\Db\Command\DataType; + +/** @var ConnectionInterface $db */ + +$transaction = $db->beginTransaction(); + +try { + $db + ->createCommand('INSERT INTO {{%posts}} ([[id]], [[title]]) VALUES (:id, :title)') + ->bindValue(':id', 1) + ->bindValue(':title', 'This is a post') + ->execute(); + + $insertTagCommand = $db + ->createCommand("INSERT INTO {{%tags}} ([[id]], [[name]]) VALUES (:id, :name)") + ->bindParam(':id', $id, DataType::INTEGER) + ->bindParam(':name', $name, DataType::STRING); + + $insertPostTagCommand = $db + ->createCommand("INSERT INTO {{%post_tag}} ([[tag_id]], [[post_id]]) VALUES (:tag_id, :post_id)") + ->bindParam(':tag_id', $id, DataType::INTEGER) + ->bindValue(':post_id', 1); + + $tags = [ + [1, 'php'], + [2, 'yii'], + [3, 'db'], + ]; + + foreach ($tags as list($id, $name)) { + $insertTagCommand->execute(); + $insertPostTagCommand->execute(); + } +} catch (Exception $e) { + $transaction->rollBack(); + // to get a slightest info about the Exception + var_dump($e->getMessage()); +} +``` + +Dessa forma, você obtém todos os dados ou nenhum dado, para que seu banco de dados permaneça consistente. + +Você também pode fazer isso sem `try ... catch`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; +use Yiisoft\Db\Query\Query; + +/** @var ConnectionInterface $db */ + +$db->transaction(function (ConnectionInterface $db) { + $db + ->createCommand('INSERT INTO {{%posts}} ([[id]], [[title]]) VALUES (:id, :title)') + ->bindValue(':id', 1) + ->bindValue(':title', 'This is a post') + ->execute(); + + $insertTagCommand = $db + ->createCommand("INSERT INTO {{%tags}} ([[id]], [[name]]) VALUES (:id, :name)") + ->bindParam(':id', $id, DataType::INTEGER) + ->bindParam(':name', $name, DataType::STRING); + + $insertPostTagCommand = $db + ->createCommand("INSERT INTO {{%post_tag}} ([[tag_id]], [[post_id]]) VALUES (:tag_id, :post_id)") + ->bindParam(':tag_id', $id, DataType::INTEGER) + ->bindValue(':post_id', 1); + + $tags = [ + [1, 'php'], + [2, 'yii'], + [3, 'db'], + ]; + + foreach ($tags as list($id, $name)) { + $insertTagCommand->execute(); + $insertPostTagCommand->execute(); + } +}); +``` + +Ao usar transações, você pode especificar o nível de isolamento como um segundo argumento de `transaction()`, `beginTransaction()` +ou `createTransaction()`. diff --git a/docs/guide/pt-BR/query-builder.md b/docs/guide/pt-BR/query-builder.md new file mode 100644 index 000000000..8d87f8a75 --- /dev/null +++ b/docs/guide/pt-BR/query-builder.md @@ -0,0 +1,48 @@ +# Query builder (Construtor de consultas) + +Construído sobre o Yii DB, o construtor de consultas permite que você construa uma consulta SQL de maneira programática e independente do DBMS. + +Em comparação com a escrita de instruções SQL brutas, o uso do construtor de consultas ajudará você a escrever códigos relacionados SQL mais legíveis +e gerar instruções SQL mais seguras. + +Usar um construtor de consultas geralmente envolve duas etapas: + +1. Construa uma instância de classe `Yiisoft\Db\Query\Query` para representar diferentes partes (como `SELECT`, `FROM`) de uma +instrução SQL `SELECT`. +2. Execute um **método de consulta**, por exemplo, `all()`, `one()`, `scalar()`, `column()`, `query()` de + `Yiisoft\Db\Query\Query` para recuperar dados do banco de dados. + +O código a seguir mostra uma maneira típica de usar um construtor de consultas. + +```php +use Yiisoft\Db\Connection\ConnectionInterface; +use Yiisoft\Db\Query\Query; + +/** @var ConnectionInterface $db */ + +$rows = (new Query($db)) + ->select(['id', 'email']) + ->from('{{%user}}') + ->where(['last_name' => 'Smith']) + ->limit(10) + ->all(); +``` + +O código acima gera e executa a seguinte consulta SQL, onde o parâmetro `:last_name` está vinculado a +à string `Smith`: + +```sql +SELECT `id`, `email` +FROM `user` +WHERE `last_name` = :last_name +LIMIT 10 +``` + +> Nota: `Yiisoft\Db\Query\Query` destina-se a ser usado mais ao invés de `Yiisoft\Db\QueryBuilder\QueryBuilder`. +> O primeiro invoca o último implicitamente quando você chama um dos métodos de consulta. +> `Yiisoft\Db\QueryBuilder\QueryBuilder` é a classe responsável por gerar instruções SQL dependentes de SGBD, como +> `SELECT`, `FROM`, `WHERE`, `ORDER BY` do `Yiisoft\Db\Query\Query`. + +## Uso + +- [Construindo consultas](/docs/guide/pt-BR/query-builder/building-queries.md). diff --git a/docs/guide/pt-BR/query-builder/building-queries.md b/docs/guide/pt-BR/query-builder/building-queries.md new file mode 100644 index 000000000..ea36eee50 --- /dev/null +++ b/docs/guide/pt-BR/query-builder/building-queries.md @@ -0,0 +1,39 @@ +# Construindo consultas + +Para construir um objeto `Yiisoft\Db\Query\Query`, você chama vários métodos de construção de consulta para especificar diferentes partes +de uma consulta SQL. + +Os nomes desses métodos são semelhantes às **palavras-chaves SQL** usadas nas partes correspondentes da **instrução SQL**. +Por exemplo, para especificar a parte `FROM` de uma **consulta SQL**, você chamaria o método `Yiisoft\Db\Query\Query::from()`. +Todos os métodos de construção de consulta retornam o próprio objeto de consulta, o que permite encadear muitas chamadas. + +- [Select](/docs/guide/pt-BR/query/select.md) +- [From](/docs/guide/pt-BR/query/from.md) +- [Where](/docs/guide/pt-BR/query/where.md) + - [Formato string](/docs/guide/pt-BR/query/where.md#formato-string) + - [Formato hash](/docs/guide/pt-BR/query/where.md#formato-hash) + - [Formato operador](/docs/guide/pt-BR/query/where.md#formato-operador) + - [and](/docs/guide/pt-BR/query/where.md#and) + - [or](/docs/guide/pt-BR/query/where.md#or) + - [not](/docs/guide/pt-BR/query/where.md#not) + - [between](/docs/guide/pt-BR/query/where.md#between) + - [not between](/docs/guide/pt-BR/query/where.md#not-between) + - [in](/docs/guide/pt-BR/query/where.md#in) + - [not in](/docs/guide/pt-BR/query/where.md#not-in) + - [like](/docs/guide/pt-BR/query/where.md#like) + - [or like](/docs/guide/pt-BR/query/where.md#or-like) + - [not like](/docs/guide/pt-BR/query/where.md#not-like) + - [or not like](/docs/guide/pt-BR/query/where.md#or-not-like) + - [exists](/docs/guide/pt-BR/query/where.md#exists) + - [not exists](/docs/guide/pt-BR/query/where.md#not-exists) + - [comparison](/docs/guide/pt-BR/query/where.md#comparison) + - [Formato objeto](/docs/guide/pt-BR/query/where.md#formato-objeto) + - [Anexando condições](/docs/guide/pt-BR/query/where.md#anexando-condições) + - [Condições de filtro](/docs/guide/pt-BR/query/where.md#condições-de-filtro) +- [OrderBy](/docs/guide/pt-BR/query/order-by.md) +- [GroupBy](/docs/guide/pt-BR/query/group-by.md) +- [Having](/docs/guide/pt-BR/query/having.md) +- [Limit and Offset](/docs/guide/pt-BR/query/limit-and-offset.md) +- [Join](/docs/guide/pt-BR/query/join.md) +- [Union](/docs/guide/pt-BR/query/union.md) +- [WithQuery](/docs/guide/pt-BR/query/with-query.md) diff --git a/docs/guide/pt-BR/query/from.md b/docs/guide/pt-BR/query/from.md new file mode 100644 index 000000000..8c82a507b --- /dev/null +++ b/docs/guide/pt-BR/query/from.md @@ -0,0 +1,34 @@ +# From + +O método `Yiisoft\Db\Query\Query::from()` especifica o fragmento `FROM` de uma **instrução SQL**. + +Por exemplo, o código a seguir selecionará todas as colunas da tabela `user`. + +```php +$query->from('{{%user}}'); +``` + +O SQL equivalente é: + +```sql +SELECT * FROM `user` +``` + +Você pode especificar **tabelas** para selecionar como uma string ou uma array. +Os nomes das tabelas podem conter **prefixos de esquema e/ou aliases de tabela**, como você faz ao escrever **instruções SQL brutas**. + +```php +$query->from(['{{public.%user}} u', '{{public.%post}} p']); + +// equal to: + +$query->from('{{public.%user}} u, {{public.%post}} p'); +``` + +> Dica: Prefira o formato array, pois deixa menos espaço para erros e é mais limpo no geral. + +Se estiver usando o formato de array, você também poderá especificar os aliases da tabela nas chaves da array, como a seguir. + +```php +$query->from(['u' => '{{public.%user}}', 'p' => '{{public.%post}}']); +``` diff --git a/docs/guide/pt-BR/query/group-by.md b/docs/guide/pt-BR/query/group-by.md new file mode 100644 index 000000000..0c3a60496 --- /dev/null +++ b/docs/guide/pt-BR/query/group-by.md @@ -0,0 +1,35 @@ +# Group by + +O método `\Yiisoft\Db\Query\Query::groupBy()` especifica o fragmento `\Yiisoft\Db\Query\Query::groupBy()` de uma consulta SQL. + +Por exemplo, o código a seguir irá gerar uma consulta que agrupa os resultados pela coluna `id` e pela coluna `status`. + +```php +$query->groupBy(['id', 'status']); +``` + +A parte relevante do SQL é: + +```sql +GROUP BY `id`, `status` +``` + +Se um `GROUP BY` envolve apenas nomes de colunas simples, você pode especificá-lo usando uma string, assim como faz ao escrever +instruções SQL brutas. + +Por exemplo, o código a seguir irá gerar uma consulta que agrupa os resultados pela coluna `id` e pela coluna `status`. + +```php +$query->groupBy('id, status'); +``` + +> Dica: Prefira o formato array se `GROUP BY` envolver alguma expressão de banco de dados. + +Você pode chamar `\Yiisoft\Db\Query\Query::addGroupBy()` para adicionar mais colunas ao fragmento `GROUP BY`. + +Por exemplo, o código a seguir irá gerar uma consulta que agrupa os resultados pela coluna `id`, a coluna `status` +e a coluna `age`. + +```php +$query->groupBy(['id', 'status'])->addGroupBy('age'); +``` diff --git a/docs/guide/pt-BR/query/having.md b/docs/guide/pt-BR/query/having.md new file mode 100644 index 000000000..2e6066ca9 --- /dev/null +++ b/docs/guide/pt-BR/query/having.md @@ -0,0 +1,33 @@ +# Having + +O método `Yiisoft\Db\Query\Query::having()` especifica o fragmento `HAVING` de uma consulta SQL. +É necessária uma condição que você pode especificar da mesma forma que `Yiisoft\Db\Query\Query::where()`. + +Por exemplo, o código a seguir irá gerar uma consulta que filtra os resultados pela coluna `status`: + +```php +$query->having(['status' => 1]); +``` + +A parte relevante do SQL é: + +```sql +HAVING `status` = 1 +``` + +Consulte a documentação de [Where](/docs/guide/pt-BR/query/where.md) para obter mais detalhes sobre como especificar uma condição. + +Você pode chamar `Yiisoft\Db\Query\Query::andHaving()` ou `Yiisoft\Db\Query\Query::orHaving()` para anexar mais condições +para o fragmento `HAVING`. + +Por exemplo, o código a seguir irá gerar uma consulta que filtra os resultados pela coluna `status` e pela coluna `age`: + +```php +$query->having(['status' => 1])->andHaving(['>', 'age', 30]); +``` + +A parte relevante do SQL é: + +```sql +HAVING (`status` = 1) AND (`age` > 30) +``` diff --git a/docs/guide/pt-BR/query/join.md b/docs/guide/pt-BR/query/join.md new file mode 100644 index 000000000..b2bc40376 --- /dev/null +++ b/docs/guide/pt-BR/query/join.md @@ -0,0 +1,53 @@ +# Join + +O método `Yiisoft\Db\Query\Query::join()` especifica o fragmento `JOIN` de uma consulta SQL. + +```php +$query->join('LEFT JOIN', 'post', 'post.user_id = user.id'); +``` + +A parte relevante do SQL é: + +```sql +LEFT JOIN `post` ON `post`.`user_id` = `user`.`id` +``` + +O método `Yiisoft\Db\Query\Query::join()` usa quatro parâmetros: + +- `type`: tipo de junção como `INNER JOIN`, `LEFT JOIN`. +- `table`: o nome da tabela a ser unida. +- `on`: condição de junção opcional, esse é o fragmento `ON`. + Consulte `Yiisoft\Db\Query\Query::where()` para obter detalhes sobre como especificar uma condição. + > Nota: A sintaxe de array não funciona para especificar uma condição baseada em coluna. + > `['user.id' => 'comment.userId']` resultará em uma condição + > onde o ID do usuário deve ser igual à string `comment.userId`. + > Você deve usar a sintaxe de string e especificar a condição como `user.id = comment.userId`. +- `params`: parâmetros opcionais para vincular à condição de junção. + +Você pode usar os seguintes métodos de atalho para especificar `INNER JOIN`, `LEFT JOIN` e `RIGHT JOIN`, respectivamente. + +- `innerJoin()`. +- `leftJoin()`. +- `rightJoin()`. + +Por exemplo: + +```php +$query->leftJoin('post', 'post.user_id = user.id'); +``` + +Para unir muitas tabelas, chame os métodos de junção várias vezes, uma vez para cada tabela. + +Além de juntar tabelas, você também pode juntar subconsultas. +Para fazer isso, especifique as subconsultas a serem unidas como objetos `Yiisoft\Db\Query\Query`. + +Por exemplo: + +```php +use Yiisoft\Db\Query\Query; + +$subQuery = (new Query())->from('post'); +$query->leftJoin(['u' => $subQuery], 'u.id = author_id'); +``` + +Nesse caso, você deve colocar a subconsulta no array e usar a chave do array para especificar o alias. diff --git a/docs/guide/pt-BR/query/limit-and-offset.md b/docs/guide/pt-BR/query/limit-and-offset.md new file mode 100644 index 000000000..67b00cb60 --- /dev/null +++ b/docs/guide/pt-BR/query/limit-and-offset.md @@ -0,0 +1,21 @@ +# Limit and offset (Limite e deslocamento) + +Os métodos `\Yiisoft\Db\Query\Query::limit()` e `\Yiisoft\Db\Query\Query::offset()` especificam +os fragmentos `LIMIT` e `OFFSET` de uma consulta SQL. + +Por exemplo, o código a seguir criará uma consulta que retornará apenas 10 registros a partir do 20º. + +```php +$query->limit(10)->offset(20); +``` + +A parte relevante do SQL é: + +```sql +LIMIT 10 OFFSET 20 +``` + +A consulta ignora limite ou deslocamento inválido, como um valor negativo. + +> Nota: Para DBMS que não suportam `LIMIT` e `OFFSET` como `MSSQL`, o construtor de consultas irá gerar uma +> declaração SQL que emula esse comportamento. diff --git a/docs/guide/pt-BR/query/order-by.md b/docs/guide/pt-BR/query/order-by.md new file mode 100644 index 000000000..bff263dd0 --- /dev/null +++ b/docs/guide/pt-BR/query/order-by.md @@ -0,0 +1,40 @@ +# Order by + +O método `\Yiisoft\Db\Query\Query::orderBy()` especifica o fragmento `ORDER BY` de uma consulta SQL. + +Por exemplo, o código a seguir irá gerar uma consulta que ordena os resultados pela coluna `id` em ordem crescente +e pela coluna `nome` em ordem decrescente. + +```php +$query->orderBy(['id' => SORT_ASC, 'name' => SORT_DESC]); +``` + +A parte relevante do SQL é: + +```sql +ORDER BY `id` ASC, `name` DESC +``` + +As chaves do array são nomes de colunas, enquanto os valores do array são as direções `ORDER BY` correspondentes. +A constante PHP `SORT_ASC` especifica a classificação ascendente e `SORT_DESC` especifica a classificação decrescente. + +Se `ORDER BY` envolver apenas nomes de colunas simples, você pode especificá-lo usando uma string, assim como faz ao escrever +instruções SQL brutas. + +Por exemplo, o código a seguir irá gerar uma consulta que ordena os resultados pela coluna `id` em ordem crescente +e pela coluna `nome` em ordem decrescente. + +```php +$query->orderBy('id ASC, name DESC'); +``` + +> Dica: Prefira o formato array se `ORDER BY` envolver alguma expressão do banco de dados. + +Você pode chamar `\Yiisoft\Db\Query\Query::addOrderBy()` para adicionar mais colunas ao fragmento `ORDER BY`. + +Por exemplo, o código a seguir irá gerar uma consulta que ordena os resultados pela coluna `id` em ordem crescente +e pela coluna `nome` em ordem decrescente. + +```php +$query->orderBy('id ASC')->addOrderBy('name DESC'); +``` diff --git a/docs/guide/pt-BR/query/select.md b/docs/guide/pt-BR/query/select.md new file mode 100644 index 000000000..bfe6cba2a --- /dev/null +++ b/docs/guide/pt-BR/query/select.md @@ -0,0 +1,101 @@ +# Select + +O método `Yiisoft\Db\Query\Query::select()` especifica o fragmento `SELECT` de uma instrução SQL. + +Em primeiro lugar, chamar este método é opcional e pode ser ignorado completamente, resultando na seleção de todas as colunas. + +```php +$query->from('{{%user}}'); + +// equal to: + +$query->select('*')->from('{{%user}}'); +``` + +Você pode especificar colunas para selecionar como um array ou como uma string. +Os nomes das colunas selecionadas serão automaticamente citados durante a geração da instrução SQL. + +```php +$query->select(['id', 'email']); + +// equal to: + +$query->select('id, email'); +``` + +Os nomes das colunas selecionados podem incluir prefixos de tabela e/ou aliases de coluna, como você faz ao escrever consultas SQL brutas. + +Por exemplo, o código a seguir selecionará as colunas `id` e `email` da tabela `user`. + +```php +$query->select(['user.id AS user_id', 'email']); + +// equal to: + +$query->select('user.id AS user_id, email'); +``` + +Se estiver usando o formato de array para especificar colunas, você também poderá usar as chaves de array para especificar os aliases das colunas. + +Por exemplo, o código acima pode ser reescrito da seguinte maneira. + +```php +$query->select(['user_id' => 'user.id', 'email']); +``` + +Se você não chamar o método `Yiisoft\Db\Query\Query::select()` ao construir uma consulta, +ele pressupõe selecionar `*`, o que significa selecionar todas as colunas. + +Além dos nomes das colunas, você também pode selecionar expressões de banco de dados. +Nesse caso, você deve usar o formato de array para evitar citações automáticas incorretas de nomes. + +Por exemplo, o código a seguir selecionará as colunas `CONCAT(first_name, ' ', last_name)` com o alias `full_name` +e a coluna `email`. + +```php +$query->select(["CONCAT(first_name, ' ', last_name) AS full_name", 'email']); +``` + +Tal como acontece com todos os lugares com SQL bruto envolvido, +você pode usar a sintaxe de cotação (quoting) independente do DBMS para nomes de tabelas e colunas ao escrever expressões de banco de dados em select. + +Você também pode selecionar subconsultas. Você deve especificar cada subconsulta em termos de um objeto `Yiisoft\Db\Query\Query`. + +Por exemplo, o código a seguir selecionará a contagem de usuários em cada postagem. + +```php +use Yiisoft\Db\Connection\ConnectionInterface; +use Yiisoft\Db\Query\Query; + +/** @var ConnectionInterface $db */ + +$subQuery = (new Query($db))->select('COUNT(*)')->from('{{%user}}'); +$query = (new Query($db))->select(['id', 'count' => $subQuery])->from('{{%post}}'); +``` + +O SQL equivalente é: + +```sql +SELECT `id`, (SELECT COUNT(*) FROM `user`) AS `count` FROM `post` +``` + +Para selecionar linhas distintas, você pode chamar `distinct()`, como a seguir. + +```php +$query->select('user_id')->distinct(); +``` + +Que resulta em: + +```sql +SELECT DISTINCT `user_id` +``` + +Você pode chamar `Yiisoft\Db\Query\Query::addSelect()` para selecionar mais colunas. + +Por exemplo, o código a seguir selecionará a coluna `email`, além das colunas `id` e `username` especificadas +inicialmente: + +```php +$query->select(['id', 'username'])->addSelect(['email']); +``` diff --git a/docs/guide/pt-BR/query/union.md b/docs/guide/pt-BR/query/union.md new file mode 100644 index 000000000..c4bd36bf6 --- /dev/null +++ b/docs/guide/pt-BR/query/union.md @@ -0,0 +1,18 @@ +# Union + +O método `Yiisoft\Db\Query\Query::union()` especifica o fragmento `UNION` de uma consulta SQL. + +Por exemplo: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; +use Yiisoft\Db\Query\Query; + +/** @var ConnectionInterface $db */ + +$query1 = (new Query($db))->select("id, category_id AS type, name")->from('{{%post}}')->limit(10); +$query2 = (new Query($db))->select('id, type, name')->from('{{%user}}')->limit(10); +$query1->union($query2); +``` + +Outras chamadas para `Yiisoft\Db\Query\Query::union()` anexarão outros fragmentos `UNION`. diff --git a/docs/guide/pt-BR/query/where.md b/docs/guide/pt-BR/query/where.md new file mode 100644 index 000000000..ca246d07f --- /dev/null +++ b/docs/guide/pt-BR/query/where.md @@ -0,0 +1,345 @@ +# Where + +O método `Yiisoft\Db\Query\Query::where()` especifica o fragmento `WHERE` de uma consulta SQL. +Você pode usar um dos quatro formatos para especificar uma condição `WHERE`. + +- formato string, `status=1`. +- formato hash, `['status' => 1, 'type' => 2]`. +- formato array, `['like', 'name', 'test']`. +- formato objeto, `new LikeCondition('name', 'LIKE', 'test')`. + +## Formato string + +O formato string é melhor usado para especificar condições básicas ou se você precisar usar funções integradas do SGBD. +Funciona como se você estivesse escrevendo um SQL bruto. + +Por exemplo, o código a seguir selecionará todos os usuários cujo status seja 1. + +```php +$query->where('status = 1'); + +// or use parameter binding to bind dynamic parameter values +$query->where('status = :status', [':status' => $status]); + +// raw SQL using MySQL "YEAR()" function on a date field +$query->where('YEAR(somedate) = 2015'); +``` + +Não incorpore variáveis diretamente na condição como a seguir, especialmente se os valores das variáveis vierem +das entradas do usuário final, porque isso tornará seu aplicativo sujeito a ataques de injeção de SQL. + +```php +// Dangerous! Don't do this unless you are certain $status must be an integer. +$query->where("status = $status"); +``` + +Ao usar a ligação de parâmetros, você pode chamar `Yiisoft\Db\Query\Query::params()` ou `Yiisoft\Db\Query\Query::addParams()` +e passar os parâmetros como um argumento separado. + +```php +$query->where('status = :status')->addParams([':status' => $status]); +``` + +Tal como acontece com todos os lugares onde o SQL bruto está envolvido, +você pode usar a sintaxe de quoting do DBMS para nomes de tabelas e colunas ao escrever condições em formato de string. + +## Formato hash + +O formato hash é melhor usado para especificar muitas subcondições concatenadas com `AND`, cada uma sendo uma simples afirmação de igualdade. +É escrito como um array cujas chaves são nomes de colunas e valores são seus valores correspondentes. + +```php +$query->where(['status' => 10, 'type' => null, 'id' => [4, 8, 15]]); +``` + +A parte relevante do SQL é: + +```sql +WHERE (`status` = 10) AND (`type` IS NULL) AND (`id` IN (4, 8, 15)) +``` + +Como você pode ver, o construtor de consultas é inteligente o suficiente para lidar com valores nulos ou arrayes. + +Você também pode usar subconsultas em formato hash como a seguir. + +```php +use Yiisoft\Db\Connection\ConnectionInterface; +use Yiisoft\Db\Query\Query; + +/** @var ConnectionInterface $db */ + +$userQuery = (new Query($db))->select('id')->from('user'); +$query->where(['id' => $userQuery]); +``` + +A parte relevante do SQL é: + +```sql +WHERE `id` IN (SELECT `id` FROM `user`) +``` + +Usando o formato hash, o Yii DB aplica internamente a vinculação de parâmetros para valores, portanto, em contraste com o formato string, +aqui você não precisa adicionar parâmetros manualmente. + +Entretanto, observe que o Yii DB nunca escapa dos nomes das colunas, então se você passar uma variável obtida do lado do usuário como uma coluna +nome sem mais verificações, o aplicativo ficará vulnerável a ataques de injeção de SQL. + +Para manter o aplicativo seguro, não use variáveis como nomes de colunas ou filtre variáveis com listas de permissões. + +Por exemplo, o código a seguir é vulnerável. + +```php +// Vulnerable code: +$column = $request->get('column'); +$value = $request->get('value'); +$query->where([$column => $value]); +// $value is safe, but the $column name won't be encoded! +``` + +## Formato operador + +O formato operador permite especificar condições arbitrárias de forma programática. Tem a seguinte sintaxe: + +```php +['operator', 'operand1', 'operand2', ...] +``` + +Onde cada operando pode ser especificado em formato de string, formato hash ou formato operador recursivamente, +enquanto o operador pode ser um dos seguintes: + +### and + +Os operandos devem ser concatenados usando `and`. + +Por exemplo, `['and', 'id=1', 'id=2']` irá gerar `id=1 AND id=2`. + +Se um operando for um array, ele será convertido em uma string usando as regras descritas aqui. + +Por exemplo, `['and', 'type=1', ['or', 'id=1', 'id=2']]` irá gerar `type=1 AND (id=1 OR id=2)`. + +> Nota: O método não fará nenhuma citação ou escape. + +### or + +Semelhante ao operador `and`, exceto que os operandos são concatenados usando `or`. + +### not + +Requer apenas 1 operando, que será encapsulado em `NOT()`. + +Por exemplo, `['not', 'id=1']` irá gerar `NOT (id=1)`. + +Operando também pode ser um array para descrever muitas expressões. + +Por exemplo `['not', ['status' => 'draft', 'name' => 'example']]` irá gerar `NOT ((status='draft') AND (name='example'))`. + +### between + +O operando 1 deve ser o nome da coluna e os operandos 2 e 3 devem ser os valores inicial e final do intervalo em que a coluna está. + +Por exemplo, `['between', 'id', 1,10]` irá gerar `id BETWEEN 1 AND 10`. + +Caso você precise construir uma condição onde o valor esteja entre duas colunas `(like 11 BETWEEN min_id AND max_id)`, + +você deve usar `Yiisoft\Db\QueryBuilder\Condition\BetweenColumnsCondition`. + +### not between + +Semelhante a `between` exceto que `BETWEEN` é substituído por `NOT BETWEEN` na condição gerada. + +### in + +O operando 1 deve ser uma coluna ou expressão de banco de dados. +O operando 2 pode ser um array ou um `Yiisoft\Db\Query\Query`. + +Isso irá gerar uma condição `IN`. +Se o operando 2 for um array, ele representará o intervalo de valores que a coluna ou expressão do banco de dados deve ter; +Se o operando 2 for um objeto `Yiisoft\Db\Query\Query`, uma subconsulta será gerada e usada como intervalo da coluna ou expressão do banco de dados. + +Por exemplo, `['in', 'id', [1, 2, 3]]` irá gerar o id `IN (1, 2, 3)`. + +O método citará o nome da coluna e os valores de escape no intervalo. +O operador in também oferece suporte a colunas compostas. + +Neste caso, o operando 1 deve ser um array de colunas, +enquanto o operando 2 deve ser um array de arrays ou um objeto `Yiisoft\Db\Query\Query` representando o intervalo das colunas. + +Por exemplo, `['in', ['id', 'name'], [['id' => 1, 'name' => 'John Doe']]]` irá gerar `(id, name) IN ( (1, 'John Doe'))`. + +### not in + +Semelhante ao operador in, exceto que `IN` é substituído por `NOT IN` na condição gerada. + +### like + +O operando 1 deve ser uma coluna ou expressão de banco de dados e o operando 2 deve ser uma string ou array representando os valores +que a coluna ou expressão do banco de dados deve ter. + +Por exemplo, `['like', 'name', 'tester']` gerará `name LIKE '%tester%'`. + +Quando o intervalo de valores é fornecido como uma array, muitos predicados `LIKE` serão gerados e concatenados usando `AND`. + +Por exemplo, `['like', 'name', ['test', 'sample']]` irá gerar `name LIKE '%test%' AND name LIKE '%sample%'`. + +Você também pode fornecer um terceiro operando opcional para especificar como escapar de caracteres especiais nos valores. +O operando deve ser uma array de mapeamentos de caracteres especiais para suas contrapartes de escape. + +Se este operando não for fornecido, um mapeamento de escape padrão será usado. + +Você pode usar false ou um array vazio para indicar que os valores já foram escapados e nenhum escape deve ser aplicado. + +> Nota: Ao usar um mapeamento de escape (ou o terceiro operando não for fornecido), +> os valores estarão automaticamente dentro de um par de caracteres percentuais. + +> Nota: Ao usar o PostgreSQL, você também pode usar `ilike` em vez de `like` para correspondência sem distinção entre maiúsculas e minúsculas. + +### or like + +Semelhante ao operador `like` exceto que `OR` é usado para concatenar os predicados `LIKE` quando o segundo +operando é uma array. + +### not like + +Semelhante ao operador `like`, exceto que `LIKE` é substituído por `NOT LIKE` na condição gerada. + +### or not like + +Semelhante ao operador `not like`, exceto que `OR` é usado para concatenar os predicados `NOT LIKE`. + +### exists + +Requer um operando que deve ser uma instância de `Yiisoft\Db\Query\Query` representando a subconsulta. +Ele construirá uma expressão `EXISTS` (subconsulta). + +## not exists + +Semelhante ao operador `exists` e cria uma expressão `NOT EXISTS` (subconsulta). + +### comparison + +`>`, `<=` ou qualquer outro operador de banco de dados válido que receba dois operandos: o primeiro operando deve ser um `nome da coluna` enquanto +o segundo operando é um `valor`. Por exemplo, `['>', 'age', 10]` irá gerar `age > 10`. + +Usando o formato operador, o Yii DB usa internamente a vinculação de parâmetros para valores, portanto, em contraste com o formato de string, +aqui você não precisa adicionar parâmetros manualmente. + +Entretanto, observe que o Yii DB nunca escapa os nomes das colunas, então se você passar uma variável como nome da coluna, a aplicação irá +provavelmente se tornar vulnerável a ataques de injeção de SQL. + +Para manter o aplicativo seguro, não use variáveis como nomes de colunas ou filtre variáveis em relação à lista de permissões. +Caso você precise obter um nome de coluna do usuário, por exemplo, o código a seguir é vulnerável. + +```php +// Vulnerable code: +$column = $request->get('column'); +$value = $request->get('value'); +$query->where(['=', $column, $value]); +// $value is safe, but $column name won't be encoded! +``` + +## Formato objeto + +O formato objeto é o modo mais poderoso, porém mais complexo de definir condições. +Você também precisa usá-lo se quiser construir sua própria abstração sobre o construtor de consultas +ou se você deseja implementar suas próprias condições complexas. + +Instâncias de classes de condição são imutáveis. +Seu único propósito é armazenar dados de condições e fornecer getters para construtores de condições. +O construtor de condições é uma classe que contém a lógica que transforma os dados armazenados na condição na expressão SQL. + +Internamente, os formatos descritos são convertidos implicitamente para o formato de objeto antes da construção do SQL bruto, +então é possível combinar formatos em uma única condição: + +```php +use Yiisoft\Db\QueryBuilder\Condition\InCondition; +use Yiisoft\Db\QueryBuilder\Condition\OrCondition; +use Yiisoft\Db\Query\Query; + +/** @var Query $query */ + +$query->andWhere( + new OrCondition( + [ + new InCondition('type', 'in', $types), + ['like', 'name', '%good%'], + 'disabled=false', + ], + ), +); +``` + +A conversão do formato operador para o formato objeto é realizada de acordo +com a propriedade `Yiisoft\Db\QueryBuilder\AbstractDQLQueryBuilder::conditionClasses` +que mapeia nomes de operadores para nomes de classes representativos. + +- `AND`, `OR` => `Yiisoft\Db\QueryBuilder\Condition\ConjunctionCondition`. +- `NOT` => `Yiisoft\Db\QueryBuilder\Condition\NotCondition`. +- `IN`, `NOT IN` => `Yiisoft\Db\QueryBuilder\Condition\InCondition`. +- `BETWEEN`, `NOT BETWEEN` => `Yiisoft\Db\QueryBuilder\Condition\BetweenCondition`. + +## Anexando condições + +Você pode usar `Yiisoft\Db\Query\Query::andWhere()` ou `Yiisoft\Db\Query\Query::orWhere()` para anexar mais condições +para um já existente. Você pode chamá-los várias vezes para acrescentar muitas condições. Isso é útil para lógica condicional, +por exemplo: + +```php +$status = 10; +$search = 'yii'; + +$query->where(['status' => $status]); + +if ($search !== '') { + $query->andWhere(['like', 'title', $search]); +} +``` + +Se $search não estiver vazio, a seguinte condição `WHERE` será gerada: + +```sql +WHERE (`status` = 10) AND (`title` LIKE '%yii%') +``` + +## Condições de filtro + +Ao criar condições `WHERE` com base nas informações dos usuários finais, você geralmente deseja ignorar os valores de entrada +que estão vazios. + +Por exemplo, em um formulário de pesquisa que permite pesquisar por nome de usuário e e-mail, você gostaria +de ignorar a condição de nome de usuário/e-mail se o usuário não inseriu nada no campo de entrada correspondente. + +Você pode atingir esse objetivo usando o método `Yiisoft\Db\Query\Query::filterWhere()`: + +```php +// $username and $email are from user inputs +$query->filterWhere(['username' => $username, 'email' => $email]); +``` + +A única diferença entre `Yiisoft\Db\Query\Query::filterWhere()` e `Yiisoft\Db\Query\Query::where()` +é que o primeiro irá ignorar os valores vazios fornecidos na condição em formato hash. + +Então, se `$email` estiver vazio enquanto `$username` não estiver, +o código acima resultará na condição SQL `WHERE username=:username`. + +> Nota: Um valor é considerado vazio se for `nulo`, um array vazio, uma string vazia ou uma string contendo +> apenas espaços em branco. + +Assim como `Yiisoft\Db\Query\Query::andWhere()` e `Yiisoft\Db\Query\Query::orWhere()`, +você pode usar `Yiisoft\Db\Query\Query::andFilterWhere()` +e `Yiisoft\Db\Query\Query::orFilterWhere()` para anexar mais condições de filtro ao existente. + +Além disso, existe `Yiisoft\Db\Query\Query::andFilterCompare()` que pode determinar o operador de forma inteligente com base +no que está no valor. + +```php +$query + ->andFilterCompare('name', 'John Doe'); + ->andFilterCompare('rating', '>9'); + ->andFilterCompare('value', '<=100'); +``` + +Você também pode especificar o operador explicitamente: + +```php +$query->andFilterCompare('name', 'Doe', 'like'); +``` diff --git a/docs/guide/pt-BR/query/with-query.md b/docs/guide/pt-BR/query/with-query.md new file mode 100644 index 000000000..35bb3ab80 --- /dev/null +++ b/docs/guide/pt-BR/query/with-query.md @@ -0,0 +1,33 @@ +# With query + +O método `\Yiisoft\Db\Query\Query::withQuery()` especifica o prefixo `WITH` de uma consulta SQL. +Você pode usá-lo em vez da subconsulta para obter mais legibilidade e alguns recursos exclusivos (CTE recursivo). +[Leia mais em SQL moderno](https://modern-sql.com/). + +Por exemplo, esta consulta selecionará todas as permissões aninhadas de admin com seus filhos recursivamente. + +```php +use Yiisoft\Db\Connection\ConnectionInterface; +use Yiisoft\Db\Query\Query; + +/** @var ConnectionInterface $db */ + +$initialQuery = (new Query($db)) + ->select(['parent', 'child']) + ->from(['aic' => '{{%auth_item_child}}']) + ->where(['parent' => 'admin']); + +$recursiveQuery = (new Query($db)) + ->select(['aic.parent', 'aic.child']) + ->from(['aic' => '{{%auth_item_child}}']) + ->innerJoin('t1', 't1.child = aic.parent'); + +$mainQuery = (new Query($db)) + ->select(['parent', 'child']) + ->from('{{%t1}}') + ->withQuery($initialQuery->union($recursiveQuery), 't1', true); +``` + +`\Yiisoft\Db\Query\Query::withQuery()` pode ser chamado múltiplas vezes para acrescentar mais CTEs à consulta principal. +As consultas serão acrescentadas na mesma ordem em que o método foi chamado. +Se uma das consultas for recursiva, todo o CTE se tornará recursivo. diff --git a/docs/guide/pt-BR/schema/cache.md b/docs/guide/pt-BR/schema/cache.md new file mode 100644 index 000000000..ebeb86446 --- /dev/null +++ b/docs/guide/pt-BR/schema/cache.md @@ -0,0 +1,64 @@ +# Configurando o cache de esquema + +As informações sobre o esquema do banco de dados necessário para o ORM vêm de +[Schema](https://github.com/yiisoft/db/blob/master/src/Schema/AbstractSchema.php) que o recupera do +servidor de banco de dados. + +Para acesso mais rápido, [Schema](https://github.com/yiisoft/db/blob/master/src/Schema/AbstractSchema.php) armazena as +informações de esquema do banco de dados em [SchemaCache](https://github.com/yiisoft/db/blob/master/src/Cache/SchemaCache.php). + +Quando o [Schema](https://github.com/yiisoft/db/blob/master/src/Schema/AbstractSchema.php) precisa +recuperar informações sobre o esquema do banco de dados, primeiro ele verifica o cache. + +Você pode configurar [SchemaCache](https://github.com/yiisoft/db/blob/master/src/Cache/SchemaCache.php) para usar +[Implementação de cache PSR-16](https://github.com/php-fig/simple-cache) de duas maneiras: + +- Usar a ligação automática do [contêiner DI](https://github.com/yiisoft/di). +- Configurá-lo manualmente. + +Os exemplos abaixo usam [yiisoft/cache](https://github.com/yiisoft/cache). Certifique-se de tê-lo instalado via Composer +usando `composer require yiisoft/cache`. + +## Cache PSR-16 com conexão automática + +Esta configuração é adequada se você quiser usar o mesmo driver de cache para todo o aplicativo. + +Crie um arquivo `config/common/di/cache.php` para cache: + +```php +use Psr\SimpleCache\CacheInterface; +use Yiisoft\Cache\File\FileCache; + +/** @var array $params */ + +return [ + CacheInterface::class => [ + 'class' => FileCache::class, + '__construct()' => [ + 'cachePath' => __DIR__ . '/../../runtime/cache', + ], + ], +]; +``` + +O `SchemaCache` requer `CacheInterface` e o contêiner DI irá resolvê-lo automaticamente. + +## Configuração manual de cache + +Esta configuração é adequada se você quiser usar um driver de cache diferente para o esquema de cache. + +Crie um arquivo `config/common/di/db-schema-cache.php` para cache: + +```php +use Yiisoft\Cache\File\FileCache; +use Yiisoft\Db\Cache\SchemaCache; + +return [ + SchemaCache::class => [ + 'class' => SchemaCache::class, + '__construct()' => [ + new FileCache(__DIR__ . '/../../runtime/cache'), + ], + ], +]; +``` diff --git a/docs/guide/pt-BR/schema/usage.md b/docs/guide/pt-BR/schema/usage.md new file mode 100644 index 000000000..174b89823 --- /dev/null +++ b/docs/guide/pt-BR/schema/usage.md @@ -0,0 +1,99 @@ +# Lendo esquemas do banco de dados + +Yii DB fornece uma maneira de inspecionar os metadados de um banco de dados, como nomes de tabelas, nomes de colunas, etc. +por meio de objetos de esquema. + +## Obtenha tabelas disponíveis + +Para obter esquemas para todas as tabelas disponíveis, você pode usar o seguinte código: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$schemas = $db->getSchema()->getTableSchemas(); +foreach ($schemas as $schema) { + echo $schema->getFullName(); +} +``` + +Se você deseja obter tabelas apenas de um determinado esquema de banco de dados: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** + * When schema name is set, the default schema name will be ignored. + * + * @var ConnectionInterface $db + */ +$schemas = $db->getSchema()->getTableSchemas('public', true); +foreach ($schemas as $schema) { + echo $schema->getFullName(); +} +``` + +> Nota: Quando `refresh` for `true`, o esquema da tabela será recriado mesmo se for encontrado no cache. + +## Inspecione uma tabela + +Para obter um esquema para uma determinada tabela, use o seguinte código: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$tableSchema = $db->getTableSchema('customer'); +``` + +Se não existir nenhuma tabela, o método retornará `null`. Então, para verificar se a tabela existe você pode fazer: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +if ($db->getTableSchema('customer') === null) { + // there is no "customer" table +} +``` + +> Nota: `getTableSchema()` pode retornar informações do esquema em cache. Se você precisar ter certeza de que as informações estão +> atualizadas, passe `true` como segundo argumento. + +Tendo um esquema de tabela, você pode obter várias informações sobre a tabela: + +```php +use \Yiisoft\Db\Schema\TableSchemaInterface; + +/** @var TableSchemaInterface $tableSchema */ + +echo 'To create ' . $tableSchema->getFullName() . " use the following SQL:\n"; +echo $tableSchema->getCreateSql(); +``` + +No nome completo o nome da tabela é prefixado pelo esquema do banco de dados. +Se o nome do esquema for igual ao esquema padrão, o nome completo não incluirá o nome do esquema. + +### Recuperando esquemas de coluna + +Você pode recuperar os metadados da coluna para uma determinada tabela usando o método `getColumns()` ou o método `getColumn()` +da classe `TableSchema`: + +```php +use Yiisoft\Db\Connection\ConnectionInterface; + +/** @var ConnectionInterface $db */ +$tableSchema = $db->getTableSchema('customer'); +$columns = $tableSchema->getColumns(); +foreach ($columns as $name => $column) { + echo $name . ' (' . $column->getDbType() . ')'; +} + +// or a single column by name + +$column = $tableSchema->getColumn('id'); +echo 'id (' . $column->getDbType() . ')'; +``` + +Em ambos os casos, você obtém a instância ou instâncias +ou a `ColumnSchemaInterface` que você pode usar para obter todas as informações sobre a coluna. diff --git a/docs/guide/pt-BR/testing.md b/docs/guide/pt-BR/testing.md new file mode 100644 index 000000000..f1b8a2b55 --- /dev/null +++ b/docs/guide/pt-BR/testing.md @@ -0,0 +1,91 @@ +# Testes + +Este pacote pode ser testado globalmente ou individualmente para cada SGBD. + +- [MSSQL](https://github.com/yiisoft/db-mssql) +- [MySQL/MariaDB](https://github.com/yiisoft/db-mysql) +- [Oracle](https://github.com/yiisoft/db-oracle) +- [PostgreSQL](https://github.com/yiisoft/db-pgsql) +- [SQLite](https://github.com/yiisoft/db-sqlite) + +## Ações do Github + +Todos os nossos pacotes possuem ações no GitHub por padrão, então você pode testar sua [contribuição](https://github.com/yiisoft/db/blob/master/.github/CONTRIBUTING.md) na nuvem. + +> Observação: recomendamos a solicitação pull no modo rascunho até que todos os testes sejam aprovados. + +## Imagens Docker + +Para maior facilidade é recomendado utilizar containers Docker para cada SGBD, para isso você pode utilizar o arquivo [docker-compose.yml](https://docs.docker.com/compose/compose-file/) que está na raiz do diretório de cada pacote. + +- [MSSQL 2022](https://github.com/yiisoft/db-mssql/blob/master/docker-compose.yml) +- [MySQL 8](https://github.com/yiisoft/db-mysql/blob/master/docker-compose.yml) +- [MariaDB 10.11](https://github.com/yiisoft/db-mysql/blob/master/docker-compose-mariadb.yml) +- [Oracle 21](https://github.com/yiisoft/db-oracle/blob/master/docker-compose.yml) +- [PostgreSQL 15](https://github.com/yiisoft/db-pgsql/blob/master/docker-compose.yml) + +Para executar os contêineres Docker você pode usar o seguinte comando: + +```dockerfile +docker compose up -d +``` + +### Testes globais + +As etapas a seguir são necessárias para executar os testes. + +1. Execute todos os contêineres Docker para cada banco de dados. +2. Instale as dependências do projeto com o composer. +3. Execute os testes. + +```shell +vendor/bin/phpunit +``` + +### Testes individuais + +As etapas a seguir são necessárias para executar os testes. + +1. Execute o contêiner Docker para o dbms que deseja testar. +2. Instale as dependências do projeto com o composer. +3. Execute os testes. + +```shell +vendor/bin/phpunit --testsuite=Pgsql +``` + +Suítes disponíveis: + +- MSSQL +- Mysql +- Oracle +- Pgsql +- Sqlite + +## Documentation + +- [Internals](docs/internals.md) + +## Support + +If you need help or have a question, the [Yii Forum](https://forum.yiiframework.com/c/yii-3-0/63) is a good place for that. +You may also check out other [Yii Community Resources](https://www.yiiframework.com/community). + +## Support the project + +[![Open Collective](https://img.shields.io/badge/Open%20Collective-sponsor-7eadf1?logo=open%20collective&logoColor=7eadf1&labelColor=555555)](https://opencollective.com/yiisoft) + +## Follow updates + +[![Official website](https://img.shields.io/badge/Powered_by-Yii_Framework-green.svg?style=flat)](https://www.yiiframework.com/) +[![Twitter](https://img.shields.io/badge/twitter-follow-1DA1F2?logo=twitter&logoColor=1DA1F2&labelColor=555555?style=flat)](https://twitter.com/yiiframework) +[![Telegram](https://img.shields.io/badge/telegram-join-1DA1F2?style=flat&logo=telegram)](https://t.me/yii3en) +[![Facebook](https://img.shields.io/badge/facebook-join-1DA1F2?style=flat&logo=facebook&logoColor=ffffff)](https://www.facebook.com/groups/yiitalk) +[![Slack](https://img.shields.io/badge/slack-join-1DA1F2?style=flat&logo=slack)](https://yiiframework.com/go/slack) + +## License + +The Yii Access is free software. It is released under the terms of the BSD License. +Please see [`LICENSE`](./LICENSE.md) for more information. + +Maintained by [Yii Software](https://www.yiiframework.com/). diff --git a/docs/internals.md b/docs/internals.md new file mode 100644 index 000000000..8dc4049f0 --- /dev/null +++ b/docs/internals.md @@ -0,0 +1,45 @@ +# Internals + +## Unit testing + +The package is tested with [PHPUnit](https://phpunit.de/). To run tests: + +```shell +./vendor/bin/phpunit +``` + +## Mutation testing + +The package tests are checked with [Infection](https://infection.github.io/) mutation framework with +[Infection Static Analysis Plugin](https://github.com/Roave/infection-static-analysis-plugin). To run it: + +```shell +./vendor/bin/roave-infection-static-analysis-plugin +``` + +## Static analysis + +The code is statically analyzed with [Psalm](https://psalm.dev/). To run static analysis: + +```shell +./vendor/bin/psalm +``` + +## Rector + +Use [Rector](https://github.com/rectorphp/rector) to make codebase follow some specific rules or +use either newest or any specific version of PHP: + +```shell +./vendor/bin/rector +``` + +## Composer require checker + +This package uses [composer-require-checker](https://github.com/maglnet/ComposerRequireChecker) to check if all dependencies are correctly defined in `composer.json`. + +To run the checker, execute the following command: + +```shell +./vendor/bin/composer-require-checker +``` diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 39b4fff25..7142ccb39 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -7,7 +7,7 @@ executionOrder="default" failOnRisky="true" failOnWarning="true" - xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.2/phpunit.xsd" + xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/10.2/phpunit.xsd" > diff --git a/src/Command/CommandInterface.php b/src/Command/CommandInterface.php index 945d122d4..2fe7ffb39 100644 --- a/src/Command/CommandInterface.php +++ b/src/Command/CommandInterface.php @@ -241,10 +241,10 @@ public function bindValue(int|string $name, mixed $value, int $dataType = null): * * @param array|ParamInterface[] $values The values to bind. This must be given in terms of an associative * array with array keys being the parameter names, and an array values the corresponding parameter values, - * for example, `[':name' => 'John', ':age' => 25]`. + * for example, `[':name' => 'John Doe', ':age' => 25]`. * By default, the SQL data type of each value is determined by its PHP type. * You may explicitly specify the {@see DataType SQL data type} type by using a {@see Param} class: - * `new Param(value, type)`, for example, `[':name' => 'John', ':profile' => new Param($profile, DataType::LOB)]`. + * `new Param(value, type)`, for example, `[':name' => 'John Doe', ':profile' => new Param($profile, DataType::LOB)]`. */ public function bindValues(array $values): static; diff --git a/tests/AbstractCommandTest.php b/tests/AbstractCommandTest.php index bd11e91b2..466871dc2 100644 --- a/tests/AbstractCommandTest.php +++ b/tests/AbstractCommandTest.php @@ -65,10 +65,10 @@ public function testConstruct(): void $sql = <<createCommand($sql, [':name' => 'John']); + $command = $db->createCommand($sql, [':name' => 'John Doe']); $this->assertSame($sql, $command->getSql()); - $this->assertSame([':name' => 'John'], $command->getParams()); + $this->assertSame([':name' => 'John Doe'], $command->getParams()); } /** @@ -229,12 +229,10 @@ public function testProfiler(string $sql = null): void $profiler = $this->createMock(ProfilerInterface::class); $profiler->expects(self::once()) ->method('begin') - ->with($sql) - ; + ->with($sql); $profiler->expects(self::once()) ->method('end') - ->with($sql) - ; + ->with($sql); $db->setProfiler($profiler); $db->createCommand($sql)->execute(); @@ -253,7 +251,8 @@ public function testProfilerData(string $sql = null): void $db = $this->getConnection(); $db->open(); - $profiler = new class ($this, $sql) implements ProfilerInterface { + $profiler = new class($this, $sql) implements ProfilerInterface + { public function __construct(private TestCase $test, private string $sql) { } diff --git a/tests/Provider/QueryBuilderProvider.php b/tests/Provider/QueryBuilderProvider.php index f8f0b5356..28e12116c 100644 --- a/tests/Provider/QueryBuilderProvider.php +++ b/tests/Provider/QueryBuilderProvider.php @@ -271,9 +271,11 @@ public static function buildCondition(): array [['not', ''], '', []], [['not', '0'], 'NOT (0)', []], [['not', 'name'], 'NOT (name)', []], - [[ - 'not', - (new query(static::getDb()))->select('exists')->from('some_table'), ], + [ + [ + 'not', + (new query(static::getDb()))->select('exists')->from('some_table'), + ], 'NOT ((SELECT [[exists]] FROM [[some_table]]))', [], ], @@ -395,17 +397,18 @@ public static function buildCondition(): array [['in', 'id', [1]], '[[id]]=:qp0', [':qp0' => 1]], [['in', 'id', new TraversableObject([1])], '[[id]]=:qp0', [':qp0' => 1]], 'composite in' => [ - ['in', ['id', 'name'], [['id' => 1, 'name' => 'oy']]], + ['in', ['id', 'name'], [['id' => 1, 'name' => 'John Doe']]], '([[id]], [[name]]) IN ((:qp0, :qp1))', - [':qp0' => 1, ':qp1' => 'oy'], + [':qp0' => 1, ':qp1' => 'John Doe'], ], 'composite in with Expression' => [ - ['in', + [ + 'in', [new Expression('id'), new Expression('name')], - [['id' => 1, 'name' => 'oy']], + [['id' => 1, 'name' => 'John Doe']], ], '(id, name) IN ((:qp0, :qp1))', - [':qp0' => 1, ':qp1' => 'oy'], + [':qp0' => 1, ':qp1' => 'John Doe'], ], 'composite in (just one column)' => [ ['in', ['id'], [['id' => 1, 'name' => 'Name1'], ['id' => 2, 'name' => 'Name2']]], @@ -456,10 +459,10 @@ public static function buildCondition(): array [ 'in', new TraversableObject(['id', 'name']), - new TraversableObject([['id' => 1, 'name' => 'oy'], ['id' => 2, 'name' => 'yo']]), + new TraversableObject([['id' => 1, 'name' => 'John Doe'], ['id' => 2, 'name' => 'yo']]), ], '([[id]], [[name]]) IN ((:qp0, :qp1), (:qp2, :qp3))', - [':qp0' => 1, ':qp1' => 'oy', ':qp2' => 2, ':qp3' => 'yo'], + [':qp0' => 1, ':qp1' => 'John Doe', ':qp2' => 2, ':qp3' => 'yo'], ], /* in object conditions */ @@ -487,14 +490,14 @@ public static function buildCondition(): array [':qp0' => 1], ], 'inCondition-custom-4' => [ - new InCondition(['id', 'name'], 'in', [['name' => 'oy']]), + new InCondition(['id', 'name'], 'in', [['name' => 'John Doe']]), '([[id]], [[name]]) IN ((NULL, :qp0))', - [':qp0' => 'oy'], + [':qp0' => 'John Doe'], ], 'inCondition-custom-5' => [ - new InCondition(['id', 'name'], 'in', [['id' => 1, 'name' => 'oy']]), + new InCondition(['id', 'name'], 'in', [['id' => 1, 'name' => 'John Doe']]), '([[id]], [[name]]) IN ((:qp0, :qp1))', - [':qp0' => 1, ':qp1' => 'oy'], + [':qp0' => 1, ':qp1' => 'John Doe'], ], 'inCondition-custom-6' => [ new InCondition(