Database

    Note To map your application data to database tables in a comfortable way, the recommended way is the Pagekit Object-relational mapper (ORM) which is described in its own chapter.

    Database credentials are stored in . Pagekit supports mysqland sqlite.

    Working with database prefixes

    All table names include the prefix of your Pagekit installation. To dynamically address tables in the backend, use the table name with the @ symbol as a placeholder for the prefix. As a convention you should start the table name with your extension name, e.g. options table for the foobar extension: @foobar_option

    Database utility

    You can manage your database schema using the database service utility (see the following examples).

    1. $util = $this['db']->getUtility();
    1. if ($util->tablesExist(['@table1', '@table2'])) {
    2. // tables exists
    3. }

    Create table

    Use Utility::createTable($table, \Closure $callback) to create a table, the first parameter passed to the callback will be a Doctrine\DBAL\Schema\Table instance.

    1. $util->createTable('@foobar_option', function($table) {
    2. $table->addColumn('name', 'string', ['length' => 64, 'default' => '']);
    3. $table->addColumn('value', 'text');
    4. $table->addColumn('autoload', 'boolean', ['default' => false]);
    5. $table->setPrimaryKey(['id']);
    6. $table->addUniqueIndex(['name'], 'OPTION_NAME');
    7. });

    The $table object is an instance of \Doctrine\DBAL\Schema\Table. You can find its class reference in the official Doctrine documentation.

    When creating a column using addColumn, you might want to look at the available and the availabe column options from the Doctrine documentation as well.

    Creating a table is commonly done in the install hook of the scripts.php inside your extension. Read more about in the next section.

    Migrations

    1. "extra": {
    2. "scripts": "scripts.php"
    3. },

    Within the scripts.php, you can hook into different events of the extension lifecycle.

    To alter an existing table, use the existing tools of the underlying Doctrine DBAL. To add columns to an existing table, you can include the following snippets in one of the updates version hooks of your extension's scripts.php.

    1. use Doctrine\DBAL\Schema\Comparator;
    2. // ...
    3. $util = App::db()->getUtility();
    4. $manager = $util->getSchemaManager();
    5. if ($util->tableExists('@my_table')) {
    6. $tableOld = $util->getTable('@my_table');
    7. $table = clone $tableOld;
    8. $table->addColumn('title', 'string', ['length' => 255]);
    9. $comparator = new Comparator;
    10. $manager->alterTable($comparator->diffTable($tableOld, $table));

    The $table object is an instance of \Doctrine\DBAL\Schema\Table. You can find its in the official Doctrine documentation.

    There are several ways of accessing the database. Pagekit offers an abstracting on the underlying MySQL or SQLite, so there is no need to use PDO or similar mechanisms.

    The QueryBuilder allows for a more comfortable way of creating queries.

    Example:

    1. $result = Application::db()->createQueryBuilder()->select('*')->from('@blog_post')->where('id = :id', ['id' => 1])->execute()->fetchAll();

    Get a query builder object

    1. use Pagekit\Application;
    2. // ...
    3. $query = Application::db()->createQueryBuilder();

    Basic selects and conditions

    MethodDescription
    select($columns = ['*'])Creates and adds a "select" to the query.
    from($table)Creates and sets a "from" to the query.
    where($condition, array $params = [])Creates and adds a "where" to the query.
    orWhere($condition, array $params = [])Creates and adds a "or where" to the query.

    Example:

    1. // create query
    2. $query = Application::db()->createQueryBuilder();
    3. // fetch title and content of all blog posts that do not have any comments
    4. $comments = $query
    5. ->select(['title', 'content'])
    6. ->from('@blog_post')
    7. ->where('comment_count = ?', [0])
    8. ->get();

    Query execution

    Aggregate functions

    MethodDescription
    min($column)Execute the query and get the "min" result.
    max($column)Execute the query and get the "max" result.
    sum($column)Execute the query and get the "sum" result.
    avg($column)Execute the query and get the "avg" result.

    Example:

    Advanced query methods

    Joins

    MethodDescription
    join($table, $condition = null, $type = 'inner')Creates and adds a "join" to the query.
    innerJoin($table, $condition = null)Creates and adds an "inner join" to the query.
    leftJoin($table, $condition = null)leftJoin($table, $condition = null)
    rightJoin($table, $condition = null)Creates and adds a "right join" to the query.

    Example:

    1. $result = Role::where(['id <> ?'], [Role::ROLE_ANONYMOUS])->orderBy('priority')->get();

    The following methods are available (defined in the ).

    ORM Query Builder: Additional methods

    MethodDescription
    get()Executes the query and gets all results.
    first()Executes the query and gets the first result.
    related($related)Set the relations that will be eager loaded.
    getRelations()Gets all relations of the query.
    getNestedRelations($relation)Gets all nested relations of the query.

    Example:

    1. $comments = Comment::query()->related(['post' => function ($query) {
    2. return $query->related('comments');
    3. }])->get();

    The plainest way to query the database is by sending raw queries to the database. This is basically just a wrapper around PDO.

    1. $result = Application::db()->executeQuery('select * from @blog_post')->fetchAll();
    2. $result = Application::db()->executeQuery('select * from @blog_post WHERE id = :id', ['id' => 1])->fetchAll();

    Insert

    Inserting data in the database can be done using the database connection instance that you can fetch via Application::db() (remember to use Pagekit\Application; at the top of your file).

    Use the method insert($tableExpression, array $data, array $types = array())

    Example:

    1. Application::db()->insert('@system_page', [
    2. 'title' => 'Home',
    3. 'content' => "<p>Hello World</p>",
    4. ]);

    When using ORM, you just need to create a new model instance and call the save() method.

    ORM