FMDBMigrationManager 1.4.1

FMDBMigrationManager 1.4.1

测试已测试
语言语言 Objective-CObjective C 语言
许可证 Apache 2
发布最新版本2015年12月

Blake WattersBlake WattersKlemen Verdnik 维护。



  • Blake Watters

用于 FMDB 的 SQLite 模式迁移管理系统。

FMDBMigrationManager 是通过 FMDB 库访问 SQLite 数据库所缺少的模式管理系统。它提供了一个简单、灵活的解决方案,将版本化模式管理引入使用 SQLite 和 FMDB 进行持久化的新或现有 Cocoa 应用程序。

功能

  • 支持在宿主数据库中创建和管理专用的迁移表。
  • 使用 SQLite 事务安全地应用迁移。
  • 基本迁移以平面 SQL 文件形式实现,命名约定包含版本和名称。
  • 支持代码迁移实现,用于执行无法用 SQL 表达的对象图迁移。
  • 通过 Objective-C 运行时协议遵守 introspection 发现基于代码的迁移。
  • 包括一个轻量级且丰富的 API,用于检查模式状态。
  • 公开正在进行的迁移状态,并通过 NSProgress 支持取消迁移。

实现细节

FMDBMigrationManager 通过在管理的数据库中引入一个简单的 schema_migrations 表来工作。此表具有以下架构:

CREATE TABLE schema_migrations(
    version INTEGER UNIQUE NOT NULL
);

schema_migrations 表中的每一行对应一个已应用的单独迁移,代表模式的一个唯一版本。此架构支持任何基于整数版本的系统,但建议您使用编码时间戳的整数。

时间戳版本

与单调递增整数相比,时间戳更佳,因为它们更好地支持分支工作流程,因为在将多个发展路线汇集在一起时,无需重新排序迁移。确保具有足够精度级别的时间戳具有非常低潜在冲突可能性,并且可以简单地排序。

推荐的时间戳迁移格式使用亚秒精度,可以通过在提供 GNU coreutils 的平台上使用 date 实用程序生成,例如使用 date +"%Y%m%d%H%M%S%3N"。不幸的是,与 Mac OS X 一起提供的 date 版本没有本地支持此格式。它可以通过调用 Ruby 生成:ruby -e "puts Time.now.strftime('%Y%m%d%H%M%S%3N').to_i"

迁移命名

FMDBMigrationManager更喜欢以平面SQL文件形式表达的迁移。这些文件可以通过任意的NSBundle包含到主项目中。为了让FMDBMigrationManager能够识别包内迁移文件及其表示的版本,文件名必须包含版本数据,并且可以包含迁移的描述性名称。迁移文件名与正则表达式匹配,以识别以下格式的文件名:(<数字版本号>)_?(<描述性名称)?.sql。名称是可选的,但如果包含,必须由下划线分隔,但版本以及.sql文件扩展名是必需的。

有效的迁移名称示例包括

  • 1.sql
  • 201406063106474_create_mb-demo-schema.sql
  • 9999_ChangeTablesToNewFormat.sql
  • 2014324_This is the Description.sql

计算原始版本和当前版本

在FMDBMigrationManager确定应该将哪些迁移应用到给定数据库之前,它必须能够评估当前模式的详细信息。

要计算“原始版本”(数据库创建时的模式版本),从schema_migrations表中选择version列的最小值。

SELECT MIN(version) FROM schema_migrations

可以通过选择schema_migrations表中存在的version列的最大值来计算数据库的当前版本。

SELECT MAX(version) FROM schema_migrations

请注意,知道当前版本并不足以确定数据库是否已完全迁移。这是因为过去创建的迁移可能尚未合并、发布和应用。

计算未应用的迁移

使用以下算法确定给定数据库应应用哪些迁移

  1. 计算数据库的原始版本。
  2. 创建一个包含给定包内所有迁移version的数组。
  3. 创建一个包含已应用到数据库的所有迁移版本(SELECT version FROM schema_migrations)的数组。
  4. 从列表中删除小于数据库原始版本的任何迁移。
  5. 比较迁移数组。剩余的集合是待处理的迁移集合。
  6. 将未应用迁移的集合按升序排序,并按从旧到新的顺序应用它们。

用法

FMDBMigrationManager设计得非常简单易用。库的广泛单元测试覆盖率提供了大量的参考代码。以下各节快速概述了如何使用库完成最常见任务。

请注意,FMDBMigrationManager的实例使用migrationsBundle初始化。该包使用实施部分中详细说明的方法扫描迁移文件。对于典型的iOS应用,通常使用主应用程序包。对于CocoaPods或框架分发,可以提供一个对NSBundle的引用。

创建迁移表

FMDBMigrationManager *manager = [FMDBMigrationManager managerWithDatabaseAtPath:@"path/to/your/DB.sqlite" migrationsBundle:[NSBundle mainBundle]];
NSError *error = nil;
BOOL success = [manager createMigrationsTable:&error];

创建SQL文件迁移

$ touch "`ruby -e "puts Time.now.strftime('%Y%m%d%H%M%S%3N').to_i"`"_CreateMyAwesomeTable.sql

现在编辑你选择的编辑器中的*_CreateMyAwesomeTable.sql文件并将其添加到你的应用程序包中。

创建Objective-C迁移

Objective-C 基础的迁移可以通过创建一个新的类来实现,该类需符合 FMDBMigrating 协议。

@interface MyAwesomeMigration : NSObject <FMDBMigrating>
@end

@implementation MyAwesomeMigration

- (NSString *)name
{
    return @"My Object Migration";
}

- (uint64_t)version
{
    return 201499000000000;
}

- (BOOL)migrateDatabase:(FMDatabase *)database error:(out NSError *__autoreleasing *)error
{
    // Do something awesome
    return YES;
}

@end

当将符合 FMDBMigrating 协议的类添加到项目后,它们将被 FMDBMigrationManager 发现并被考虑进行迁移。

迁移数据库

FMDBMigrationManager *manager = [FMDBMigrationManager managerWithDatabaseAtPath:@"path/to/your/DB.sqlite" migrationsBundle:[NSBundle mainBundle]];
NSError *error = nil;
BOOL success = [manager migrateDatabaseToVersion:UINT64_MAX progress:nil error:&error];

检查架构状态

FMDBMigrationManager 包含了用于调查数据库状态的多个方法。以下是快速浏览:

FMDBMigrationManager *manager = [FMDBMigrationManager managerWithDatabaseAtPath:@"path/to/your/DB.sqlite" migrationsBundle:[NSBundle mainBundle]];
NSLog(@"Has `schema_migrations` table?: %@", manager.hasMigrationsTable ? @"YES" : @"NO");
NSLog(@"Origin Version: %llu", manager.originVersion);
NSLog(@"Current version: %llu", manager.currentVersion);
NSLog(@"All migrations: %@", manager.migrations);
NSLog(@"Applied versions: %@", manager.appliedVersions);
NSLog(@"Pending versions: %@", manager.pendingVersions);

安装

FMDBMigrationManager 体积小巧,仅依赖 SQLite 和 FMDB。因此,可以简单地将库直接添加到任何 Cocoa 项目中,只需添加源代码,链接到 libsqlite,并包含 FMDB。尽管如此,我们建议通过 CocoaPods 进行安装,因为它提供模块化和易于版本管理。

通过源代码

只需将 FMDBMigrationManager.hFMDBMigrationManager.m 添加到您的项目中,并使用 #import "FMDBMigrationManager.h"

单元测试

FMDBMigrationManager 使用 Expecta 单元测试匹配器库进行测试。要运行测试,您必须执行以下操作:

  1. 通过 CocoaPods 安装依赖项:pod install
  2. 打开工作区:open FMDBMigrationManager.xcworkspace
  3. 通过 产品 菜单 > 测试 运行测试

或者,您也可以通过安装 Ruby Gem 依赖项在命令行上运行测试。FMDBMigrationManager 使用 xctasks Gem 在 Rake 之上提供 CLI 自动化。要在 CLI 上运行测试

  1. 安装依赖项:bundle install
  2. 调用 Rake:bundle exec rake test

Rake 任务用于通过 Travis CI (查看 .travis.yml) 驱动持续集成。

致谢

FMDBMigrationManager 是由 Blake Watters 在其为 Layer 的工作期间,在旧金山精心制作的。在 Layer,我们正在构建互联网的通信层。我们重视、支持和创作开源工程杰作。

Blake Watters

许可证

FMDBMigrationManager 在 Apache 2 许可下可供使用。有关更多信息,请参阅 LICENSE 文件。