placebook/framework-selfupdate

与 SQL 迁移的半自动工作

2.0.1 2021-06-20 11:54 UTC

This package is auto-updated.

Last update: 2024-09-20 19:09:37 UTC


README

此包旨在对项目核心或第三方包的数据库结构进行半自动更新。

此包是 Placebook\Framework 的一部分,但可以用于您的任何项目。此外,它不仅可以用于 SQL 迁移,还可以用于任何其他可逆迁移。

内核工作方式

该项目包含一个用于此包的文件夹。例如,/install。此文件夹的路径已传递给包

use Placebook\Framework\Core\Install\SelfUpdate;

SelfUpdate::$installDir = ROOT . '/install';

此目录包含 versions.json 文件和 custom_versions.json,内容如下

{
    "details": {
        "0":     {"class": null},
        "1.0.0": {"class": "Migration_1"},
        "2.0.0": {"class": "Migration_2"},
        "3.0.0": {"class": "Migration_3", "namespace": "\\YourProject\\Test\\Migration"}
    }
}

这里是版本描述。默认情况下,类名位于命名空间 Placebook\Framework\Core\Install 中,但可以指定另一个命名空间。内核版本将始终只增加第一个版本号,并在 versions.json 中。然后特定站点可以采用内核的当前版本,例如,3.0.0,并按您的喜好增加版本,但不能增加主版本号(3)。并将您的版本存储在文件 custom_versions.json 中。包将合并这两个文件,并能够从零开始升级到内核的最大版本,然后到特定项目的最大版本。同时,已经运行并具有自己的迁移的特定项目将能够更新其内核版本,并且与其一起更新的将是 versions.json。例如,将出现版本 4.0.0。然后包将更新内核,然后项目必须为其迁移分配版本 >4.0.0。Placebook\Framework 核心不会将版本保存到文件 custom_versions.json 中,它只属于您。这样,包将很好地与内核和项目迁移自动协同工作。

更新过程

指定的文件夹包含文件 db_version.lock。它存储内核的当前版本。如果没有文件,则版本解释为 0

在同一文件夹中有一个文件 updating.lock。如果存在,则更新正在进行中,则包将不会在另一个线程中启动更新。因此,如果迁移需要很长时间,则只有第一个请求(在上传新文件后)将启动迁移。其余的传入请求将基于基础结构进行处理。包读取所有可用的版本,并将它们按升序排列。从一个版本到另一个版本,需要经过所有中间版本。如果更新中断,则 updating.lock 文件将保留,并且更新不会再次启动,直到您手动解决问题。

对于站点

内核更新

namespace Placebook\Framework\Core\Install;

SelfUpdate::$installDir = ROOT . '/install';
SelfUpdate::updateDbIfLessThen('6.0.0'); // update to a specific version
SelfUpdate::updateDbIfLessThen(SelfUpdate::getMaxVersion()); // upgrade to maximum version


// updateDbIfLessThen updates only upwards. If you need to roll back down, there is another method for this:
$current = SelfUpdate::getDbVersion();
SelfUpdate::updateFromTo($current, '0.0.7'); // update that will work up and down (downgrade)

添加迁移

  • 站点需要将迁移包装在一个实现了接口 Placebook\Framework\Core\Install\MigrationInterface 的类中
  • 您需要在 custom_versions.json 中添加新版本下的类名和命名空间(如果它不是默认的 Placebook\Framework\Core\Install,则不是默认的)
  • 在类中,最好实现向上迁移和迁移回滚

迁移类示例

<?php

namespace Placebook\Framework\Core\Install;

use Exception;
use cri2net\php_pdo_db\PDO_DB;

class Migration_sample implements MigrationInterface
{
    public static function up()
    {
        $pdo = PDO_DB::getPDO();
        try {

            $pdo->beginTransaction();
            // something useful
            $pdo->commit();

        } catch (Exception $e) {
            $pdo->rollBack();
            throw $e;
        }
    }

    public static function down()
    {
        $pdo = PDO_DB::getPDO();
        try {

            $pdo->beginTransaction();
            // Rollback update
            $pdo->commit();

        } catch (Exception $e) {
            $pdo->rollBack();
            throw $e;
        }
    }
}

对于包

只需要一个版本文件,不需要 custom_versions.json。建议的结构如下

  • /vendor/vendor_name/package_name/versions.json
  • /vendor/vendor_name/package_name/**/ 任何有用的类,包括具有迁移的类

由于网站上有模块,您可以将 SelfUpdate 的工作移入一个单独的文件,该文件将为所有请求连接。建议内容

<?php
namespace Placebook\Framework\Core\Install;

use Exception;

// kernel update
SelfUpdate::$installDir = PROTECTED_DIR . '/install';

// data about modules for updating
$modules = [
    ['vendor' => 'vendor1', 'name' => 'package1'],
    ['vendor' => 'vendor2', 'name' => 'package2'],
];

try {
    foreach ($modules as $module) {
        
        try {

            $versionsDir = PROTECTED_DIR . "/vendor/{$module['vendor']}/" . $module['name']; // path to vendor folder
            $versions = SelfUpdate::getVersions($versionsDir); // get package versions
            $max = SelfUpdate::getMaxVersion($versions); // get max version
            SelfUpdate::updatePackage($max, $versionsDir, $module['vendor'], $module['name']); // update
            
        } catch (Exception $e) {
        }

    }

    SelfUpdate::updateDbIfLessThen(SelfUpdate::getMaxVersion());

} catch (Exception $e) {
}

已安装的模块版本将存储在路径 install/modules/<vendor_name>/<package_name>.version.lock 中。如果一个模块有数据库迁移并且可以通过 composer 安装,那么在将该项目作为依赖项添加时,只需将其添加到模块数组中一次,然后就可以通过 composer 更新其版本,数据库结构的更改将自动发生