Open vccabral opened 6 years ago
So, if you place a breakpoint on the +(void)initialize
method, you should see one for every object. Form your previous issues, it could be that the delegate is being set after opening the database?
This is inside my App delegate.
SharkORM.setDelegate(self)
SharkORM.openDatabaseNamed("dbname")
I'm running into the very same issue. After some sleuthing, I've found that the code in -[SharkSchemaManager refactorDatabase:(NSString*)database entity:(NSString*)entity]
is failing if it is called before the database is opened.
This happens with Swift because some Swift objects are initialized before the app's AppDelegate is given a chance to open the Shark database in it's init
method. refactorDatabase
is designed to handle this situation, but it fails. When SharkORM.openDatabaseNamed
is called and invokes refactorDatabase
to define entities discovered previously, the tests for a nil database fail and cause refactorDatabase
to return prematurely.
Changing refectorDatabase
to this corrects the problem:
- (void)refactorDatabase:(NSString*)database entity:(NSString*)entity {
if (!database || [database isEqualToString:@""]) {
// this is blank, so grab the default
if (SRKGlobals.sharedObject.defaultDatabaseName != nil) {
database = SRKGlobals.sharedObject.defaultDatabaseName;
}
// see if this database has been opened
if ([SRKGlobals.sharedObject handleForName:database] == nil) {
// this database will be refactored when finally opened in teh future.
return;
}
} // database != nil
// check to see if this table already exists
if (databases[entity] == nil) {
if ([entity isEqualToString:@"SmallPerson"]) {
int i=0;
}
// completely new table, so we can do this in a single operation
NSString* sql = @"CREATE TABLE IF NOT EXISTS ";
sql = [sql stringByAppendingString:entity];
sql = [sql stringByAppendingString:@" (Id "];
if ([self schemaPrimaryKeyTypeForEntity:entity] == SRK_PROPERTY_TYPE_NUMBER) {
sql = [sql stringByAppendingString:@"INTEGER PRIMARY KEY AUTOINCREMENT);"];
} else {
sql = [sql stringByAppendingString:@"TEXT PRIMARY KEY);"];
}
[SharkORM executeSQL:sql inDatabase:database];
// now add the columns in one-by-one
for (NSString* f in [self schemaPropertiesForEntity:entity]) {
sql = @"ALTER TABLE ";
sql = [sql stringByAppendingString:entity];
sql = [sql stringByAppendingString:@" ADD COLUMN "];
sql = [sql stringByAppendingString:f];
sql = [sql stringByAppendingString:@" "];
sql = [sql stringByAppendingString:[self sqlTextTypeFromColumnType:[self entityTypeToSQLSotrageType:[self schemaPropertyType:entity property:f]]]];
[SharkORM executeSQL:sql inDatabase:database];
}
} else {
NSString* sql = @"";
// existing table, so look for missing columns and add them
for (NSString* f in [self schemaPropertiesForEntity:entity]) {
if (![self databasePropertyExistsInEntity:entity property:f]) {
sql = @"ALTER TABLE ";
sql = [sql stringByAppendingString:entity];
sql = [sql stringByAppendingString:@" ADD COLUMN "];
sql = [sql stringByAppendingString:f];
sql = [sql stringByAppendingString:@" "];
sql = [sql stringByAppendingString:[self sqlTextTypeFromColumnType:[self entityTypeToSQLSotrageType:[self schemaPropertyType:entity property:f]]]];
[SharkORM executeSQL:sql inDatabase:database];
}
}
// look for changed data value types
for (NSString* f in [self schemaPropertiesForEntity:entity]) {
if ([self databasePropertyExistsInEntity:entity property:f]) {
if ([self entityTypeToSQLSotrageType:[self schemaPropertyType:entity property:f]] != [self databasePropertyTypeForEntity:entity property:f]) {
// detect change, and migrate data accordingly
}
}
}
// notify the entity class that we are between two states, all new columns have been added, but we have not removed the old ones yet.
//TODO: implement migration
// look for extra columns that need to be dropped
BOOL foundDefuncColumns = NO;
for (NSString* f in [self databasePropertiesForEntity:entity]) {
if (![self schemaPropertyExists:entity property:f]) {
foundDefuncColumns = YES;
}
}
if (foundDefuncColumns) {
// rename the old table
[SharkORM executeSQL:[NSString stringWithFormat:@"ALTER TABLE %@ RENAME TO temp_%@;", entity, entity] inDatabase:database];
// completely new table, so we can do this in a single operation
NSString* sql = @"CREATE TABLE IF NOT EXISTS ";
sql = [sql stringByAppendingString:entity];
sql = [sql stringByAppendingString:@" (Id "];
if ([self schemaPrimaryKeyTypeForEntity:entity] == SRK_PROPERTY_TYPE_NUMBER) {
sql = [sql stringByAppendingString:@"INTEGER PRIMARY KEY AUTOINCREMENT);"];
} else {
sql = [sql stringByAppendingString:@"TEXT PRIMARY KEY);"];
}
[SharkORM executeSQL:sql inDatabase:database];
// now add the columns in one-by-one
for (NSString* f in [self schemaPropertiesForEntity:entity]) {
sql = @"ALTER TABLE ";
sql = [sql stringByAppendingString:entity];
sql = [sql stringByAppendingString:@" ADD COLUMN "];
sql = [sql stringByAppendingString:[self sqlTextTypeFromColumnType:[self entityTypeToSQLSotrageType:[self schemaPropertyType:entity property:f]]]];
[SharkORM executeSQL:sql inDatabase:database];
}
// copy the data from the temp database
[SharkORM executeSQL:[NSString stringWithFormat:@"INSERT INTO %@ (%@) SELECT %@ FROM temp_%@;", entity, [[self schemaPropertiesForEntity:entity] componentsJoinedByString:@","], [[self schemaPropertiesForEntity:entity] componentsJoinedByString:@","], entity] inDatabase:database];
// drop the temp table
[SharkORM executeSQL:[NSString stringWithFormat:@"DROP TABLE temp_%@;", entity] inDatabase:database];
// clear out the indexes as they are no longer on this new table
databases[entity].indexes = [NSMutableDictionary new];
}
}
// now create and remove indexes on the tables
NSDictionary<NSString*, NSString*>* idx = [self schemaIndexDefinitionsForEntity:entity];
for (NSString* i in idx.allKeys) {
if ([self databaseIndexDefinitionsForEntity:entity][i] == nil) {
// missing index, create it now
[SharkORM executeSQL:idx[i] inDatabase:database];
}
}
// remove old indexes
idx = [self databaseIndexDefinitionsForEntity:entity];
for (NSString* i in idx.allKeys) {
if ([self schemaIndexDefinitionsForEntity:entity][i] == nil) {
// missing index, create it now
[SharkORM executeSQL:[NSString stringWithFormat:@"DROP INDEX IF EXISTS %@;", i] inDatabase:database];
}
}
}
great I have another fix for the code above even, where new columns don't get created properly. I'll bring it all together and do a release tomorrow.
Thanks @alldritt
I am attempting to use SharkORM with Swift 4.1 and the table are not being created automatically.