diff --git a/dbscripts/build_dbexport.sh b/dbscripts/build_dbexport.sh index 03da0eb..11ed009 100644 --- a/dbscripts/build_dbexport.sh +++ b/dbscripts/build_dbexport.sh @@ -9,8 +9,8 @@ DBEXPORT=database.sql # This should match what's in the application's user defaults under UD_DATABASE_MIN_VERSION -DBVERSION=19 -DBEXPANSION="Phoebe 1.0" +DBVERSION=20 +DBEXPANSION="Proteus 1.0" VERQUERY="INSERT INTO version VALUES ($DBVERSION,'$DBEXPANSION');" diff --git a/src/Core/DBManager.h b/src/Core/DBManager.h index c605168..fa5fce2 100644 --- a/src/Core/DBManager.h +++ b/src/Core/DBManager.h @@ -57,6 +57,8 @@ XmlFetcher *remoteFetcher; + NSTask *buildDBTask; + BOOL cancelling; } diff --git a/src/Core/DBManager.m b/src/Core/DBManager.m index 4bb15f5..b9176f6 100644 --- a/src/Core/DBManager.m +++ b/src/Core/DBManager.m @@ -119,9 +119,13 @@ -(IBAction)cancel:(id)sender { cancelling = YES; [remoteFetcher cancel]; - [dbDownload cancel]; - // cancelling an NSURLDownload doesn't provide any feedback so we have to do it ourselves - [self download:dbDownload didFailWithError:[NSError errorWithDomain:@"User Cancelled" code:1 userInfo:nil]]; + if( dbDownload ) + { + [dbDownload cancel]; + // cancelling an NSURLDownload doesn't provide any feedback so we have to do it ourselves + [self download:dbDownload didFailWithError:[NSError errorWithDomain:@"User Cancelled" code:1 userInfo:nil]]; + } + [buildDBTask terminate]; } -(void) progressThread:(double)currentProgress @@ -246,22 +250,24 @@ - (BOOL)checkIncludedDB #pragma mark NSURLDownload delegate methods -/* - these delegates are called from within the main thread, so there is no need for - performSelectorOnMainThread - */ -(void) downloadFinished:(NSURLDownload*)download { - [dbDownload release]; - dbDownload = nil; - - [downloadResponse release]; - downloadResponse = nil; - - NSNotification *not = [NSNotification notificationWithName:NOTE_DATABASE_DOWNLOAD_COMPLETE object:self]; - [[NSNotificationCenter defaultCenter]postNotification:not]; - - [self buildDatabase]; + @synchronized(self) + { + if( dbDownload ) + { + [dbDownload release]; + dbDownload = nil; + + [downloadResponse release]; + downloadResponse = nil; + + NSNotification *not = [NSNotification notificationWithName:NOTE_DATABASE_DOWNLOAD_COMPLETE object:self]; + [[NSNotificationCenter defaultCenter]postNotification:not]; + + [self buildDatabase]; + } + } } - (void)download:(NSURLDownload *)download didReceiveResponse:(NSURLResponse *)response @@ -348,8 +354,8 @@ -(BOOL) privateBuildDatabase buffer = malloc(MEGABYTE); - if(buffer == NULL){ - /*yeah, right*/ + if( cancelling || (buffer == NULL) ) + { fclose(fin); goto _finish_cleanup; } @@ -365,10 +371,14 @@ -(BOOL) privateBuildDatabase b64_ntop(sha_digest,SHA_DIGEST_LENGTH,(char*)buffer,MEGABYTE); - if(![sha1_bzip isEqualToString:[NSString stringWithUTF8String:(const char*)buffer]]){ - /*SHA1 Digest failed!*/ - NSLog(@"SHA1 bz2 hashing failed ('%@' != '%s')",sha1_bzip,buffer); - [self logProgressThread:@"Tarball verification failed"]; + if( cancelling || ![sha1_bzip isEqualToString:[NSString stringWithUTF8String:(const char*)buffer]] ) + { + if( !cancelling ) + { + /*SHA1 Digest failed!*/ + NSLog(@"SHA1 bz2 hashing failed ('%@' != '%s')",sha1_bzip,buffer); + [self logProgressThread:@"Tarball verification failed"]; + } fclose(fin); free(buffer); goto _finish_cleanup; @@ -381,11 +391,13 @@ -(BOOL) privateBuildDatabase str = [Config buildPathSingle:DATABASE_SQL]; fout = fopen([str fileSystemRepresentation],"w+"); - if(fout == NULL){ + if( cancelling || (fout == NULL) ) + { + if( !cancelling ) + NSLog(@"Couldn't open output file"); fclose(fin); fclose(fout); free(buffer); - NSLog(@"Couldn't open output file"); goto _finish_cleanup; } @@ -394,9 +406,13 @@ -(BOOL) privateBuildDatabase BZFILE *compress = BZ2_bzReadOpen(&bzerror,fin,0,0,NULL,0); - if(bzerror != BZ_OK){ - [self logProgressThread:@"Decompression error"]; - NSLog(@"Bzip2 error!"); + if( cancelling || (bzerror != BZ_OK) ) + { + if( !cancelling ) + { + [self logProgressThread:@"Decompression error"]; + NSLog(@"Bzip2 error!"); + } free(buffer); fclose(fin); fclose(fout); @@ -419,13 +435,16 @@ -(BOOL) privateBuildDatabase b64_ntop(sha_digest,SHA_DIGEST_LENGTH,(char*)buffer,MEGABYTE); - if(![sha1_dec isEqualToString:[NSString stringWithUTF8String:(char*)buffer]]){ - /*SHA1 Digest failed!*/ - NSLog(@"SHA1 sql hashing failed ('%@' != '%s')",sha1_dec,buffer); - [self logProgressThread:@"SQL verification failed"]; + if( cancelling || ![sha1_dec isEqualToString:[NSString stringWithUTF8String:(char*)buffer]] ) + { + if( !cancelling ) + { + /*SHA1 Digest failed!*/ + NSLog(@"SHA1 sql hashing failed ('%@' != '%s')",sha1_dec,buffer); + [self logProgressThread:@"SQL verification failed"]; + } fclose(fin); free(buffer); - //[delegate newDatabaseBuilt:self status:NO]; goto _finish_cleanup; } @@ -434,74 +453,69 @@ -(BOOL) privateBuildDatabase BZ2_bzReadClose(&bzerror,compress); fclose(fin); - [self logProgressThread: - NSLocalizedString(@"Tarball extracted and verified",) - ]; + [self logProgressThread:NSLocalizedString(@"Tarball extracted and verified",)]; [self progressThread:4.0]; str = [Config buildPathSingle:DATABASE_SQLITE_TMP]; - [[NSFileManager defaultManager] - removeItemAtPath:str error:nil]; + [[NSFileManager defaultManager] removeItemAtPath:str error:nil]; [self logProgressThread:NSLocalizedString(@"Building Database",)]; [self progressThread:5.0]; + if( cancelling ) + { + goto _finish_cleanup; + } + /* fork and exec sqlite to build the database. the old approach used C code to read the file and manually read the queries and build the DB, which was slow and crap. */ - NSTask *task = [[NSTask alloc]init]; - [task setLaunchPath:@"/usr/bin/sqlite3"]; - - NSArray *args = [NSArray arrayWithObjects: - @"-init", - [Config buildPathSingle:DATABASE_SQL], - str, - @".quit",nil]; - - [task setArguments:args]; - [task launch]; - [task waitUntilExit]; - [task release]; - + NSArray *args = [NSArray arrayWithObjects: + @"-init", + [Config buildPathSingle:DATABASE_SQL], + str, + @".quit",nil]; + buildDBTask = [NSTask launchedTaskWithLaunchPath:@"/usr/bin/sqlite3" arguments:args]; + [buildDBTask waitUntilExit]; + if( NSTaskTerminationReasonUncaughtSignal == [buildDBTask terminationReason] ) + { + if( !cancelling ) + { + NSLog( @"Failed to build database" ); + } + goto _finish_cleanup; + } + buildDBTask = nil; + [self progressThread:7.0]; NSLog(@"Database successfully built!"); /*remove the old database*/ str = [Config buildPathSingle:DATABASE_SQLITE]; - [[NSFileManager defaultManager] - removeItemAtPath:str error:nil]; + [[NSFileManager defaultManager] removeItemAtPath:str error:nil]; /*rename the file*/ str = [Config buildPathSingle:DATABASE_SQLITE_TMP]; NSString *str2 = [Config buildPathSingle:DATABASE_SQLITE]; - [[NSFileManager defaultManager] - moveItemAtPath:str - toPath:str2 - error:NULL]; - - [self logProgressThread:NSLocalizedString(@"All done! Please Restart.", - @"Database construction complete") - ]; + [[NSFileManager defaultManager] moveItemAtPath:str toPath:str2 error:NULL]; + + [self logProgressThread:NSLocalizedString(@"All done! Please Restart.", @"Database construction complete")]; status = YES; _finish_cleanup: /*remove xml defn*/ - str = [Config buildPathSingle:DBUPDATE_DEFN]; - [[NSFileManager defaultManager] - removeItemAtPath:str error:nil]; + [[NSFileManager defaultManager] removeItemAtPath:[Config buildPathSingle:DBUPDATE_DEFN] error:nil]; + /*remove sql*/ - str = [Config buildPathSingle:DATABASE_SQL]; - [[NSFileManager defaultManager] - removeItemAtPath:str error:nil]; + [[NSFileManager defaultManager] removeItemAtPath:[Config buildPathSingle:DATABASE_SQL] error:nil]; + /*remove bzip sql*/ - str = [Config buildPathSingle:DATABASE_SQL_BZ2]; - [[NSFileManager defaultManager] - removeItemAtPath:str error:nil]; + [[NSFileManager defaultManager] removeItemAtPath:[Config buildPathSingle:DATABASE_SQL_BZ2] error:nil]; return status; } diff --git a/src/Private/MainController.m b/src/Private/MainController.m index 22999aa..f32e1f1 100644 --- a/src/Private/MainController.m +++ b/src/Private/MainController.m @@ -525,7 +525,7 @@ -(void) awakeFromNib [prefDefaults setObject:@"http://labs.sixones.com/vitality/database.xml" forKey:UD_DB_UPDATE_URL]; [prefDefaults setObject:@"http://labs.sixones.com/vitality/database.sql.bz2" forKey:UD_DB_SQL_URL]; - [prefDefaults setObject:[NSNumber numberWithInt:19] forKey:UD_DATABASE_MIN_VERSION]; + [prefDefaults setObject:[NSNumber numberWithInt:20] forKey:UD_DATABASE_MIN_VERSION]; [[NSUserDefaults standardUserDefaults] registerDefaults:prefDefaults]; [prefDefaults release];