Skip to content

Instantly share code, notes, and snippets.

@HHuckebein
Created April 8, 2013 07:58
Show Gist options
  • Save HHuckebein/5335034 to your computer and use it in GitHub Desktop.
Save HHuckebein/5335034 to your computer and use it in GitHub Desktop.
Convert SQLite database into a CoreDate model - uses Marus Zarras - ..prefix.pch add-on Bill Dudney - SQLiteAccess.m/.h
//
// AppDelegate+ImportDB.m
// LogBook
//
// Created by Bernd Rabe on 16.09.10.
// Copyright 2010 RABE_IT Services. All rights reserved.
//
// Helper
#import "NSDateFormatter+DateFromStringExtension.h"
#import "NSManagedObject+ToolBox.h"
#import "NSEntityDescription+Toolbox.h"
// Main
#import "AppDelegate+ImportDB.h"
#import <CoreLocation/CoreLocation.h>
#import "SQLiteAccess.h"
@implementation AppDelegate (ImportDB)
#pragma mark - Common Entity Import
/*
properties - read from sqlite database (keys are value)
be aware of the fact, that the following method only works correctly
if the property names to be inserted in core data correspond to each other
except property names ending with "URI"
initialize will try to find a corresponding relation object by removing the URI part on the core data side
exception: properties of type NSString ending with Normalized
used for search in conjunction with NormalizedStringTransformer.h/.m
we look for a sqlite
breaks if an not optional property is not initialized
exception: property names ending of Type NSDateAttributeType with "Date" or "Time"
ending with Date expects a date in the format specified in Definitions.h (here yyy-MM-dd)
ending with Time expects a time in the format specified in Definitions.h (here HH:mm)
*/
- (void)initializeManagedObject:(NSManagedObject *)managedObject withEntityDescription:(NSEntityDescription *)entityDescription
properties:(NSDictionary *)properties andRelations:(NSDictionary *)relations
{
NSString *value, *valueTransformerClassName;
NSRange range;
NSAttributeDescription *desc = nil;
BOOL isOptional = YES, propertyExists = YES;
NSDictionary *allProperties = [entityDescription attributesByName];
// NSPredicate *predicateFindAllStringsWithoutURI = [NSPredicate predicateWithFormat:@"self matches '.{1,}(?<!URI)$'"];
// NSArray *filteredPropertiesWOURI = [[allProperties allKeys] filteredArrayUsingPredicate:predicateFindAllStringsWithoutURI];
for (NSString *key in allProperties) {
ZAssert(!(!isOptional && !propertyExists), @"Property %@ in %@ is not optional!\n%@", [desc name], [entityDescription managedObjectClassName], properties);
desc = [allProperties valueForKey:key];
isOptional = [desc isOptional], propertyExists = YES;
switch ([desc attributeType]) {
case NSInteger16AttributeType:
case NSInteger32AttributeType:
case NSInteger64AttributeType:
value = [properties valueForKey:[desc name]];
if ([value isKindOfClass:[NSString class]]) {
[managedObject setValue:[NSNumber numberWithInteger:[value integerValue]] forKey:[desc name]];
}
else {
propertyExists = NO;
}
break;
case NSDoubleAttributeType:
value = [properties valueForKey:[desc name]];
if ([value isKindOfClass:[NSString class]]) {
[managedObject setValue:[NSNumber numberWithDouble:[value doubleValue]] forKey:[desc name]];
}
else {
propertyExists = NO;
}
break;
case NSFloatAttributeType:
value = [properties valueForKey:[desc name]];
if ([value isKindOfClass:[NSString class]]) {
[managedObject setValue:[NSNumber numberWithFloat:[value floatValue]] forKey:[desc name]];
}
else {
propertyExists = NO;
}
break;
case NSStringAttributeType:
// if the name contains Normalized we wanna
// use hte name without "Normalized" and process that
// value here
range = [[desc name] rangeOfString:@"Normalized"];
if (range.location != NSNotFound) {
value = [properties valueForKey:[[desc name] substringToIndex:range.location]];
if (value && [value isKindOfClass:[NSString class]]) {
[managedObject setValue:value forKey:[desc name]];
}
else {
propertyExists = NO;
}
}
else {
value = [properties valueForKey:[desc name]];
if ([value isKindOfClass:[NSString class]]) {
[managedObject setValue:value forKey:[desc name]];
}
else {
propertyExists = NO;
}
}
break;
case NSBooleanAttributeType:
value = [properties valueForKey:[desc name]];
if ([value isKindOfClass:[NSString class]]) {
[managedObject setValue:[NSNumber numberWithBool:[value boolValue]] forKey:[desc name]];
}
else {
propertyExists = NO;
}
break;
case NSDateAttributeType:
value = [properties valueForKey:[desc name]];
if ([value isKindOfClass:[NSString class]]) {
NSInteger found = [[desc name] rangeOfString:@"Date" options:NSLiteralSearch range:NSMakeRange([[desc name] length] - [@"Date" length], [@"Date" length])].location;
if (found != NSNotFound) {
[managedObject setValue:[NSDateFormatter dateFromString:value withFormat:kDateFormat] forKey:[desc name]];
}
else {
found = [[desc name] rangeOfString:@"Time" options:NSLiteralSearch range:NSMakeRange([[desc name] length] - [@"Time" length], [@"Time" length])].location;
if (found != NSNotFound) {
[managedObject setValue:[NSDateFormatter timeFromString:value withFormat:kTimeFormat] forKey:[desc name]];
}
else {
propertyExists = NO;
}
}
}
else {
propertyExists = NO;
}
break;
case NSTransformableAttributeType:
value = [properties valueForKey:[desc name]];
if (![value isKindOfClass:[NSNull class]]) {
valueTransformerClassName = [desc valueTransformerName];
NSInteger foundClass = [valueTransformerClassName rangeOfString:@"Number"].location;
if (foundClass != NSNotFound) {
NSInteger foundDescription = [valueTransformerClassName rangeOfString:@"Double"].location;
if (foundDescription != NSNotFound) {
NSNumber *number = [NSNumber numberWithDouble:[value doubleValue]];
[managedObject setValue:number forKey:[desc name]];
}
}
else {
foundClass = [valueTransformerClassName rangeOfString:@"String"].location;
if (foundClass != NSNotFound) {
[managedObject setValue:value forKey:[desc name]];
}
}
}
if (!isOptional && [managedObject valueForKey:[desc name]] == nil) {
propertyExists = NO;
}
break;
default:
break;
}
}
if (relations) {
isOptional = YES, propertyExists = YES;
NSPredicate *predicateFindURIString = [NSPredicate predicateWithFormat:@"self matches '.{1,}URI$'"];
NSArray *relationArray = [[allProperties allKeys] filteredArrayUsingPredicate:predicateFindURIString];
for (NSString *relation in relationArray) {
ZAssert(!(!isOptional && !propertyExists), @"Relation %@ in %@ is not optional!\n%@", [desc name], [entityDescription managedObjectClassName], relations);
desc = [allProperties valueForKey:relation];
isOptional = [desc isOptional], propertyExists = YES;
switch ([desc attributeType]) {
case NSStringAttributeType:
value = [relations valueForKey:[desc name]];
if ([value isKindOfClass:[NSString class]]) {
[managedObject setValue:value forKey:[desc name]];
}
else {
propertyExists = NO;
}
break;
default:
break;
}
}
}
}
#pragma mark - Init Default Database
- (void)initDefaultDB
{
NSString *indexString = nil;
// Initialize Continent/Country/SubDivision Entities Continent Init
NSArray *continents = nil, *countries = nil, *subDivisions = nil;
NSEntityDescription *continentEntityDesc = [NSEntityDescription entityForName:kClassContinent inManagedObjectContext:self.dataModel.moc];
NSEntityDescription *countryEntityDesc = [NSEntityDescription entityForName:kClassCountry inManagedObjectContext:self.dataModel.moc];
NSEntityDescription *subDivisionEntityDesc = [NSEntityDescription entityForName:kClassSubDivision inManagedObjectContext:self.dataModel.moc];
NSEntityDescription *airportEntityDesc = [NSEntityDescription entityForName:kClassAirport inManagedObjectContext:self.dataModel.moc];
NSEntityDescription *licenceTypeEntityDesc = [NSEntityDescription entityForName:kClassLicenceType inManagedObjectContext:self.dataModel.moc];
NSEntityDescription *ratingEntityDesc = [NSEntityDescription entityForName:kClassRating inManagedObjectContext:self.dataModel.moc];
NSEntityDescription *pilotEntityDesc = [NSEntityDescription entityForName:kClassPilot inManagedObjectContext:self.dataModel.moc];
NSEntityDescription *manufacturerEntityDesc = [NSEntityDescription entityForName:kClassManufacturer inManagedObjectContext:self.dataModel.moc];
NSEntityDescription *attendantEntityDesc = [NSEntityDescription entityForName:kClassAttendant inManagedObjectContext:self.dataModel.moc];
NSEntityDescription *pilotMedicalEntityDesc = [NSEntityDescription entityForName:kClassPilotMedical inManagedObjectContext:self.dataModel.moc];
NSEntityDescription *pilotLicenceEntityDesc = [NSEntityDescription entityForName:kClassPilotLicence inManagedObjectContext:self.dataModel.moc];
NSEntityDescription *pilotAircaftEntityDesc = [NSEntityDescription entityForName:kClassPilotAircraft inManagedObjectContext:self.dataModel.moc];
NSEntityDescription *pilotFlightLogEntityDesc = [NSEntityDescription entityForName:kClassPilotFlightLog inManagedObjectContext:self.dataModel.moc];
NSEntityDescription *pilotOthersEntityDesc = [NSEntityDescription entityForName:kClassPilotOthers inManagedObjectContext:self.dataModel.moc];
continents = [[NSArray alloc] initWithArray:[self runSelectManyRowsWithSQL:@"SELECT * FROM Continents ORDER BY name;"]];
for (NSDictionary *continentItem in continents) {
Continent *newContinent = [NSEntityDescription insertNewObjectForEntityForName:kClassContinent
inManagedObjectContext:self.dataModel.moc
assignPersistentStoreSkipDefaultConfiguration:YES];
[self initializeManagedObject:newContinent withEntityDescription:continentEntityDesc properties:continentItem andRelations:nil];
}
[self.dataModel saveContext];
#pragma mark - Helper
- (NSPredicate *)predicateForPropertiesStartingWith:(NSString *)identifier
{
NSDictionary *variables = [[NSDictionary alloc] initWithObjectsAndKeys:identifier, @"IDENTIFIER", nil];
static NSPredicate *predicate = nil;
if (predicate == nil) {
predicate = [NSPredicate predicateWithFormat:@"self BEGINSWITH $IDENTIFIER"];
}
NSPredicate *findPredicate = [predicate predicateWithSubstitutionVariables:variables];
return findPredicate;
}
#pragma mark - SQLiteAccess
- (NSArray *)runSelectManyValuesWithSQL:(NSString *)query
{
DLog(@"%@", query);
return [SQLiteAccess selectManyValuesWithSQL:query];
}
- (NSString *)runSelectOneValueWithSQL:(NSString *)query
{
DLog(@"%@", query);
return [SQLiteAccess selectOneValueSQL:query];
}
- (NSArray *)runSelectManyRowsWithSQL:(NSString *)query
{
DLog(@"%@", query);
return [SQLiteAccess selectManyRowsWithSQL:query];
}
- (NSDictionary *)runSelectOneRowWithSQL:(NSString *)query
{
DLog(@"%@", query);
return [SQLiteAccess selectOneRowWithSQL:query];
}
- (NSNumber *)insertWithSQL:(NSString *)query
{
DLog(@"%@", query);
return [SQLiteAccess insertWithSQL:query];
}
- (void)updateWithSQL:(NSString *)query
{
DLog(@"%@", query);
return [SQLiteAccess updateWithSQL:query];
}
- (void)deleteWithSQL:(NSString *)query
{
DLog(@"%@", query);
return [SQLiteAccess deleteWithSQL:query];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment