PHP code example of tobento / service-database

1. Go to this page and download the library: Download tobento/service-database library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

tobento / service-database example snippets


use Tobento\Service\Database\Databases;
use Tobento\Service\Database\DatabasesInterface;

$databases = new Databases();

var_dump($databases instanceof DatabasesInterface);
// bool(true)

use Tobento\Service\Database\Databases;
use Tobento\Service\Database\PdoDatabase;
use Tobento\Service\Database\DatabaseInterface;
use PDO;

$databases = new Databases();

$database = new PdoDatabase(
    pdo: new PDO('sqlite::memory:'),
    name: 'name',
);

var_dump($database instanceof DatabaseInterface);
// bool(true)

$databases->add($database);

use Tobento\Service\Database\Databases;
use Tobento\Service\Database\PdoDatabase;
use Tobento\Service\Database\DatabaseInterface;
use PDO;

$databases = new Databases();

$databases->register(
    'name',
    function(string $name): DatabaseInterface {        
        return new PdoDatabase(
            new PDO('sqlite::memory:'),
            $name
        );
    }
);

use Tobento\Service\Database\DatabaseInterface;
use Tobento\Service\Database\DatabaseException;

$database = $databases->get('name');

var_dump($database instanceof DatabaseInterface);
// bool(true)

$databases->get('unknown');
// throws DatabaseException

var_dump($databases->has('name'));
// bool(false)

use Tobento\Service\Database\Databases;
use Tobento\Service\Database\PdoDatabase;
use Tobento\Service\Database\DatabaseInterface;
use Tobento\Service\Database\DatabaseException;
use PDO;

$databases = new Databases();

$databases->add(
    new PdoDatabase(new PDO('sqlite::memory:'), 'sqlite')
);

// add default
$databases->addDefault(name: 'primary', database: 'sqlite');

// get default database for the specified name.
$primaryDatabase = $databases->default('primary');

var_dump($primaryDatabase instanceof DatabaseInterface);
// bool(true)

var_dump($databases->hasDefault('primary'));
// bool(true)

var_dump($databases->getDefaults());
// array(1) { ["primary"]=> string(6) "sqlite" }

$databases->default('unknown');
// throws DatabaseException

use Tobento\Service\Database\PdoDatabase;
use Tobento\Service\Database\DatabaseInterface;
use Tobento\Service\Database\PdoDatabaseInterface;
use PDO;

$database = new PdoDatabase(
    pdo: new PDO('sqlite::memory:'),
    name: 'sqlite',
);

var_dump($database instanceof DatabaseInterface);
// bool(true)

var_dump($database instanceof PdoDatabaseInterface);
// bool(true)

use Tobento\Service\Database\PdoDatabaseFactory;
use Tobento\Service\Database\DatabaseFactoryInterface;
use Tobento\Service\Database\PdoDatabaseInterface;
use Tobento\Service\Database\DatabaseInterface;
use Tobento\Service\Database\DatabaseException;
use PDO;

$factory = new PdoDatabaseFactory();

var_dump($factory instanceof DatabaseFactoryInterface);
// bool(true)

$database = $factory->createDatabase(
    name: 'mysql',
    config: [
        'driver' => 'mysql',
        'host' => 'localhost',
        'port' => null,
        'database' => 'db_name',
        'charset' => 'utf8mb4',
        'username' => 'root',
        'password' => '',
        'options' => [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_EMULATE_PREPARES => false,
        ],
    ],
);
// throws DatabaseException on failure

var_dump($database instanceof PdoDatabaseInterface);
// bool(true)

var_dump($database instanceof DatabaseInterface);
// bool(true)

// with dsn parameter
$database = $factory->createDatabase(
    name: 'sqlite',
    config: [
        'dsn' => 'sqlite::memory:',
        'username' => '',
        'password' => '',
        'options' => [],
    ],
);

use Tobento\Service\Database\PdoDatabaseFactory;
use Tobento\Service\Database\PdoFactoryInterface;
use Tobento\Service\Database\DatabaseException;
use PDO;

$factory = new PdoDatabaseFactory();

var_dump($factory instanceof PdoFactoryInterface);
// bool(true)

$pdo = $factory->createPdo(
    name: 'sqlite',
    config: [
        'dsn' => 'sqlite::memory:',
        'username' => '',
        'password' => '',
        'options' => [],
    ],
);
// throws DatabaseException on failure

var_dump($pdo instanceof PDO);
// bool(true)

use PDOStatement;

$statement = $database->execute(
    statement: 'ALTER TABLE products ADD color varchar(60)'
);

var_dump($statement instanceof PDOStatement);
// bool(true)

$products = $database->execute(
    statement: 'SELECT title FROM products WHERE color = ?',
    bindings: ['blue']
)->fetchAll();

// with named parameters, order free
$products = $database->execute(
    'SELECT title FROM products WHERE color = :color',
    ['color' => 'blue']
)->fetchAll();

$database->execute(
    statement: 'INSERT INTO shop_products (name, color) VALUES (?, ?)',
    bindings: ['Shirt', 'blue'],
);

// you might return the number of rows affected:
$rowsAffected = $database->execute(
    'INSERT INTO shop_products (name, color) VALUES (?, ?)',
    ['Shirt', 'blue']
)->rowCount();

var_dump($rowsAffected);
// int(1)

$rowsAffected = $database->execute(
    statement: 'UPDATE products SET name = ? WHERE color = ?',
    bindings: ['Shirt', 'blue']
)->rowCount();

var_dump($rowsAffected);
// int(2)

$rowsAffected = $database->execute(
    statement: 'DELETE FROM shop_products WHERE color = ?',
    bindings: ['blue']
)->rowCount();

var_dump($rowsAffected);
// int(2)

use Tobento\Service\Database\PdoDatabaseInterface;

$database->transaction(function(PdoDatabaseInterface $db): void {

    $db->execute(
        'UPDATE products SET active = ? WHERE color = ?',
        [true, 'red']
    );
    
    $db->execute(
        'UPDATE products SET active = ? WHERE color = ?',
        [false, 'bar']
    );    
});

$database->begin();

// your queries

$database->commit();

$database->begin();

// your queries

$database->rollback();

var_dump($database->supportsNestedTransactions());
// bool(true)

use PDO;

var_dump($database->pdo() instanceof PDO);
// bool(true)

use Tobento\Service\Database\Schema\Table;

$table = new Table(name: 'products');
$table->primary('id');
$table->string('name', 100)->nullable(false)->default('');
$table->bool('active', true);

$table->string('name')->length(21);

$table->string('name')->nullable(false);

$table->bool('name')->default(true);

$table->int('name')->unsigned(true);

$table->renameColumn('column', 'new_column');

$table->dropColumn('column');

$table->renameTable('new_name');

$table->dropTable();

$table->truncate();

$table->string('column')->parameter('charset', 'utf8mb4');

$table->string('column')->parameter('collation', 'utf8mb4_roman_ci');

$table->index('index_name')->column('name');

$table->index('index_name')->column('name', 'another_name');

$table->index('index_name')->column('name')->unique();

$table->index('index_name')->column('name', 'another_name')->unique();

$table->index()->column('name')->primary();

$table->index('index_name')->rename('new_name');

$table->index('index_name')->drop();

use Tobento\Service\Database\Schema\ItemsInterface;

$items = $table->items(iterable: [
    ['name' => 'Foo', 'active' => true],
    ['name' => 'Bar', 'active' => true],
    // ...
])
->chunk(length: 100)
->useTransaction(false) // default is true
->forceInsert(true); // default is false

var_dump($items instanceof ItemsInterface);
// bool(true)

use Tobento\Service\Iterable\ItemFactoryIterator;
use Tobento\Service\Seeder\Str;
use Tobento\Service\Seeder\Arr;

$table->items(new ItemFactoryIterator(
    factory: function(): array {
        return [
            'name' => Str::string(10),
            'color' => Arr::item(['green', 'red', 'blue']),
        ];
    },
    create: 1000000 // create 1 million items
))
->chunk(length: 10000)
->useTransaction(false) // default is true
->forceInsert(true); // default is false

use Tobento\Service\Iterable\JsonFileIterator;
use Tobento\Service\Iterable\ModifyIterator;

$iterator = new JsonFileIterator(
    file: 'private/src/countries.json',
);

// you may use the modify iterator:
$iterator = new ModifyIterator(
    iterable: $iterator,
    modifier: function(array $item): array {
        return [
          'iso' => $item['iso'] ?? '',
          'name' => $item['country'] ?? '',
        ];
    }
);
        
$table->items($iterator)
      ->chunk(length: 100)
      ->useTransaction(true) // default is true
      ->forceInsert(false); // default is false

use Tobento\Service\Database\Schema\TableFactoryInterface;
use Tobento\Service\Database\Schema\TableFactory;
use Tobento\Service\Database\Schema\Table;

$tableFactory = new TableFactory();

var_dump($tableFactory instanceof TableFactoryInterface);
// bool(true)

$table = $tableFactory->createTable(name: 'users');

var_dump($table instanceof Table);
// bool(true)

use Tobento\Service\Database\Schema\ColumnFactoryInterface;
use Tobento\Service\Database\Schema\ColumnFactory;

$columnFactory = new ColumnFactory();

var_dump($columnFactory instanceof ColumnFactoryInterface);
// bool(true)

use Tobento\Service\Database\Schema\ColumnFactory;
use Tobento\Service\Database\Schema\ColumnInterface;
use Tobento\Service\Database\Schema\CreateColumnException;

try {
    $column = (new ColumnFactory())->createColumn(type: 'int', name: 'foo');
    
    var_dump($column instanceof ColumnInterface);
    // bool(true)
    
} catch(CreateColumnException $e) {
    //
}

use Tobento\Service\Database\Schema\ColumnFactory;
use Tobento\Service\Database\Schema\ColumnInterface;
use Tobento\Service\Database\Schema\CreateColumnException;

try {
    $column = (new ColumnFactory())->createColumnFromArray([
        'type' => 'int',
        'name' => 'foo',
    ]);
    
    var_dump($column instanceof ColumnInterface);
    // bool(true)
    
} catch(CreateColumnException $e) {
    //
}

use Tobento\Service\Database\Schema\ColumnFactory;

$column = (new ColumnFactory())->createColumnFromArray([
    'type' => 'int',
    'name' => 'foo',
    
    'length' => 99,
    'nullable' => false,
    'default' => 'value',
    'unsigned' => true,
    
    'parameters' => [
        'charset' => 'utf8mb4',
        'collation' => 'utf8mb4_roman_ci',
    ],
    
    // Decimal column
    'precision' => 8,
    'scale' => 4,
]);

use Tobento\Service\Database\Schema\IndexFactoryInterface;
use Tobento\Service\Database\Schema\IndexFactory;

$indexFactory = new IndexFactory();

var_dump($indexFactory instanceof IndexFactoryInterface);
// bool(true)

use Tobento\Service\Database\Schema\IndexFactory;
use Tobento\Service\Database\Schema\IndexInterface;
use Tobento\Service\Database\Schema\CreateIndexException;

try {
    $index = (new IndexFactory())->createIndex(name: 'foo');
    
    var_dump($index instanceof IndexInterface);
    // bool(true)
    
} catch(CreateIndexException $e) {
    //
}

use Tobento\Service\Database\Schema\IndexFactory;
use Tobento\Service\Database\Schema\IndexInterface;
use Tobento\Service\Database\Schema\CreateIndexException;

try {
    $index = (new IndexFactory())->createIndexFromArray([
        'name' => 'foo',
    ]);
    
    var_dump($index instanceof IndexInterface);
    // bool(true)
    
} catch(CreateIndexException $e) {
    //
}

use Tobento\Service\Database\Schema\IndexFactory;

$index = (new IndexFactory())->createIndexFromArray([
    'name' => 'foo',
    
    'column' => 'name',
    // or multiple
    'column' => ['name', 'another_name'],
    
    'unique' => true,
    'primary' => true,
    
    'rename' => 'newname',
    'drop' => true,
]);

use Tobento\Service\Database\Processor\PdoMySqlProcessor;
use Tobento\Service\Database\Processor\ProcessorInterface;
use Tobento\Service\Database\Processor\ProcessException;
use Tobento\Service\Database\PdoDatabaseInterface;
use Tobento\Service\Database\Schema\Table;

$processor = new PdoMySqlProcessor();

var_dump($processor instanceof ProcessorInterface);
// bool(true)

try {
    $processor->process(
        $table, // Table
        $database // PdoDatabaseInterface
    );    
} catch (ProcessException $e) {
    // Handle exception.
}

use Tobento\Service\Database\Processor\PdoMySqlProcessor;

$processor = new PdoMySqlProcessor(new CustomStorage());

use Tobento\Service\Database\Processor\Processors;
use Tobento\Service\Database\Processor\PdoMySqlProcessor;
use Tobento\Service\Database\Processor\ProcessorInterface;
use Tobento\Service\Database\Processor\ProcessException;

$processors = new Processors(
    new PdoMySqlProcessor(),
);

var_dump($processor instanceof ProcessorInterface);
// bool(true)

try {
    $processors->process($table, $database);
} catch (ProcessException $e) {
    //
}

use Tobento\Service\Database\Processor\PdoMySqlStorage;
use Tobento\Service\Database\Processor\StorageInterface;
use Tobento\Service\Database\Processor\StorageFetchException;
use Tobento\Service\Database\PdoDatabaseInterface;
use Tobento\Service\Database\Schema\Table;

$storage = new PdoMySqlStorage();

var_dump($storage instanceof StorageInterface);
// bool(true)

try {
    $table = $storage->fetchTable(
        $database, // PdoDatabaseInterface
        'table_name'
    );
    
    var_dump($table instanceof Table);
    // bool(true) or NULL if table does not exist.

} catch (StorageFetchException $e) {
    // Handle exception.
}

use Tobento\Service\Database\Processor\PdoMySqlStorage;
use Tobento\Service\Database\Processor\StorageInterface;
use Tobento\Service\Database\Processor\StorageStoreException;
use Tobento\Service\Database\PdoDatabaseInterface;
use Tobento\Service\Database\Schema\Table;

$storage = new PdoMySqlStorage();

var_dump($storage instanceof StorageInterface);
// bool(true)

try {
    $storage->storeTable(
        $database, // PdoDatabaseInterface
        $table // Table
    );

} catch (StorageStoreException $e) {
    // Handle exception.
}

use Tobento\Service\Database\Processor\Storages;
use Tobento\Service\Database\Processor\PdoMySqlStorage;
use Tobento\Service\Database\Processor\StorageInterface;
use Tobento\Service\Database\Processor\StorageStoreException;

$storages = new Storages(
    new PdoMySqlStorage(),
);

var_dump($storages instanceof StorageInterface);
// bool(true)

try {
    $storages->storeTable($database, $table);
} catch (StorageStoreException $e) {
    // Handle exception.
}

use Tobento\Service\Database\Processor\PdoMySqlProcessor;
use Tobento\Service\Database\Processor\StorageInterface;
use Tobento\Service\Database\Processor\StorageFetchException;
use Tobento\Service\Database\Processor\StorageStoreException;
use Tobento\Service\Database\Processor\ProcessException;
use Tobento\Service\Database\Schema\Table;
use Tobento\Service\Database\DatabaseInterface;

class CustomStorage implements StorageInterface
{
    /**
     * Returns true if the processor supports the database, otherwise false.
     *
     * @param DatabaseInterface $database
     * @return bool
     */
    public function supportsDatabase(DatabaseInterface $database): bool
    {
        return true;
    }
    
    /**
     * Returns the specified table if exist, otherwise null.
     *
     * @param DatabaseInterface $database
     * @param string $name The table name
     * @return null|Table
     * @throws StorageFetchException
     */    
    public function fetchTable(DatabaseInterface $database, string $table): null|Table
    {
        // your logic.
        return null;
    }
    
    /**
     * Store the table.
     *
     * @param DatabaseInterface $database
     * @param string $name
     * @return void
     * @throws StorageStoreException
     */    
    public function storeTable(DatabaseInterface $database, Table $table): void
    {
        // your logic.
    }
}

try {
    $table = (new CustomStorage())->fetchTable($database, 'table_name');
} catch (ProcessException $e) {
    // Handle exception.
}

use Tobento\Service\Database\Migration\DatabaseMigration;
use Tobento\Service\Database\Schema\Table;

class DbMigrations extends DatabaseMigration
{
    public function description(): string
    {
        return 'db migrations';
    }

    /**
     * Register tables used by the install and uninstall methods
     * to create the actions from.
     *
     * @return void
     */
    protected function registerTables(): void
    {
        $this->registerTable(
            table: function(): Table {
                $table = new Table(name: 'users');
                $table->primary('id');
                return $table;
            },
            database: $this->databases->default('pdo'),
            name: 'Users',
            description: 'Users desc',
        );
        
        $this->registerTable(
            table: function(): Table {
                $table = new Table(name: 'products');
                $table->primary('id');
                return $table;
            },
            database: $this->databases->default('pdo'),
        );
    }
}

use Tobento\Service\Database\Migration\DatabaseMigration;
use Tobento\Service\Database\Migration\DatabaseAction;
use Tobento\Service\Database\Migration\DatabaseDeleteAction;
use Tobento\Service\Database\Schema\Table;
use Tobento\Service\Migration\ActionsInterface;
use Tobento\Service\Migration\Actions;

class DbMigrations extends DatabaseMigration
{
    public function description(): string
    {
        return 'db migrations';
    }

    /**
     * Return the actions to be processed on install.
     *
     * @return ActionsInterface
     */
    public function install(): ActionsInterface
    {
        return new Actions(
            new DatabaseAction(
                processor: $this->processor,
                database: $this->databases->default('pdo'),
                table: function(): Table {
                    $table = new Table(name: 'products');
                    $table->primary('id');
                    return $table;
                },
                name: 'Products',
                description: 'Products table installed',
            ),
        );
    }
    
    /**
     * Return the actions to be processed on uninstall.
     *
     * @return ActionsInterface
     */
    public function uninstall(): ActionsInterface
    {
        return $this->createDatabaseDeleteActionsFromInstall();
        
        // or manually:
        return new Actions(
            new DatabaseDeleteAction(
                processor: $this->processor,
                database: $this->databases->default('pdo'),
                table: new Table(name: 'products'),
                name: 'Products',
                description: 'Products table uninstalled',
            ),
        );
    }
}

use Tobento\Service\Database\Migration\DatabaseMigrationSeeder;
use Tobento\Service\Database\Schema\Table;
use Tobento\Service\Iterable\ItemFactoryIterator;

class DbMigrationsSeeder extends DatabaseMigrationSeeder
{
    public function description(): string
    {
        return 'db migrations seeding';
    }

    /**
     * Register tables used by the install method
     * to create the actions from.
     * The uninstall method returns empty actions.
     *
     * @return void
     */
    protected function registerTables(): void
    {
        $this->registerTable(
            table: function(): Table {
                $table = new Table(name: 'users');
                // no need to specifiy columns again
                // if you the table migrated before.
                
                // seeding:
                $table->items(new ItemFactoryIterator(
                    factory: function(): array {
                        return [
                            'name' => $this->seed->fullname(),
                            'email' => $this->seed->email(),
                        ];
                    },
                    create: 10000
                ))
                ->chunk(length: 2000)
                ->useTransaction(false) // default is true
                ->forceInsert(true); // default is false
                
                return $table;
            },
            database: $this->databases->default('pdo'),
        );
    }
}

$result = $migrator->install(DbMigrations::class);

$result = $migrator->uninstall(DbMigrations::class);