Did you find something wrong?
Be sure to let us know about it with an
issue.
Thank you!
Database Extra
Aplus Framework Database Extra Library.
Installation
The installation of this library can be done with Composer:
composer require aplus/database-extra
Introduction
The Database Extra library provides tools for working with database migrations and seeding.
Migrations
Migrations works like a database versioning.
With them, you can manage schemas and tables. Up and down for a given version.
The migration files are according to the template below:
use Framework\Database\Extra\Migration;
return new class() extends Migration
{
public function up() : void
{
//
}
public function down() : void
{
//
}
};
In the up
method, the creation and modification of schemas and tables must be
performed.
While in the down
method, the opposite way is carried out, undoing the
modifications carried out in the up method.
The file names must follow an order, in which the migrations will go up and down.
You can use the date and time as a prefix and a brief description. For example:
2022_05_26_213000_create_table_users.php
Another way is simply numbering the start of the migration file. For example:
100_create_table_users.php
The important thing is that each migration system has its own standard.
In the examples that we will see, we will use a number as a prefix and a brief description.
Inside the migration directory, we create the 100_create_table_users.php
file:
migrations/100createtableusers.php
use Framework\Database\Definition\Table\TableDefinition;
use Framework\Database\Extra\Migration;
return new class() extends Migration
{
protected string $table = 'Users';
public function up() : void
{
$this->getDatabase()->createTable($this->table)
->definition(function (TableDefinition $def) {
$def->column('id')->int()->primaryKey()->autoIncrement();
$def->column('name')->varchar(32);
$def->column('birthday')->date();
})->run();
}
public function down() : void
{
$this->getDatabase()->dropTable($this->table)->ifExists()->run();
}
};
This file creates the Users table in the up
method and drop it in the down
method.
The file below creates the Posts table, which will run after 100createtableusers, due to it starting with the number 200.
migrations/200createtableposts.php
use Framework\Database\Definition\Table\TableDefinition;
use Framework\Database\Extra\Migration;
return new class() extends Migration
{
protected string $table = 'Posts';
public function up() : void
{
$this->getDatabase()->createTable($this->table)
->definition(function (TableDefinition $def) {
$def->column('id')->int()->primaryKey()->autoIncrement();
$def->column('userId')->int()->null();
$def->column('title')->varchar(128);
$def->column('contents')->text();
$def->column('createdAt')->timestamp();
$def->index()
->foreignKey('userId')
->references('Users', 'id')
->onDelete('SET NULL')
->onUpdate('CASCADE');
})->run();
}
public function down() : void
{
$this->getDatabase()->dropTable($this->table)->ifExists()->run();
}
};
In the next example, let's change the Users table, adding two columns to it on the way up and removing them on the way down:
migrations/300altertableusers.php
use Framework\Database\Definition\Table\TableDefinition;
use Framework\Database\Extra\Migration;
return new class() extends Migration
{
protected string $table = 'Users';
public function up() : void
{
$this->getDatabase()->alterTable($this->table)
->add(function (TableDefinition $def) {
$def->column('email')->varchar(255)->after('id');
$def->column('password')->varchar(255);
})->run();
}
public function down() : void
{
$this->getDatabase()->alterTable($this->table)
->dropColumnIfExists('email')
->dropColumnIfExists('password')
->run();
}
};
The files must return an instance of the Framework\Database\Extra\Migration
class to run in a Migrator.
Migrator
Migrations are performed in a Migrator instance.
To instantiate it, you need a Database instance and at least one directory where the migrations are stored.
use Framework\Database\Database;
use Framework\Database\Extra\Migrator;
$database = new Database('root', 'password', 'app');
$directories = [
__DIR__ . '/migrations',
];
$migrator = new Migrator($database, $directories);
Once this is done, you can move the versioning of the migrations.
Migrate Up
The migrateUp
method runs migrations up.
Each time it runs the migration up method, it gives the migration name:
foreach($migrator->migrateUp() as $name) {
echo $name . PHP_EOL;
}
Migrate Down
It is also possible to go down to undo all migrations:
foreach($migrator->migrateDown() as $name) {
echo $name . PHP_EOL;
}
Or, go down only a specific amount, as in the example below, going down only 3 migrations.
foreach($migrator->migrateDown(3) as $name) {
echo $name . PHP_EOL;
}
Migrate To
With the migrateTo
method you can automatically move to a certain version.
It will go up or down migrations according to the current version.
foreach($migrator->migrateTo('2022_05_26_123000') as $name) {
echo $name . PHP_EOL;
}
Seeding
Seeding is a way of inserting data into database tables for testing purposes.
A Seeder is the class for performing this task.
They must extend the Framework\Database\Extra\Seeder
class and perform data
insertion in the run
method:
use Framework\Database\Extra\Seeder;
class SeederName extends Seeder
{
public function run() : void
{
//
}
}
Let's look at an example for inserting data into the Users table:
UsersSeeder.php
use Framework\Database\Extra\Seeder;
class UsersSeeder extends Seeder
{
public function run() : void
{
$this->getDatabase()->insert('Users')
->columns('name', 'birthday', 'email', 'password')
->values([
[
'Seiya',
'2009-12-01',
'[email protected]',
password_hash('password', PASSWORD_DEFAULT),
],
[
'Shiryu',
'2008-10-04',
'[email protected]',
password_hash('password', PASSWORD_DEFAULT),
],
[
'Hyoga',
'2008-01-23',
'[email protected]',
password_hash('password', PASSWORD_DEFAULT),
],
[
'Shun',
'2009-09-09',
'[email protected]',
password_hash('password', PASSWORD_DEFAULT),
],
[
'Ikki',
'2007-08-15',
'[email protected]',
password_hash('password', PASSWORD_DEFAULT),
],
])->run();
}
}
Each seeder can be executed individually, but all the seeders that will be called can be defined in a class.
Let's see an example with the DatabaseSeeder.php file, which uses the call
method to call and run other seeders:
use Framework\Database\Extra\Seeder;
class DatabaseSeeder extends Seeder
{
public function run() : void
{
$this->call([
UsersSeeder::class,
PostsSeeder::class,
]);
}
}
Once this is done, just run the main seeder, which will call all the others to run:
use Framework\Database\Database;
$database = new Database('root', 'password', 'app');
$seeder = new DatabaseSeeder($database);
$seeder->run();
Conclusion
Aplus Database Extra Library is an easy-to-use tool for PHP developers, beginners and experienced.
It is perfect for managing databases with versioning and tests with fake data.
The more you use it, the more you will learn.