iOS uses FMDB and FMDB migration manager to upgrade the database version

Keywords: Database iOS SQLite

FMDB is generally used for data saving in iOS. Generally, fields will not be modified or added after being defined. If it is strict, we need to add the function of adding fields to the database. At present, FMDB and FMDB migration manager are used in the project to save the database version number and upgrade the database

According to the explanation on the Internet, there are two methods, only one of which is introduced here:

Here's another way https://www.jianshu.com/p/6cfc38a6d2c0

Create a new class: Migration follows fmdb Migration protocol, name: upgrade description (can be set to nil), version: version number of current database, array: database operation;

#import <Foundation/Foundation.h>
#import "FMDBMigrationManager.h"

@interface Migration : NSObject<FMDBMigrating>

@property (nonatomic, readonly) NSString *name;
@property (nonatomic, readonly)uint64_t version;

/**
 @param name Database upgrade description
 @param version Current version number
 @param updateArray Database operation, since there may be more than one, use array
 @return  Migration
 */
- (instancetype)initWithName:(NSString *)name andVersion:(uint64_t)version andExecuteUpdateArray:(NSArray *)updateArray;

- (BOOL)migrateDatabase:(FMDatabase *)database error:(out NSError *__autoreleasing *)error;

@end
#import "Migration.h"

@interface Migration()

@property (nonatomic, copy) NSString *myName;
@property (nonatomic, assign) uint64_t myVersion;
@property (nonatomic, strong) NSArray *updateArray;

@end

@implementation Migration

- (instancetype)initWithName:(NSString *)name andVersion:(uint64_t)version andExecuteUpdateArray:(NSArray *)updateArray
{
    if (self = [super init]) {
        _myName = name;
        _myVersion = version;
        _updateArray = updateArray;
    }
    return self;
}

- (NSString *)name {
    return _myName;
}

- (uint64_t)version {
    return _myVersion;
}

- (BOOL)migrateDatabase:(FMDatabase *)database error:(out NSError *__autoreleasing *)error {
    for (NSString *updateStr in _updateArray) {
        [database executeUpdate:updateStr];
    }
    return YES;
}

@end
// #define CACHESDIRECTORY ([NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0])

    NSString *documentsPath = CACHESDIRECTORY; // [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    
    // File path
    
    NSString *filePath = [documentsPath stringByAppendingPathComponent:@"express.sqlite"];
    NSLog(@"filePath == %@",filePath);
    // Instantiate FMDataBase object
    
    _db = [FMDatabase databaseWithPath:filePath];
    
    [_db open];

    FMDBMigrationManager *manager = [FMDBMigrationManager  managerWithDatabaseAtPath:filePath migrationsBundle:[NSBundle mainBundle]];
    // Here, migration 1 means new
    Migration *migration_1 = [[Migration alloc] initWithName:@"Newly build table surface" andVersion:1 andExecuteUpdateArray:@[@"CREATE TABLE 'express' ('express_number' VARCHAR(255),'express_name' VARCHAR(255),'express_type' VARCHAR(255), 'express_date' VARCHAR(255),'express_message' VARCHAR(255), 'express_image' ARCHAR(255))"]];
    [manager addMigration:migration_1];
    // Add fields
    Migration * migration_2=[[Migration alloc]initWithName:@"USer Table new fields email" andVersion:2 andExecuteUpdateArray:@[@"alter table express add email text"]];
    [manager addMigration:migration_2];
    
    BOOL resultState = NO;
    NSError *error = nil;
    if (!manager.hasMigrationsTable) {
        resultState = [manager createMigrationsTable:&error];
    }
    resultState = [manager migrateDatabaseToVersion:UINT64_MAX progress:nil error:&error];
    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);
    
    [_db close];

 

Posted by freddykhalid on Thu, 02 Jan 2020 13:50:06 -0800