tobento/app-database 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

tobento/app-database

最新稳定版本:2.0.1

Composer 安装命令:

composer require tobento/app-database

包简介

App database support.

README 文档

README

Database support for the app.

Table of Contents

Getting Started

Add the latest version of the app database project running this command.

composer require tobento/app-database

Requirements

  • PHP 8.4 or greater

Documentation

App

Check out the App Skeleton if you are using the skeleton.

You may also check out the App to learn more about the app in general.

Database Boot

The database boot does the following:

  • Registers databases based on its configuration file
  • Binds DatabasesInterface to the app container.
  • Binds PdoDatabaseInterface to the app container using the default pdo database
  • Binds PDO to the app container for autowiring by using the default pdo database
  • Binds StorageInterface to the app container.

Database Config

The configuration for the database is located in the app/config/database.php file at the default App Skeleton config location.

use function Tobento\App\{directory};

return [

    /*
    |--------------------------------------------------------------------------
    | Default Database Names
    |--------------------------------------------------------------------------
    |
    | Specify the default database names you wish to use for your application.
    |
    | The default "pdo" is used by the application for the default
    | PdoDatabaseInterface implementation.
    | Moreover, it is used for autowiring classes with PDO parameters and
    | may be used in other app boots.
    | If you do not need it at all, just ignore or remove it.
    |
    | The default "storage" is used by the application for the default
    | StorageInterface implementation and may be used in other app boots.
    | If you do not need it at all, just ignore or remove it.
    |
    */

    'defaults' => [
        'pdo' => 'sqlite',
        'storage' => 'file',
    ],
    
    /*
    |--------------------------------------------------------------------------
    | Databases
    |--------------------------------------------------------------------------
    |
    | Configure any databases needed for your application.
    |
    */
    
    'databases' => [
        
        'sqlite' => [
            'factory' => \Tobento\Service\Database\PdoDatabaseFactory::class,
            'config' => [
                'dsn' => 'sqlite:'.directory('app').'storage/database/database.sqlite',
                'charset' => 'utf8mb4',
                'options' => [
                    \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
                    \PDO::ATTR_EMULATE_PREPARES => false,
                ],
            ],
        ],
        
        'sqlite-storage' => [
            'factory' => \Tobento\Service\Database\Storage\StorageDatabaseFactory::class,
            'config' => [
                'storage' => \Tobento\Service\Storage\PdoSqliteStorage::class,
                'database' => 'sqlite',
            ],
        ],
        
        'mysql' => [
            'factory' => \Tobento\Service\Database\PdoDatabaseFactory::class,
            'config' => [
                'driver' => 'mysql',
                'host' => 'localhost',
                'port' => null,
                'database' => 'app',
                'username' => 'root',
                'password' => '',
                'charset' => 'utf8mb4',
                'options' => [
                    \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
                    \PDO::ATTR_EMULATE_PREPARES => false,
                ],
            ],
        ],
        
        'mysql-storage' => [
            'factory' => \Tobento\Service\Database\Storage\StorageDatabaseFactory::class,
            'config' => [
                'storage' => \Tobento\Service\Storage\PdoMySqlStorage::class,
                'database' => 'mysql',
            ],
        ],
        
        'file' => [
            'factory' => \Tobento\Service\Database\Storage\StorageDatabaseFactory::class,
            'config' => [
                'storage' => Tobento\Service\Storage\JsonFileStorage::class,
                'dir' => directory('app').'storage/database/file/',
            ],
        ],
       
    ],
    
    /*
    |--------------------------------------------------------------------------
    | Database Processors
    |--------------------------------------------------------------------------
    |
    | The processors used for migration.
    |
    */
    
    'processors' => [
        // Processor for MySql and MariaDb:
        \Tobento\Service\Database\Processor\PdoMySqlProcessor::class,
        
        \Tobento\Service\Database\Processor\PdoSqliteProcessor::class,
        
        \Tobento\Service\Database\Storage\StorageDatabaseProcessor::class,
    ],

];

Pdo Database Factory

Check out the Database Service - Pdo Database Factory for its config parameters.

Storage Database Factory

Check out the Database Storage Service for its documentation.

Check out the Storage Service - Storages for the available storages.

Database Usage

You may access the default databases by the app:

use Tobento\App\AppFactory;
use Tobento\Service\Database\DatabasesInterface;
use Tobento\Service\Database\PdoDatabaseInterface;
use Tobento\Service\Database\Processor\ProcessorInterface;
use Tobento\Service\Storage\StorageInterface;

// Create the app
$app = new AppFactory()->createApp();

// Add directories:
$app->dirs()
    ->dir(realpath(__DIR__.'/../'), 'root')
    ->dir(realpath(__DIR__.'/app/'), 'app')
    ->dir($app->dir('app').'config', 'config', group: 'config');

// Adding boots
$app->boot(\Tobento\App\Database\Boot\Database::class);
$app->booting();

// Databases:
$databases = $app->get(DatabasesInterface::class);

// Default Pdo Database:
$database = $app->get(PdoDatabaseInterface::class);

// Default Storage:
$storage = $app->get(StorageInterface::class);

// Processor for migration:
$processor = $app->get(ProcessorInterface::class);

// Run the app
$app->run();

Check out the Database Service - Databases to learn more about the usage of the DatabasesInterface::class.

Check out the Database Service - Using PDO Database to learn more about the usage of the PdoDatabaseInterface::class.

Check out the Storage Service - Queries to learn more about the usage of the StorageInterface::class.

Using autowiring

You can also request the databases or the processor in any class resolved by the app.

use Tobento\Service\Database\DatabasesInterface;
use Tobento\Service\Database\PdoDatabaseInterface;
use Tobento\Service\Database\Processor\ProcessorInterface;
use Tobento\Service\Storage\StorageInterface;
use PDO;

class SomeService
{
    public function __construct(
        protected DatabasesInterface $databases,
        protected PdoDatabaseInterface $database,
        protected ProcessorInterface $processor,
        protected StorageInterface $storage,
        protected PDO $pdo,
    ) {}
}

Migration

Create Migration

Create a migration class by extending the DatabaseMigration::class and using the registerTables method to specifiy your tables.

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'),
        );
    }
}

Check out the Database Service - Table Schema for its documentation.

Check out the Database Service - Create Migration to learn more about it.

Install And Uninstall Migration

Check out the App Migration - Install And Uninstall Migration to learn more about it.

App Migration Example

use Tobento\App\AppFactory;
use Tobento\Service\Database\Migration\DatabaseMigration;
use Tobento\Service\Database\Schema\Table;
use Tobento\Service\Database\DatabasesInterface;

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

    protected function registerTables(): void
    {
        $this->registerTable(
            table: function(): Table {
                $table = new Table(name: 'users');
                $table->primary('id');
                $table->string('name');
                $table->items(iterable: [
                    ['name' => 'John'],
                    ['name' => 'Mia'],
                ]);
                return $table;
            },
            database: $this->databases->default('pdo'),
        );
    }
}

$app = new AppFactory()->createApp();

// Add directories:
$app->dirs()
    ->dir(realpath(__DIR__.'/../'), 'root')
    ->dir(realpath(__DIR__.'/app/'), 'app')
    ->dir($app->dir('app').'config', 'config', group: 'config');

// Adding boots:
$app->boot(\Tobento\App\Database\Boot\Database::class);
$app->booting();

// Install migration:
$app->install(DbMigrations::class);

// Fetch user names:
$database = $app->get(DatabasesInterface::class)->default('pdo');

$userNames = $database->execute(
    statement: 'SELECT name FROM users',
)->fetchAll(\PDO::FETCH_COLUMN);

// var_dump($userNames);
// array(2) { [0]=> string(4) "John" [1]=> string(3) "Mia" }

// Run the app:
$app->run();

Seeding

Seeding Boot

The seeding boot does the following:

The following seeders will be availbale:

Keep in mind that no Resources are set as they may be specific to your app needs. Therefore, the seeders mostly using the Lorem Seeder as fallback.

use Tobento\App\AppFactory;
use Tobento\Service\Seeder\SeedInterface;

// Create the app
$app = new AppFactory()->createApp();

// Adding boots
$app->boot(\Tobento\App\Database\Boot\Seeding::class);
$app->booting();

$seed = $app->get(SeedInterface::class);

// Run the app
$app->run();

Create Migration Seeder

Create a migration class for seeding by extending the DatabaseMigrationSeeder::class and using the registerTables method to specifiy your tables.

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 and uninstall methods
     * to create the actions from.
     *
     * @return void
     */
    protected function registerTables(): void
    {
        $this->registerTable(
            table: function(): Table {
                $table = new Table(name: 'users');
                // no need to specifiy columns again
                // if you have migrated the table before.
                
                // seeding:
                $table->items(new ItemFactoryIterator(
                    factory: function(): array {
                    
                        $fullname = $this->seed->fullname();
                        
                        return [
                            'name' => $fullname,
                            'email' => $this->seed->email(from: $fullname),
                            'weekday' => $this->seed->locale(['de', 'en'])->weekday(1, 7, 'EEEE'),
                        ];
                    },
                    create: 10000
                ))
                ->chunk(length: 2000)
                ->useTransaction(false) // default is true
                ->forceInsert(true); // default is false
                
                return $table;
            },
            database: $this->databases->default('pdo'),
            name: 'Users seeding',
            description: 'Users seeded',
        );
    }
}

Check out the Database Service - Create Migration Seeder to learn more about it.

Check out the Seeder Service for its documentation.

Check out the Database Service - Table Schema for its documentation.

Seeder Resources

You may add seeder resources by the following ways:

Globally by using the app on method

use Tobento\App\AppFactory;
use Tobento\Service\Seeder\SeedInterface;
use Tobento\Service\Seeder\Resource;

// Create the app
$app = new AppFactory()->createApp();

// Adding boots
$app->boot(\Tobento\App\Database\Boot\Seeding::class);
$app->booting();

// Add resources:
$app->on(SeedInterface::class, function(SeedInterface $seed) {

    $seed->resources()->add(new Resource('countries', 'en', [
        'Usa', 'Switzerland', 'Germany',
    ]));
});

$seed = $app->get(SeedInterface::class);

var_dump($seed->country());
// string(7) "Germany"

// Run the app
$app->run();

Specific on your migration seeder

use Tobento\Service\Database\Migration\DatabaseMigrationSeeder;
use Tobento\Service\Seeder\Resource;

class DbMigrationsSeeder extends DatabaseMigrationSeeder
{
    // ...
    
    protected function registerTables(): void
    {
        $this->seed->resources()->add(new Resource('countries', 'en', [
            'Usa', 'Switzerland', 'Germany',
        ]));
        
        // register tables:
    }
}

You may check out Seeder Service - Resources or Seeder Service - Files Resources for its documentation.

App Migration Seeder Example

use Tobento\App\AppFactory;
use Tobento\Service\Database\Migration\DatabaseMigration;
use Tobento\Service\Database\Migration\DatabaseMigrationSeeder;
use Tobento\Service\Database\Schema\Table;
use Tobento\Service\Database\DatabasesInterface;
use Tobento\Service\Iterable\ItemFactoryIterator;

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

    protected function registerTables(): void
    {
        $this->registerTable(
            table: function(): Table {
                $table = new Table(name: 'users');
                $table->primary('id');
                $table->string('name');
                $table->string('email');
                return $table;
            },
            database: $this->databases->default('pdo'),
        );
    }
}

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

    protected function registerTables(): void
    {
        $this->registerTable(
            table: function(): Table {
                $table = new Table(name: 'users');
                
                $table->items(new ItemFactoryIterator(
                    factory: function(): array {
                    
                        $fullname = $this->seed->fullname();
                        
                        return [
                            'name' => $fullname,
                            'email' => $this->seed->email(from: $fullname),
                        ];
                    },
                    create: 10,
                ))
                ->chunk(length: 2000)
                ->useTransaction(false) // default is true
                ->forceInsert(true); // default is false
                
                return $table;
            },
            database: $this->databases->default('pdo'),
        );
    }
}

$app = new AppFactory()->createApp();

// Add directories:
$app->dirs()
    ->dir(realpath(__DIR__.'/../'), 'root')
    ->dir(realpath(__DIR__.'/app/'), 'app')
    ->dir($app->dir('app').'config', 'config', group: 'config');

// Adding boots:
$app->boot(\Tobento\App\Database\Boot\Database::class);
$app->boot(\Tobento\App\Database\Boot\Seeding::class);
$app->booting();

// Install migration:
$app->install(DbMigrations::class);
$app->install(DbMigrationsSeeder::class);

// Fetch user names:
$database = $app->get(DatabasesInterface::class)->default('pdo');

$emailsToNames = $database->execute(
    statement: 'SELECT email, name FROM users',
)->fetchAll(\PDO::FETCH_KEY_PAIR);

var_dump($emailsToNames);
// array(10) { ["vitae.elit@example.org"]=> string(10) "Vitae Elit" ... }

// Run the app:
$app->run();

Credits

统计信息

  • 总下载量: 142
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 1
  • 依赖项目数: 9
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2023-03-06

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固