From 7f6081d4c9fec4b3b72c2634e5343bb7b72075a9 Mon Sep 17 00:00:00 2001 From: Nimrod A Date: Thu, 7 Feb 2013 15:37:45 +0200 Subject: [PATCH 1/4] Add allow nulls and default value to columns. Enable use of constraints and default values in FmdbMigration createTable --- Classes/FmdbMigration.h | 1 + Classes/FmdbMigration.m | 30 +++++++++++++++++++---- Classes/FmdbMigrationColumn.h | 8 ++++++ Classes/FmdbMigrationColumn.m | 46 +++++++++++++++++++++++++++++++++-- 4 files changed, 78 insertions(+), 7 deletions(-) diff --git a/Classes/FmdbMigration.h b/Classes/FmdbMigration.h index d0e4802..78dcaff 100644 --- a/Classes/FmdbMigration.h +++ b/Classes/FmdbMigration.h @@ -25,6 +25,7 @@ - (void)createTable:(NSString *)tableName; - (void)createTable:(NSString *)tableName withColumns:(NSArray *)columns; +- (void)createTable:(NSString *)tableName withColumns:(NSArray *)columns andPrimaryKeys:(NSArray *)keyNames; - (void)dropTable:(NSString *)tableName; - (void)addColumn:(FmdbMigrationColumn *)column forTableName:(NSString *)tableName; diff --git a/Classes/FmdbMigration.m b/Classes/FmdbMigration.m index 33253d1..31aeb88 100644 --- a/Classes/FmdbMigration.m +++ b/Classes/FmdbMigration.m @@ -43,12 +43,32 @@ - (void)downWithDatabase:(FMDatabase *)db #pragma mark - #pragma mark Helper methods for manipulating database schema -- (void)createTable:(NSString *)tableName withColumns:(NSArray *)columns +- (void)createTable:(NSString *)tableName withColumns:(NSArray *)columns { - [self createTable:tableName]; - for (FmdbMigrationColumn *migrationColumn in columns) { - [self addColumn:migrationColumn forTableName:tableName]; - } + NSMutableArray *columnDefinitions; + [columnDefinitions addObject:"id integer primary key autoincrement"]; + for (FmdbMigrationColumn *migrationColumn in columns) { + [columnDefinitions addObject:[migrationColumn sqlDefinition]]; + } + + NSString *sql = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS %@ (%@)", tableName, [columnDefinitions componentsJoinedByString:@","]]; + [db_ executeUpdate:sql]; +} + +- (void)createTable:(NSString *)tableName + withColumns:(NSArray *)columns + andPrimaryKeys:(NSArray *)keyNames +{ + NSMutableArray *columnDefinitions = [[NSMutableArray alloc] initWithCapacity:[columns count]]; + for (FmdbMigrationColumn *migrationColumn in columns) { + [columnDefinitions addObject:[migrationColumn sqlDefinition]]; + } + + NSString *sql = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS %@ (%@, primary key (%@))", + tableName, + [columnDefinitions componentsJoinedByString:@","], + [keyNames componentsJoinedByString:@","]]; + [db_ executeUpdate:sql]; } - (void)createTable:(NSString *)tableName diff --git a/Classes/FmdbMigrationColumn.h b/Classes/FmdbMigrationColumn.h index f1f31db..57019b3 100644 --- a/Classes/FmdbMigrationColumn.h +++ b/Classes/FmdbMigrationColumn.h @@ -16,6 +16,7 @@ } @property (retain) NSString *columnName; @property (retain) NSString *columnType; +@property BOOL allowNulls; @property (retain) id defaultValue; + (FmdbMigrationColumn*)columnWithColumnName:(NSString*)columnName @@ -23,6 +24,13 @@ + (FmdbMigrationColumn*)columnWithColumnName:(NSString*)columnName columnType:(NSString*)columnType defaultValue:(id)defaultValue; ++ (FmdbMigrationColumn*)columnWithColumnName:(NSString*)columnName + columnType:(NSString*)columnType + defaultValue:(id)defaultValue + allowNulls:(BOOL)allowNulls; ++ (FmdbMigrationColumn*)columnWithColumnName:(NSString*)columnName + columnType:(NSString*)columnType + allowNulls:(BOOL)allowNulls; // Used for sql queries "ALTER TABLE table_name ADD COLUMN [column sqlDefinition]" - (NSString *)sqlDefinition; diff --git a/Classes/FmdbMigrationColumn.m b/Classes/FmdbMigrationColumn.m index f246dc2..66ee65b 100644 --- a/Classes/FmdbMigrationColumn.m +++ b/Classes/FmdbMigrationColumn.m @@ -10,7 +10,7 @@ @implementation FmdbMigrationColumn -@synthesize columnName=columnName_, columnType=columnType_, defaultValue=defaultValue_; +@synthesize columnName=columnName_, columnType=columnType_, defaultValue=defaultValue_, allowNulls=allowNulls_; #pragma mark - #pragma mark Constructor helpers @@ -34,6 +34,36 @@ + (FmdbMigrationColumn*)columnWithColumnName:(NSString*)columnName return column; } ++ (FmdbMigrationColumn *)columnWithColumnName:(NSString *)columnName + columnType:(NSString *)columnType + defaultValue:(id)defaultValue + allowNulls:(BOOL)allowNulls +{ + FmdbMigrationColumn* column = [self columnWithColumnName:columnName columnType:columnType defaultValue:defaultValue]; + column.allowNulls = allowNulls; + return column; +} + ++ (FmdbMigrationColumn *)columnWithColumnName:(NSString *)columnName + columnType:(NSString *)columnType + allowNulls:(BOOL)allowNulls +{ + FmdbMigrationColumn* column = [self columnWithColumnName:columnName columnType:columnType]; + column.allowNulls = allowNulls; + return column; +} + + +- (id)init +{ + self = [super init]; + if (self) { + allowNulls_ = true; + } + + return self; +} + // Notes from http://www.sqlite.org/lang_altertable.html: // Column-def may take any of the forms permissable in a CREATE TABLE statement, with the following restrictions: // * The column may not have a PRIMARY KEY or UNIQUE constraint. @@ -41,7 +71,19 @@ + (FmdbMigrationColumn*)columnWithColumnName:(NSString*)columnName // * If a NOT NULL constraint is specified, then the column must have a default value other than NULL. - (NSString *)sqlDefinition { - NSString *sql = [NSString stringWithFormat:@"%@ %@", self.columnName, self.columnTypeDefinition]; + NSString *nullString = self.allowNulls ? @"NULL" : @"NOT NULL"; + NSMutableArray *statements = [NSMutableArray arrayWithArray: @[ + self.columnName, + self.columnTypeDefinition, + nullString + ]]; + + if (self.defaultValue) { + [statements addObject:[NSString stringWithFormat:@"default %@", self.defaultValue]]; + } + + NSString *sql = [statements componentsJoinedByString:@" "]; + return sql; } From 9b1da9887e093c981deb1d6d0590aca4c7f74a8d Mon Sep 17 00:00:00 2001 From: Nimrod A Date: Tue, 6 Aug 2013 21:09:20 +0300 Subject: [PATCH 2/4] Added an option to create or drop indexes --- Classes/FmdbMigration.h | 6 ++ Classes/FmdbMigration.m | 100 ++++++++++-------- .../xcschemes/fmdb-migration-manager.xcscheme | 59 +++++++++++ .../xcschemes/xcschememanagement.plist | 22 ++++ 4 files changed, 140 insertions(+), 47 deletions(-) create mode 100644 fmdb-migration-manager.xcodeproj/xcuserdata/nimast.xcuserdatad/xcschemes/fmdb-migration-manager.xcscheme create mode 100644 fmdb-migration-manager.xcodeproj/xcuserdata/nimast.xcuserdatad/xcschemes/xcschememanagement.plist diff --git a/Classes/FmdbMigration.h b/Classes/FmdbMigration.h index 78dcaff..a3d51c7 100644 --- a/Classes/FmdbMigration.h +++ b/Classes/FmdbMigration.h @@ -25,13 +25,19 @@ - (void)createTable:(NSString *)tableName; - (void)createTable:(NSString *)tableName withColumns:(NSArray *)columns; + +- (void)createIndex:(NSString *)indexName onTable:(NSString *)tableName withColumns:(NSArray *)columns; + - (void)createTable:(NSString *)tableName withColumns:(NSArray *)columns andPrimaryKeys:(NSArray *)keyNames; - (void)dropTable:(NSString *)tableName; +- (void)dropIndex:(NSString *)indexName; + - (void)addColumn:(FmdbMigrationColumn *)column forTableName:(NSString *)tableName; // This init method exists for the purposes of unit testing. // Production code should never call this method, instead instantiate // your subclasses with +migration method. - (id)initWithDatabase:(FMDatabase *)db; + @end diff --git a/Classes/FmdbMigration.m b/Classes/FmdbMigration.m index 31aeb88..e05f39f 100644 --- a/Classes/FmdbMigration.m +++ b/Classes/FmdbMigration.m @@ -10,41 +10,37 @@ @implementation FmdbMigration -@synthesize db=db_; +@synthesize db = db_; + (id)migration { - return [[[self alloc] init] autorelease]; + return [[[self alloc] init] autorelease]; } #pragma mark - #pragma mark up/down methods -- (void)up -{ - NSLog([NSString stringWithFormat:@"%s: -up method not implemented", NSStringFromClass([self class])]); +- (void)up { + NSLog([NSString stringWithFormat:@"%s: -up method not implemented", NSStringFromClass([self class])]); } -- (void)down -{ - NSLog([NSString stringWithFormat:@"%s: -down method not implemented", NSStringFromClass([self class])]); +- (void)down { + NSLog([NSString stringWithFormat:@"%s: -down method not implemented", NSStringFromClass([self class])]); } -- (void)upWithDatabase:(FMDatabase *)db -{ - self.db = db; - [self up]; +- (void)upWithDatabase:(FMDatabase *)db { + self.db = db; + [self up]; } -- (void)downWithDatabase:(FMDatabase *)db -{ - self.db = db; - [self down]; + +- (void)downWithDatabase:(FMDatabase *)db { + self.db = db; + [self down]; } #pragma mark - #pragma mark Helper methods for manipulating database schema -- (void)createTable:(NSString *)tableName withColumns:(NSArray *)columns -{ +- (void)createTable:(NSString *)tableName withColumns:(NSArray *)columns { NSMutableArray *columnDefinitions; [columnDefinitions addObject:"id integer primary key autoincrement"]; for (FmdbMigrationColumn *migrationColumn in columns) { @@ -55,58 +51,68 @@ - (void)createTable:(NSString *)tableName withColumns:(NSArray *)columns [db_ executeUpdate:sql]; } +- (void)createIndex:(NSString *)indexName + onTable:(NSString *)tableName + withColumns:(NSArray *)columns { + NSString *indexColumns = [columns componentsJoinedByString:@","]; + NSString *sql = [NSString stringWithFormat:@"CREATE INDEX IF NOT EXISTS %@ ON %@ (%@);", + indexName, + tableName, + indexColumns]; + [db_ executeUpdate:sql]; +} + - (void)createTable:(NSString *)tableName withColumns:(NSArray *)columns - andPrimaryKeys:(NSArray *)keyNames -{ + andPrimaryKeys:(NSArray *)keyNames { NSMutableArray *columnDefinitions = [[NSMutableArray alloc] initWithCapacity:[columns count]]; for (FmdbMigrationColumn *migrationColumn in columns) { [columnDefinitions addObject:[migrationColumn sqlDefinition]]; } NSString *sql = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS %@ (%@, primary key (%@))", - tableName, - [columnDefinitions componentsJoinedByString:@","], - [keyNames componentsJoinedByString:@","]]; + tableName, + [columnDefinitions componentsJoinedByString:@","], + [keyNames componentsJoinedByString:@","]]; + [db_ executeUpdate:sql]; +} + +- (void)createTable:(NSString *)tableName { + NSString *sql = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS %@ (id integer primary key autoincrement)", tableName]; [db_ executeUpdate:sql]; } -- (void)createTable:(NSString *)tableName -{ - NSString *sql = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS %@ (id integer primary key autoincrement)", tableName]; - [db_ executeUpdate:sql]; +- (void)dropTable:(NSString *)tableName { + NSString *sql = [NSString stringWithFormat:@"DROP TABLE IF EXISTS %@", tableName]; + [db_ executeUpdate:sql]; } -- (void)dropTable:(NSString *)tableName -{ - NSString *sql = [NSString stringWithFormat:@"DROP TABLE IF EXISTS %@", tableName]; - [db_ executeUpdate:sql]; +- (void)dropIndex:(NSString *)indexName { + NSString *sql = [NSString stringWithFormat:@"DROP INDEX IF EXISTS %@", indexName]; + [db_ executeUpdate:sql]; } -- (void)addColumn:(FmdbMigrationColumn *)column forTableName:(NSString *)tableName -{ - NSString *sql = [NSString stringWithFormat:@"ALTER TABLE %@ ADD COLUMN %@", tableName, [column sqlDefinition]]; - [db_ executeUpdate:sql]; +- (void)addColumn:(FmdbMigrationColumn *)column forTableName:(NSString *)tableName { + NSString *sql = [NSString stringWithFormat:@"ALTER TABLE %@ ADD COLUMN %@", tableName, [column sqlDefinition]]; + [db_ executeUpdate:sql]; } #pragma mark - #pragma mark Unit testing helpers -- (id)initWithDatabase:(FMDatabase *)db -{ - if ([super init]) { - self.db = db; - return self; - } - return nil; +- (id)initWithDatabase:(FMDatabase *)db { + if ([super init]) { + self.db = db; + return self; + } + return nil; } -- (void)dealloc -{ - [db_ release]; - - [super dealloc]; +- (void)dealloc { + [db_ release]; + + [super dealloc]; } diff --git a/fmdb-migration-manager.xcodeproj/xcuserdata/nimast.xcuserdatad/xcschemes/fmdb-migration-manager.xcscheme b/fmdb-migration-manager.xcodeproj/xcuserdata/nimast.xcuserdatad/xcschemes/fmdb-migration-manager.xcscheme new file mode 100644 index 0000000..4717b97 --- /dev/null +++ b/fmdb-migration-manager.xcodeproj/xcuserdata/nimast.xcuserdatad/xcschemes/fmdb-migration-manager.xcscheme @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/fmdb-migration-manager.xcodeproj/xcuserdata/nimast.xcuserdatad/xcschemes/xcschememanagement.plist b/fmdb-migration-manager.xcodeproj/xcuserdata/nimast.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..69a2cc6 --- /dev/null +++ b/fmdb-migration-manager.xcodeproj/xcuserdata/nimast.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,22 @@ + + + + + SchemeUserState + + fmdb-migration-manager.xcscheme + + orderHint + 31 + + + SuppressBuildableAutocreation + + D2AAC0C605546C1D00DB518D + + primary + + + + + From 30437f0d4666dcfb5dd6345ecce47a53f3cf022f Mon Sep 17 00:00:00 2001 From: Israel Roth Date: Fri, 9 Aug 2013 01:47:48 +0300 Subject: [PATCH 3/4] fixed some bugs with objective-c vs. c strings --- Classes/FmdbMigration.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Classes/FmdbMigration.m b/Classes/FmdbMigration.m index e05f39f..c134444 100644 --- a/Classes/FmdbMigration.m +++ b/Classes/FmdbMigration.m @@ -20,11 +20,11 @@ + (id)migration { #pragma mark up/down methods - (void)up { - NSLog([NSString stringWithFormat:@"%s: -up method not implemented", NSStringFromClass([self class])]); + NSLog([NSString stringWithFormat:@"%@: -up method not implemented", NSStringFromClass([self class])]); } - (void)down { - NSLog([NSString stringWithFormat:@"%s: -down method not implemented", NSStringFromClass([self class])]); + NSLog([NSString stringWithFormat:@"%@: -down method not implemented", NSStringFromClass([self class])]); } - (void)upWithDatabase:(FMDatabase *)db { @@ -41,8 +41,8 @@ - (void)downWithDatabase:(FMDatabase *)db { #pragma mark Helper methods for manipulating database schema - (void)createTable:(NSString *)tableName withColumns:(NSArray *)columns { - NSMutableArray *columnDefinitions; - [columnDefinitions addObject:"id integer primary key autoincrement"]; + NSMutableArray *columnDefinitions = [[NSMutableArray alloc] initWithCapacity:10]; + [columnDefinitions addObject:@"id integer primary key autoincrement"]; for (FmdbMigrationColumn *migrationColumn in columns) { [columnDefinitions addObject:[migrationColumn sqlDefinition]]; } From f34f116a26e8412c9c4563a5ee9a2b38ff497e65 Mon Sep 17 00:00:00 2001 From: Sha Date: Tue, 12 Nov 2013 12:39:36 +0200 Subject: [PATCH 4/4] added dropColumn method --- Classes/FmdbMigration.h | 2 ++ Classes/FmdbMigration.m | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/Classes/FmdbMigration.h b/Classes/FmdbMigration.h index a3d51c7..0b322e7 100644 --- a/Classes/FmdbMigration.h +++ b/Classes/FmdbMigration.h @@ -34,6 +34,8 @@ - (void)dropIndex:(NSString *)indexName; - (void)addColumn:(FmdbMigrationColumn *)column forTableName:(NSString *)tableName; +- (void)dropColumn:(FmdbMigrationColumn *)column forTableName:(NSString *)tableName; + // This init method exists for the purposes of unit testing. // Production code should never call this method, instead instantiate diff --git a/Classes/FmdbMigration.m b/Classes/FmdbMigration.m index c134444..5f9e3d5 100644 --- a/Classes/FmdbMigration.m +++ b/Classes/FmdbMigration.m @@ -97,6 +97,11 @@ - (void)addColumn:(FmdbMigrationColumn *)column forTableName:(NSString *)tableNa [db_ executeUpdate:sql]; } +- (void)dropColumn:(NSString *)columnName forTableName:(NSString *)tableName { + NSString *sql = [NSString stringWithFormat:@"ALTER TABLE %@ DROP COLUMN %@", tableName, columnName]; + [db_ executeUpdate:sql]; +} + #pragma mark - #pragma mark Unit testing helpers