Scaffold/Scaffold — pull request #125 by nathggns (2013-05-31 20:04:12+00:00)
Title: Add function support

These commits add SQL function support across Scaffold's database system.

# Changelog

This pull request added the following two classes.

- `DatabaseQueryBuilderFunction`
- Base class for generating strings for functions in Scaffold. Has a method for each of the languages Scaffold supports, currently only SQL, and has a map of fallbacks (`SQLite => 'SQL`).
- `DatabaseQueryBuilderFunctionRandom`
- An example of a function that doesn't use it's name (`random`) to generate the string. Instead, it returns a custom string `RAND`. We'll probably need to add a lot more of these.

It adds the following service

- `database.query.builder.function`
- Checks if a custom class exists for this function, and returns an instance of that custom class, or the base `DatabaseQueryBuilderFunction` class.

`Database::__construct` has been modified to not need an instance of Config passed to it if it has been initiated before.

`Dynamic` has been modified to support being an alias for a class method. Simply pass the same array you'd pass to `call_user_func`

The following methods have been added

- `Database::func_*`
- This creates the object that is recognised as a function across the system. The object has only one method, `as`, which allows you to alias the function (generating SQL strings like `SELECT COUNT(*) AS `count` FROM ...`)
- `DatabaseQueryBuilder::val`
- This is a chained helper for the `vals` section of `query_opts` for SELECT statements.
- `DatabaseQueryBuilder::is_func`
- Tests if a value is a valid function object.
- `DatabaseQueryBuilder::func`
- Converts a function object to the string required.
- `ModelDatabase::value`
- `__get` is now an alias for this. We can now pass function objects to it. Results of functions will never be cached.
- `ModelDatabase::alias`
- Alias properties. Allows you to call functions using properties.

The following bugs have been fixed

- `Database::__callStatic` successfully passes unknown functions through to the driver.