Skip to content

Commit

Permalink
Adding more docs in Database Readme
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzo committed Jan 1, 2015
1 parent 20c1688 commit a2456ec
Showing 1 changed file with 221 additions and 1 deletion.
222 changes: 221 additions & 1 deletion src/Database/Readme.md
Expand Up @@ -8,6 +8,13 @@ profiling queries sent to the database.
It adopts the API from the native PDO extension in PHP for familiarity, but solves many of the
inconsistencies PDO has, while also provides several features that extends PDO capabilities.

A distinguishing factor this library has, when compared to similar database connection packages,
is that it takes the concept of "data types" to its core. It lets you work with complex PHP objects
or structures that can be passed as query conditions or to be inserted in the database.

The typing system will intelligently convert the PHP structures when passing them to the database, and
convert them back when retrieving.


## Connecting to the database

Expand Down Expand Up @@ -93,7 +100,7 @@ Alternatively you can construct a statement manually and then fetch rows from it
```php
$statement = $connection->prepare('SELECT * from articles WHERE id != :id');
$statement->bind(['id' => 1], ['id' => 'integer']);
$results $statement->fetchAll('assoc');
$results = $statement->fetchAll('assoc');
```

The default types that are understood by this library and can be passed to the `bind()` function or to `execute()`
Expand All @@ -112,6 +119,17 @@ are:

More types can be added dynamically, but it will be explained shortly after.

Statements can be reused by binding new values to the parameters in the query:

```php
$statement = $connection->prepare('SELECT * from articles WHERE id = :id');
$statement->bind(['id' => 1], ['id' => 'integer']);
$results = $statement->fetchAll('assoc');

$statement->bind(['id' => 1], ['id' => 'integer']);
$results = $statement->fetchAll('assoc');
```

### Updating Rows

Updating can be done using the `update()` function in the connection object. In the following
Expand All @@ -138,3 +156,205 @@ The example above will execute the following SQL:
```sql
UPDATE articles SET title = 'New Title' WHERE created >= '2014-10-10 00:00:00' AND created < '2014-10-13 00:00:00';
```

More on creating complex where conditions or more complex update queries later.

### Deleting Rows

Similarly, the `delete()` method is used to delete rows from the database:

```php
$connection->delete('articles', ['created <' => DateTime('now')], ['created' => 'date']);
```

Will generate the following SQL

```sql
DELETE FROM articles where created < '2014-10-10'
```

### Inserting Rows

Rows can be inserted using the `insert()` method:

```php
$connection->insert(
'articles',
['title' => 'My Title', 'body' => 'Some paragraph', 'created' => new DateTime()],
['created' => 'datetime']
);
```

More complex updates, deletes and insert queries can be generated using the `Query` class.

## Query Builder

One of the goals of this library is allowing the generation of both simple and complex queries with
ease. The query builder can be accessed by getting a new instance of a query:

```php
$query = $connection->newQuery();
```

### Select

Adding fields to the `SELECT` clause:

```php
$query->select(['id', 'title', 'body']);

// Results in SELECT id AS pk, title AS aliased_title, body ...
$query->select(['pk' => 'id', 'aliased_title' => 'title', 'body']);

// Use a closure
$query->select(function ($query) {
return ['id', 'title', 'body'];
});
```

### Where Conditions

Generating conditions:

```php
// WHERE id = 1
$query->where(['id' => 1]);

// WHERE id > 2
$query->where(['id >' => 1]);

// WHERE id = 2
$query->where(['id >' => 1]);
```

As you can see you can use any operator by placing it with a space after the field name.
Adding multiple conditions is easy as well:

```php
$query->where(['id >' => 1])->andWhere(['title' => 'My Title']);

// Equivalent to
$query->where(['id >' => 1, 'title' => 'My title']);
```

It is possible to generate `OR` conditions as well

```php
$query->where(['id >' => 1])->orWhere(['title' => 'My Title']);

// Equivalent to
$query->where(['OR' => ['id >' => 1, 'title' => 'My title']]);
```

For even more complex conditions you can use closures and expression objects:

```php
$query->where(function ($exp) {
return $exp
->eq('author_id', 2)
->eq('published', true)
->notEq('spam', true)
->gt('view_count', 10);
});
```

Which results in:

```sql
SELECT * FROM articles
WHERE
author_id = 2
AND published = 1
AND spam != 1
AND view_count > 10
```

Combining expressions is also possible:

```php
$query->where(function ($exp) {
$orConditions = $exp->or_(['author_id' => 2])
->eq('author_id', 5);
return $exp
->not($orConditions)
->lte('view_count', 10);
});
```

That generates:

```sql
SELECT *
FROM articles
WHERE
NOT (author_id = 2 OR author_id = 5)
AND view_count <= 10
```

When using the expression objects you can use the following methods to create conditions:

* `eq()` Creates an equality condition.
* `notEq()` Create an inequality condition
* `like()` Create a condition using the LIKE operator.
* `notLike()` Create a negated LIKE condition.
* `in()` Create a condition using IN.
* `notIn()` Create a negated condition using IN.
* `gt()` Create a > condition.
* `gte()` Create a >= condition.
* `lt()` Create a < condition.
* `lte()` Create a <= condition.
* `isNull()` Create an IS NULL condition.
* `isNotNull()` Create a negated IS NULL condition.

### Aggregates and SQL Functions

```php
// Results in SELECT COUNT(*) count FROM ...
$query->select(['count' => $query->func()->count('*')]);
```

A number of commonly used functions can be created with the func() method:

* `sum()` Calculate a sum. The arguments will be treated as literal values.
* `avg()` Calculate an average. The arguments will be treated as literal values.
* `min()` Calculate the min of a column. The arguments will be treated as literal values.
* `max()` Calculate the max of a column. The arguments will be treated as literal values.
* `count()` Calculate the count. The arguments will be treated as literal values.
* `concat()` Concatenate two values together. The arguments are treated as bound parameters unless marked as literal.
* `coalesce()` Coalesce values. The arguments are treated as bound parameters unless marked as literal.
* `dateDiff()` Get the difference between two dates/times. The arguments are treated as bound parameters unless marked as literal.
* `now()` Take either ‘time’ or ‘date’ as an argument allowing you to get either the current time, or current date.

When providing arguments for SQL functions, there are two kinds of parameters you can use, literal arguments and bound parameters. Literal parameters allow you to reference columns or other SQL literals. Bound parameters can be used to safely add user data to SQL functions. For example:

```php
$concat = $query->func()->concat([
'title' => 'literal',
' NEW'
]);
$query->select(['title' => $concat]);
```

The above generates:

```sql
SELECT CONCAT(title, :c0) ...;
```

### Other SQL Clauses

Read of all other SQL clases that the builder is capable of generating in the [official API docs](http://api.cakephp.org/3.0/class-Cake.Database.Query.html)

### Getting Results out of a Query

Once you’ve made your query, you’ll want to retrieve rows from it. There are a few ways of doing this:

```php
// Iterate the query
foreach ($query as $row) {
// Do stuff.
}

// Get the statement and fetch all results
$results = $query->execute()->fetchAll('assoc');
```

0 comments on commit a2456ec

Please sign in to comment.