Skip to content
This repository has been archived by the owner on May 24, 2022. It is now read-only.

Commit

Permalink
Merge branch 'release/0.8.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
ihabunek committed May 7, 2015
2 parents dfbe046 + efda63d commit b8de3df
Show file tree
Hide file tree
Showing 19 changed files with 431 additions and 136 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
Phormium Changelog
==================

0.8.0 / 2015-05-07
------------------

* Added database attributes to configuration
* **BC BREAK**: Phormium will no longer force lowercase column names on
database tables. This can still be done manually by setting the
`PDO::ATTR_CASE:` attribute to `PDO::CASE_LOWER` in the configuration.

0.7.0 / 2014-12-05
------------------
Expand Down
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 changes: 5 additions & 23 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,28 +48,10 @@ It would return something like:
]
```

Raw filters
-----------
Enable custom FK guessers
-------------------------

Implement raw filters for user to write manually, instead of using existing
ones. Some examples:

Can have literals left of the operator:

```
$qs->rawFilter("1=1");
```

Arguments passed to perform a prepared query:

```
$qs->rawFilter("column = :value", ['value' => 3]);
```

Can use functions and operators:

```
$qs->rawFilter("column = :value * 2", ['value' => 3]);
$qs->rawFilter("lower(column) like lower(:value)", ['value' => "FOO"]);
```
Enable setting a custom ModelRelationsTrait::guessForeignKey() function.

This will enable custome db naming schemas to be guessed by phormium, instead
of having to be set manually.
15 changes: 10 additions & 5 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
# serve to show the default.

import sys, os
import sphinx_rtd_theme

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
Expand Down Expand Up @@ -56,16 +57,16 @@

# General information about the project.
project = u'Phormium'
copyright = u'2014, Ivan Habunek'
copyright = u'2015, Ivan Habunek'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '0.7.0'
version = '0.8.0'
# The full version, including alpha/beta/rc tags.
release = '0.7.0'
release = '0.8.0'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down Expand Up @@ -109,15 +110,15 @@

# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'default'
html_theme = 'sphinx_rtd_theme'

# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}

# Add any paths that contain custom themes here, relative to this directory.
# html_theme_path = ['_themes']
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]

# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
Expand All @@ -140,6 +141,10 @@
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']

# Additional CSS
def setup(app):
app.add_stylesheet("theme_overrides.css")

# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
Expand Down
127 changes: 87 additions & 40 deletions docs/configure.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,59 +2,51 @@
Configuration
=============

Phormium uses a configuration file to configure databases to which to connect.
JSON and YAML notations are natively supported.
Phormium uses a configuration array to configure the databases to which to
connect. JSON and YAML files are also supported. To configure Phormium, pass the
configuration array, or a path to the configuration file to
``Phormium\DB::configure()``.

The configuration comprises of the following options:
The configuration array comprises of the following options:

`databases`
One or more databases to which you wish to connect. Indexed by a database
name (here `mydb1` and `mydb2`) which will be used later in the model to
determine in which database the table is located. Each database should
contain the DSN (see PDO_ for details). Username and password are optional.
Configuration for one or more databases to which you wish to connect,
indexed by a database name which is used in the model to determine in which
database the table is located.

.. _PDO: http://www.php.net/manual/en/pdo.construct.php
Databases
---------

Each entry in ``databases`` has the following configuration options:

JSON example:
`dsn`
The Data Source Name, or DSN, contains the information required to connect
to the database. See `PDO documentation`_ for more information.

.. code-block:: javascript
{
"databases": {
"mydb1": {
"dsn": "mysql:host=localhost;dbname=db1",
"username": "myuser",
"password": "mypass"
},
"mydb2": {
"dsn": "sqlite:/path/to/db2.sqlite"
}
}
}
`username`
The username used to connect to the database.

YAML example:
`password`
The username used to connect to the database.

.. code-block:: yaml
`attributes`
Associative array of PDO attributes with corresponding values to be set on
the PDO connection after it has been created.

databases:
mydb1:
dsn: mysql:host=localhost;dbname=db1
username: myuser
password: mypass
mydb2:
dsn: sqlite:/path/to/db2.sqlite
When using a configuration array PDO constants can be used directly
(e.g. ``PDO::ATTR_CASE``), whereas when using a config file, the constant
can be given as a string (e.g. ``"PDO::ATTR_CASE"``) instead.

To configure Phormium, pass the path to the configuration file to the configure
method.
For available attributes see the `PDO attributes`_ documentation.

.. code-block:: php
.. _PDO documentation: http://www.php.net/manual/en/pdo.construct.php
.. _PDO attributes: http://php.net/manual/en/pdo.setattribute.php

Phormium\DB::configure('/path/to/config.json');
Phormium\DB::configure('/path/to/config.yaml');
Examples
--------

Alternatively, you can configure Phormium using an array instead of a
configuration file:
PHP example
~~~~~~~~~~~

.. code-block:: php
Expand All @@ -63,7 +55,11 @@ configuration file:
"db1" => [
"dsn" => "mysql:host=localhost;dbname=db1",
"username" => "myuser",
"password" => "mypass"
"password" => "mypass",
"attributes" => [
PDO::ATTR_CASE => PDO::CASE_LOWER,
PDO::ATTR_STRINGIFY_FETCHES => true
]
],
"db2" => [
"dsn" => "sqlite:/path/to/db2.sqlite"
Expand All @@ -72,3 +68,54 @@ configuration file:
]);
.. note:: Short array syntax `[ ... ]` requires PHP 5.4+.

JSON example
~~~~~~~~~~~~

This is the equivalent configuration in JSON.

.. code-block:: javascript
{
"databases": {
"db1": {
"dsn": "mysql:host=localhost;dbname=db1",
"username": "myuser",
"password": "mypass",
"attributes": {
"PDO::ATTR_CASE": "PDO::CASE_LOWER",
"PDO::ATTR_STRINGIFY_FETCHES": true
}
},
"db2": {
"dsn": "sqlite:\/path\/to\/db2.sqlite"
}
}
}
.. code-block:: php
Phormium\DB::configure('/path/to/config.json');
YAML example
~~~~~~~~~~~~

This is the equivalent configuration in YAML.

.. code-block:: yaml
databases:
db1:
dsn: 'mysql:host=localhost;dbname=db1'
username: myuser
password: mypass
attributes:
'PDO::ATTR_CASE': 'PDO::CASE_LOWER'
'PDO::ATTR_STRINGIFY_FETCHES': true
db2:
dsn: 'sqlite:/path/to/db2.sqlite'
.. code-block:: php
Phormium\DB::configure('/path/to/config.yaml');
2 changes: 2 additions & 0 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Sphinx>=1.2.2
sphinx_rtd_theme
84 changes: 78 additions & 6 deletions src/Phormium/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

namespace Phormium;

use PDO;

use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\Processor;
use Symfony\Component\Config\Exception\FileLoaderLoadException;
Expand Down Expand Up @@ -43,9 +41,11 @@ public static function getDatabase($name)
return self::$config['databases'][$name];
}

public static function addDatabase($name, $dsn, $username = null, $password = null)
public static function addDatabase($name, $dsn, $username = null, $password = null, array $attributes = [])
{
self::$config['databases'][$name] = compact('dsn', 'username', 'password');
$attributes = self::processAttributes($name, $attributes);

self::$config['databases'][$name] = compact('dsn', 'username', 'password', 'attributes');
}

/** Load configuration from array or file. */
Expand All @@ -68,14 +68,80 @@ public static function load($config)

$processor = new Processor();
$tree = self::getConfigTreeBuilder()->buildTree();
self::$config = $processor->process($tree, array($config));
$config = $processor->process($tree, array($config));
self::$config = self::processConfig($config);
}

/**
* Process and validate a configuration array.
*/
private static function processConfig(array $config)
{
foreach ($config['databases'] as $name => $dbConfig) {
$config['databases'][$name] = self::processDbConfig($name, $dbConfig);
}

return $config;
}

private static function processDbConfig($name, $config)
{
$config['attributes'] = self::processAttributes($name, $config['attributes']);

return $config;
}

private static function processAttributes($dbName, $attributes)
{
$processed = [];

foreach ($attributes as $name => $value) {
try {
$procName = self::processConstant($name, false);
} catch (\Exception $ex) {
throw new \Exception("Invalid attribute \"$name\" specified in configuration for database \"$dbName\".");
}

try {
$procValue = self::processConstant($value, true);
} catch (\Exception $ex) {
throw new \Exception("Invalid value \"$value\" given for attribute \"$name\", in configuration for database \"$dbName\".");
}

$processed[$procName] = $procValue;
}

return $processed;
}

private static function processConstant($value, $allowScalar = false)
{
// If the value is an integer, assume it's a PDO::* constant value
// and leave it as-is
if (is_integer($value)) {
return $value;
}

// If it's a string which starts with "PDO::", try to find the
// corresponding PDO constant
if (is_string($value) && substr($value, 0, 5) === 'PDO::' && defined($value)) {
return constant($value);
}

if ($allowScalar && is_scalar($value)) {
return $value;
}

throw new \Exception("Invalid constant value");
}

private static function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();

$rootNode = $treeBuilder->root('phormium')
$rootNode = $treeBuilder->root('phormium');

$rootNode
->children()
->arrayNode('databases')
->prototype('array')
Expand All @@ -89,6 +155,12 @@ private static function getConfigTreeBuilder()
->scalarNode('password')
->defaultNull()
->end()
->arrayNode('attributes')
->useAttributeAsKey('name')
->prototype('scalar')
->isRequired()
->end()
->end()
->end()
->end()
->end()
Expand Down
Loading

0 comments on commit b8de3df

Please sign in to comment.