diff --git a/Classes/FmdbMigration.h b/Classes/FmdbMigration.h
index d0e4802..0b322e7 100644
--- a/Classes/FmdbMigration.h
+++ b/Classes/FmdbMigration.h
@@ -25,12 +25,21 @@
- (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;
+- (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
// your subclasses with +migration method.
- (id)initWithDatabase:(FMDatabase *)db;
+
@end
diff --git a/Classes/FmdbMigration.m b/Classes/FmdbMigration.m
index 33253d1..5f9e3d5 100644
--- a/Classes/FmdbMigration.m
+++ b/Classes/FmdbMigration.m
@@ -10,62 +10,95 @@
@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:@"%@: -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:@"%@: -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
-{
- [self createTable:tableName];
- for (FmdbMigrationColumn *migrationColumn in columns) {
- [self addColumn:migrationColumn forTableName:tableName];
- }
+- (void)createTable:(NSString *)tableName withColumns:(NSArray *)columns {
+ NSMutableArray *columnDefinitions = [[NSMutableArray alloc] initWithCapacity:10];
+ [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
-{
- NSString *sql = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS %@ (id integer primary key autoincrement)", tableName];
- [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)dropTable:(NSString *)tableName
-{
- NSString *sql = [NSString stringWithFormat:@"DROP TABLE IF EXISTS %@", tableName];
- [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)addColumn:(FmdbMigrationColumn *)column forTableName:(NSString *)tableName
-{
- NSString *sql = [NSString stringWithFormat:@"ALTER TABLE %@ ADD COLUMN %@", tableName, [column sqlDefinition]];
+- (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)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)dropColumn:(NSString *)columnName forTableName:(NSString *)tableName {
+ NSString *sql = [NSString stringWithFormat:@"ALTER TABLE %@ DROP COLUMN %@", tableName, columnName];
[db_ executeUpdate:sql];
}
@@ -73,20 +106,18 @@ - (void)addColumn:(FmdbMigrationColumn *)column forTableName:(NSString *)tableNa
#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/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;
}
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
+
+
+
+
+