tobento/app-database

应用数据库支持。

1.0.2 2024-02-21 16:59 UTC

This package is auto-updated.

Last update: 2024-09-21 18:34:57 UTC


README

应用数据库支持。

目录

入门

使用以下命令添加运行中的应用数据库项目最新版本。

composer require tobento/app-database

需求

  • PHP 8.0 或更高版本

文档

应用

如果您使用的是骨架,请查看 应用骨架

您还可以查看 应用 以了解有关应用的更多信息。

数据库启动

数据库启动执行以下操作

  • 根据其配置文件注册数据库
  • 将 DatabasesInterface 绑定到应用容器。
  • 使用默认 pdo 数据库将 PdoDatabaseInterface 绑定到应用容器。
  • 使用默认 pdo 数据库将 PDO 绑定到应用容器以实现自动注入。
  • 将 StorageInterface 绑定到应用容器。

数据库配置

数据库配置位于默认 应用骨架 配置位置的 app/config/database.php 文件中。

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' => 'mysql',
        'storage' => 'file',
    ],
    
    /*
    |--------------------------------------------------------------------------
    | Databases
    |--------------------------------------------------------------------------
    |
    | Configure any databases needed for your application.
    |
    */
    
    'databases' => [
        
        '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,
                ],
            ],
        ],
        
        'file' => [
            'factory' => \Tobento\Service\Database\Storage\StorageDatabaseFactory::class,
            'config' => [
                'storage' => Tobento\Service\Storage\JsonFileStorage::class,
                'dir' => directory('app').'storage/database/file/',
            ],
        ],
        
        'mysql-storage' => [
            'factory' => \Tobento\Service\Database\Storage\StorageDatabaseFactory::class,
            'config' => [
                'storage' => \Tobento\Service\Storage\PdoMySqlStorage::class,
                'database' => 'mysql',
            ],
        ],
       
    ],
    
    /*
    |--------------------------------------------------------------------------
    | Database Processors
    |--------------------------------------------------------------------------
    |
    | The processors used for migration.
    |
    */
    
    'processors' => [
        // Processor for MySql and MariaDb:
        \Tobento\Service\Database\Processor\PdoMySqlProcessor::class,
        
        \Tobento\Service\Database\Storage\StorageDatabaseProcessor::class,
    ],

];

Pdo 数据库工厂

查看 数据库服务 - Pdo 数据库工厂 以了解其配置参数。

存储数据库工厂

查看 数据库存储服务 以了解其文档。

查看 存储服务 - 存储库 以了解可用的存储库。

数据库使用

您可以通过应用访问默认数据库

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();

查看 数据库服务 - 数据库 了解有关 DatabasesInterface::class 的使用。

查看 数据库服务 - 使用 PDO 数据库 了解有关 PdoDatabaseInterface::class 的使用。

查看 存储服务 - 查询 了解有关 StorageInterface::class 的使用。

使用自动注入

您也可以在任何由应用解析的类中请求数据库或处理器。

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,
    ) {}
}

迁移

创建迁移

通过扩展 DatabaseMigration::class 并使用 registerTables 方法指定您的表来创建迁移类。

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\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();

播种

播种启动

播种启动执行以下操作

以下将提供以下种子生成器

请注意,没有设置任何 资源,因为这些可能特定于您的应用程序需求。因此,种子生成器主要使用 Lorem Seeder 作为后备。

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();

创建迁移播种器

通过扩展 DatabaseMigrationSeeder::class 并使用 registerTables 方法指定您的表来创建一个用于种子生成迁移的类。

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

查看 数据库服务 - 创建迁移种子生成器 以获取更多信息。

查看 种子生成服务 的文档。

查看 数据库服务 - 表模式 了解其文档。

播种器资源

您可以通过以下方式添加种子资源

全局使用 app 方法

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();

在您的迁移种子生成器中特定使用

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:
    }
}

您可以查看 种子生成服务 - 资源种子生成服务 - 文件资源 的文档。

应用迁移播种器示例

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();

仓库

进行中...

鸣谢