Skip to content

Commit

Permalink
Document new iterator capabilities
Browse files Browse the repository at this point in the history
  • Loading branch information
trasher committed Aug 6, 2018
1 parent 1af856e commit 56a559a
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 15 deletions.
86 changes: 85 additions & 1 deletion source/devapi/database/dbiterator.rst
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ Default operator is ``=``, but other operators can be used, by giving an array c
$DB->request('glpi_computers', ['name' => ['LIKE' , 'pc00%']]);
// => SELECT * FROM `glpi_computers` WHERE `name` LIKE 'pc00%'
Known operators are ``=``, ``<``, ``<=``, ``>``, ``>=``, ``LIKE``, ``REGEXP``, ``NOT LIKE``, ``NOT REGEX`` and ``&`` (BITWISE AND).
Known operators are ``=``, ``!=``, ``<``, ``<=``, ``>``, ``>=``, ``LIKE``, ``REGEXP``, ``NOT LIKE``, ``NOT REGEX``, ``&`` (BITWISE AND), and ``|`` (BITWISE OR).

Aliases
+++++++
Expand Down Expand Up @@ -315,3 +315,87 @@ You can use some aggregation SQL functions on fields: ``COUNT``, ``SUM``, ``AVG`
$DB->request(['SELECT' => ['bar', 'SUM' => 'amount AS total'], 'FROM' => 'glpi_computers', 'GROUPBY' => 'amount']);
// => SELECT `bar`, SUM(`amount`) AS `total` FROM `glpi_computers` GROUP BY `amount`
Sub queries
+++++++++++

.. versionadded:: 9.3.1

You can use subqueries, using the specific `QuerySubQuery` class. It takes two arguments: the first is an array of criteria to get the query built, and the second is an optional operator to use. Allowed operators are the same than documented below plus `IN` and `NOT IN`. Default operator is `IN`.

.. code-block:: php
<?php
$sub_query = new \QuerySubQuery([
'SELECT' => 'id',
'FROM' => 'subtable',
'WHERE' => [
'subfield' => 'subvalue'
]
]);
$DB->request(['FROM' => 'glpi_computers', 'WHERE' => ['field' => $sub_query]]);
// => SELECT * FROM `glpi_computers` WHERE `field` IN (SELECT `id` FROM `subtable` WHERE `subfield` = 'subvalue')
$sub_query = new \QuerySubQuery([
'SELECT' => 'id',
'FROM' => 'subtable',
'WHERE' => [
'subfield' => 'subvalue'
]
], 'NOT IN');
$DB->request(['FROM' => 'glpi_computers', 'WHERE' => ['field' => $sub_query]]);
// => SELECT * FROM `glpi_computers` WHERE `field` NOT IN (SELECT `id` FROM `subtable` WHERE `subfield` = 'subvalue')
What if iterator does not provide what I'm looking for?
+++++++++++++++++++++++++++++++++++++++++++++++++++++++

Even if we do our best to get as many things as possible implemented in the iterator, there are several things that are missing... Consider for example you want to use the SQL `NOW()` function, or want to use a value based on another field: there is no native way to achieve that.

Right now, there is a `QueryExpression` class that would permit to do such things on values (an not on fields since it is not possible to use a class instance as an array key).

.. warning::

The `QueryExpression` class will pass raw SQL. You are in charge to escape name and values you use into it!

For example, to use the SQL `NOW()` function:

.. code-block:: php
<?php
$DB->request([
'FROM' => 'my_table',
'WHERE' => [
'date_end' => ['>', new \QueryExpression('NOW()')]
]
]);
// SELECT * FROM `my_table` WHERE `date_end` > NOW()
Another example with a field value:

.. code-block:: php
<?php
$DB->request([
'FROM' => 'my_table',
'WHERE' => [
'field' => new \QueryExpression(DBmysql::quoteName('other_field'))
]
]);
// SELECT * FROM `my_table` WHERE `field` = `other_field`
.. versionadded:: 9.3.1

You can also use some function or non supported stuff on field part by using a `RAW` entry in the query:

.. code-block:: php
<?php
$DB->request([
'FROM' => 'my_table',
'WHERE' => [
'RAW' => [
'LOWER(' . DBmysql::quoteName('field') . ')' => strtolower('Value')
]
]
]);
// SELECT * FROM `my_table` WHERE LOWER(`field`) = 'value'
30 changes: 16 additions & 14 deletions source/devapi/database/dbupdate.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,6 @@ Updating

Just as SQL `SELECT` queries, you should avoid plain SQL and use methods provided by the famework from the `DB object <https://forge.glpi-project.org/apidoc/class-DBmysql.html>`_.

.. note::

To make a database query that could not be done using recommanded way (calling SQL functions such as ``NOW()``, ``ADD_DATE()``, ... for example), you can do:

.. code-block:: php
<?php
$DB->query('UPDATE glpi_users SET date_mod = NOW()');
Just like :doc:`querying database <dbiterator>`; you will have to rely on plain SQL when using not supported features, like SQL functions.

General
^^^^^^^

Expand Down Expand Up @@ -63,9 +52,22 @@ You can update rows in the database using the `update() method <https://forge.gl
An `updateOrDie() method <https://forge.glpi-project.org/apidoc/class-DBmysql.html#_updateOrDie>`_ is also provided.

.. note::
.. versionadded:: 9.3.1

When issuing an `UPDATE` query, you can use an `ORDER` and/or a `LIMIT` clause along with the where (which remains **mandatory**). In order to achieve that, use an indexed array with appropriate keys:

The ``update()`` method does not currently support using another field in set. You will therefore have to run queries like ``UPDATE glpi_my_table` SET `ranking` = ranking+1`` using the legacy way.
.. code-block:: php
<?php
$DB->update(
'my_table', [
'my_field' => 'my value'
], [
'WHERE' => ['field' => 'value'],
'ORDER' => ['date DESC', 'id ASC'],
'LIMIT' => 1
]
);
Removing a row
^^^^^^^^^^^^^^
Expand Down Expand Up @@ -111,7 +113,7 @@ Let's see an example with an insert statement:
$stmt->execute();
}
Just like the `buildInsert()` method used here, `buildInsert` and `buildDelete` methods are available. They take exactly the same arguments as non build methods.
Just like the `buildInsert()` method used here, `buildUpdate` and `buildDelete` methods are available. They take exactly the same arguments as "non build" methods.

.. note::

Expand Down

0 comments on commit 56a559a

Please sign in to comment.