From d419db7c602f8511a2711052aead5055e053d22f Mon Sep 17 00:00:00 2001 From: hrach Date: Fri, 24 Apr 2015 15:39:42 +0200 Subject: [PATCH] doc: added connection, param placeholders chapters [skip ci] --- doc/datetime.texy | 4 +- doc/default.texy | 86 ++++++++++++++++++++++++++++++- doc/menu.texy | 10 ++-- doc/param-placeholders.texy | 87 ++++++++++++++++++++++++++++++++ doc/timezones-mysql-support.texy | 2 +- 5 files changed, 180 insertions(+), 9 deletions(-) create mode 100644 doc/param-placeholders.texy diff --git a/doc/datetime.texy b/doc/datetime.texy index 0d2b01b0..00cb4e6e 100644 --- a/doc/datetime.texy +++ b/doc/datetime.texy @@ -1,5 +1,5 @@ -DateTime and timezones support -############################## +DateTime TimeZones Support +########################## Let us recapitulate some facts: diff --git a/doc/default.texy b/doc/default.texy index 16c62879..6278dd8d 100644 --- a/doc/default.texy +++ b/doc/default.texy @@ -1,5 +1,87 @@ Nextras\Dbal ############ -.[note] -Documentation is work-in-progress. Please be patient. +Connection +========== + +Connection instance is starting point for working with database. Connection constructor accepts configuration array. Possible keys depend on the specific driver, although driver share the key names: + +|* driver | driver name, use `mysqli` or `pgsql` +|* host | database server name +|* username | username for authentication +|* password | password for authentication +|* database | name of database +|* charset | charset encoding of connection +|* applicationTz | time zone for returned DateTime objects +|* connectionTz | time zone for connection +|* simpleStorageTz | time zone for simple time stamp type + +/--php +$connection = new Nextras\Dbal\Connection([ + 'driver' => 'mysqli', + 'host' => 'localhost', + 'username' => 'root', + 'password' => '****', + 'database' => 'test', +]); +\-- + +By default, connection is lazy, it connects to database when needed. However, you can force the connection by calling `connect()` method. Of course, you can `disconnect()` or `reconnect()` your connection. Use `ping()` method to stay in touch with database. + +------------ + +Querying +======== + +Use `query()` method to run SQL queries. Query method accepts "pseudo" SQL statement. Dbal support parameter placeholders, which are passed separately and will be properly escaped and sanitized. Take a look on [Parameter Placeholders | param-placeholders] chapter. + +/--php +$connection->query('SELECT * FROM foo WHERE id = %i', 1); +// SELECT * FROM foo WHERE id = 1 + +$connection->query('SELECT * FROM foo WHERE title = %s', 'foo" OR 1=1'); +// SELECT * FROM foo WHERE title = "foo\" OR 1=1" +\-- + +"Pseudo" SQL support `[]` square brackets for easily escaping of column names. However, if you pass column name from user input as parameter, use proper `%column` placeholder. + +/--php +$connection->query('SELECT * FROM [foo] WHERE %column = %i', 'id, 1); +// SELECT * FROM `foo` WHERE `id` = 1 +\-- + +To retrieve last inserted id use `getLastInsertedId()` method. For PostgreSQL method accepts a sequence name. Number of affected rows is available through `getAffectedRows()` method. + +Each `query()` return new `Nextras\Dbal\Result\Result` object. Result object allows you to iterate over fetched data and fetch each row into `Nextras\Dbal\Result\Row` object: + +/--php +$users = $connection->query('SELECT * FROM [users]'); +foreach ($users as $row) { + $row->name; +} +\-- + +Result object implements `SeekableIterator`. You can use `fetch()` method to fetch rows, `fetchField()` to fetch the first field form the first row, or `fetchAll()` method to return array of row objects. + +/--php +$maximum = $connection->query('SELECT MAX([age]) FROM [users]')->fetchField(); +\-- + +------------ + +Transactions +============ + +Connection object provide convenient API for working with transaction. You can easily `beginTransaction()`, `commitTransaction()` and `rollbackTransaction()`. Usually you need to react to exception by calling rollback, otherwise commit it. For such use case there is `transactional()` method. + +/--php +$connection->transactional(function(Connection $connection) { + $connection->query('INSERT INTO users %values', [ + 'name' => 'new user' + ]); + $connection->query('INSERT INTO urls %values', [ + 'url' => 'new-user', + 'user_id' => $connection->getLastInsertedId(); + ]); +}); +\-- diff --git a/doc/menu.texy b/doc/menu.texy index cff3cc8f..e73d54df 100644 --- a/doc/menu.texy +++ b/doc/menu.texy @@ -1,7 +1,9 @@ -- [Introduction | default] +- [Connection | default] +- [Param Placeholders | param-placeholders] - [Query Builder | query-builder] -- [DateTime and TimeZones | datetime] - ----- +- [DateTime TimeZones | datetime] +/---div .[tuts] +Tutorials: - [MySQL Timezone Support | timezones-mysql-support] +\-- diff --git a/doc/param-placeholders.texy b/doc/param-placeholders.texy new file mode 100644 index 00000000..83cbdc99 --- /dev/null +++ b/doc/param-placeholders.texy @@ -0,0 +1,87 @@ +Parameter Placeholders +###################### + +Dbal allows you easy way to escape and build your SQL query. You can use powerful placeholders: + +|* `%s`, `%?s`, `%s[]` | string | not nullable, nullable, array of +|* `%i`, `%?i`, `%i[]` | integer | not nullable, nullable, array of +|* `%f`, `%?f`, `%f[]` | float | not nullable, nullable, array of +|* `%b`, `%?b`, `%b[]` | boolean | not nullable, nullable, array of +|* `%dt`, `%?dt`, `%dt[]` | datetime | not nullable, nullable, array of +|* `%dts`, `%?dts`, `%dts[]` | datetime | datetime with [conversion to simple storage time zone | datetime] +|* `%any`, `%any[]` | | any value scalary value, array of scalar values + +All modifiers require receiving argument of the modifier data type - eg. `%f` accepts only floats and integers. + +/--php +$connection->query('id = %i AND name IN (%?s, %?s)', 1, NULL, 'foo'); +// `id` = 1 AND name IN (NULL, 'foo') +\-- + +Other available modifiers: + +|* `%table` | escapes string as table name +|* `%column` | escapes string as column name +|* `%ex` | expands array as processor arguments +|* `%raw` | inserts string argument as is + +`%ex` modifier expands passed array as arguments of new `query()` method call. + +/--php +$connection->query('%ex', ['id = %i', 1]); +// equals to +$connection->query('id = %i', 1); +\-- + +Last modifiers are connected with array processing: + +|* `%and` | AND condition +|* `%or` | OR condition +|* `%values`, `%values[]` | expands array for INSERT clause, multi insert +|* `%set` | expands array for SET clause + +Let's examine `%and` and `%or` behavior. If array key is numeral and value is array, value is expanded with `%ex` modifier. + +/--php +$connection->query('%and', [ + 'city' => 'Winterfell', + 'age' => 23, +]); +// `city` = 'Winterfell' AND `age` = 23 + + +$connection->query('%or', [ + 'city' => 'Winterfell', + 'age' => [23, 25], +]); +// `city` = 'Winterfell' OR `age` IN (23, 25) + + +$connection->query('%or', [ + 'city' => 'Winterfell', + ['[age] IN %i[]', [23, 25]], +]); +// `city` = 'Winterfell' OR `age` IN (23, 25) +\-- + +Examples for inserting and updating: + +/--php +$connection->query('INSERT INTO [users] %values', [ + 'name' => 'Jon Snow' +]); +// INSERT INTO `users` (`name`) VALUES ('Jon Snow') + + +$connection->query('INSERT INTO [users] %values[]', [ + ['name' => 'Jon Snow'], + ['name' => 'The Imp'], +]); +// INSERT INTO `users` (`name`) VALUES ('Jon Snow'), ('The Imp') + + +$connection->query('UPDATE [users] %set WHERE [id] = %i', [ + 'name' => 'Jon Snow' +], 1); +// UPDATE `users` SET `name` = 'Jon Snow' WHERE `id` = 1 +\-- diff --git a/doc/timezones-mysql-support.texy b/doc/timezones-mysql-support.texy index 78a6fbb9..cc3e8529 100644 --- a/doc/timezones-mysql-support.texy +++ b/doc/timezones-mysql-support.texy @@ -1,7 +1,7 @@ Named Timezone Support in MySQL ############################### -MySQL, by default, does not "support" named timezones, therefore you could get errors similar to `Unknown or incorrect time zone: ‚Europe/Prague‘`. In fact, MySQL just does not know the correct timeshift for this name and allows you to import the configuration. +MySQL, by default, does not "support" named timezones, therefore you could get errors similar to `Unknown or incorrect time zone: 'Europe/Prague'`. In fact, MySQL just does not know the correct timeshift for this name and allows you to import the configuration. -------