Il 16/08/2010 18.54, Black, Michael (IS) ha scritto: > Can you post your code? In particular the place where it fails and you retry? > >
Here's the thread execution loop: - (void)main { [[NSThread currentThread] setName:@"WriteThread"]; while (![self isCancelled]) { DBObject *obj=[objQueue poll]; if(obj==nil) break; @try{ [connector writeObject:obj]; } @catch (NSException *e) { [self logMessage:[NSString stringWithFormat:@"Exception during writing. %@ : %@", [e name], [e reason]]]; [[DBHandler instance] abort]; return; } writtenItems++; [[NSNotificationCenter defaultCenter] postNotificationName:@"WriteCount" object:[NSNumber numberWithInt:writtenItems]]; } [[DBHandler instance] writingDidFinish]; } Here's the writing code: - (void) writeObject:(DBObject*)obj { int count =0; bool correct=false; while (!correct || count == 5) { sqlite3_stmt *statement = [obj insertStatementForSQLite:sqliteDB]; [self checkErr:sqlite3_step(statement)]; [self checkErr:sqlite3_finalize(statement)]; correct=[self verifyOrDeleteObject:obj]; if (!correct) { count++; } } if (!correct) @throw [NSException exceptionWithName:@"InsertException" reason:@"Insertion failed 5 times" userInfo:nil]; } Here 'obj' belongs to one of the 3 classes that represents the 3 tables I'm working with. The insertStatementForSQLite: call generates a sqlite3_stmt ready to execute, with all the parameters already bound. checkErr: just throws an exception and aborts if the return code from SQLite is not OK. verifyOrDeleteObject: does a SELECT for a single field of the inserted record and compares it with the original DBObject, deleting it and returning false if it doesn't match. Finally here's the statement generation code for the table that gets the corrupted record: - (sqlite3_stmt*) insertStatementForSQLite:(sqlite3*)handle { char *stString ="INSERT INTO z_lemma_tbl(lemma_id, lemma_FK_testo_id, lemma_ricerca, lemma_ordine, lemma_visualizzato, lemma_category, lemma_FK_dizionario_id, lemma_hash, lemma_ordine_icoge) values(?,?,?,?,?,?,?,?,?);"; sqlite3_stmt *statement; int err=sqlite3_prepare_v2(handle, stString, -1, &statement, NULL); if (err!=SQLITE_OK) @throw [NSException exceptionWithName:@"SQLite error" reason:[NSString stringWithCString:sqlite3_errmsg(handle) encoding:NSUTF8StringEncoding] userInfo:nil]; sqlite3_bind_int(statement, 1, self.idLemma); sqlite3_bind_int(statement, 2, self.idTesto); sqlite3_bind_text(statement, 3, [self.lemmaRicerca cStringUsingEncoding:NSUTF8StringEncoding], [self.lemmaRicerca lengthOfBytesUsingEncoding:NSUTF8StringEncoding], SQLITE_STATIC); sqlite3_bind_text(statement, 4, [self.lemmaOrdine cStringUsingEncoding:NSUTF8StringEncoding], [self.lemmaOrdine lengthOfBytesUsingEncoding:NSUTF8StringEncoding], SQLITE_STATIC); sqlite3_bind_text(statement, 5, [self.lemmaVisualizzato cStringUsingEncoding:NSUTF8StringEncoding], [self.lemmaVisualizzato lengthOfBytesUsingEncoding:NSUTF8StringEncoding], SQLITE_STATIC); sqlite3_bind_text(statement, 6, [self.lemmaCategoria cStringUsingEncoding:NSUTF8StringEncoding], [self.lemmaCategoria lengthOfBytesUsingEncoding:NSUTF8StringEncoding], SQLITE_STATIC); sqlite3_bind_int(statement, 7, self.idDizionario); sqlite3_bind_text(statement, 8, [self.hashCode cStringUsingEncoding:NSUTF8StringEncoding], [self.hashCode lengthOfBytesUsingEncoding:NSUTF8StringEncoding], SQLITE_STATIC); sqlite3_bind_int(statement, 9, self.idIcoge); return statement; } I'm using SQLITE_STATIC since the memory buffer returned by cStringUsingEncoding should be valid until the object is deallocated, which doesn't happen until after the statement is executed. Thanks for your help. > From: sqlite-users-boun...@sqlite.org on behalf of Dario Napolitano > Sent: Mon 8/16/2010 11:33 AM > To: sqlite-users@sqlite.org > Subject: EXTERNAL:[sqlite] Record corruption on Mac OS X 10.6 (Snow Leopard) > > > > Hello everyone. > I have developed a conversion tool to generate a SQLite database from a > MySQL one. The tool is a simple C Cocoa application in which I have > statically compiled the amalgamation source of SQLite. The tool has a > reading thread that pulls records from MySQL and a writing thread that > saves them into the SQLite database, via a locking queue. The SQLite > connection is created on the main thread and then handed off to the > writing thread which is the only one to use it. > > This tool worked correctly under Mac Os 10.5 (Leopard), but since > upgrading to Snow Leopard the output database contains several corrupted > records (about 300 out of 75000). The corrupted records are generally > random (different on each execution) and are corrupted *only* in the > TEXT columns, while INTEGER and BLOB columns are unharmed. Also the > corruption only happens in one of the 3 tables that are processed, the > one with several TEXT fields. The corruption involves *all* the TEXT > fields in a record or none at all. > > I have done extensive debugging to rule out unrelated causes. > Specifically I have also tried to issue the INSERT statement followed by > a SELECT to check what was just inserted by comparing it with the same > memory buffer: the data that goes into the INSERT is not the same that > comes back with the SELECT. Also, upon detecting the corruption, the > program deletes the just inserted record and issues the same INSERT > statement, which manages to correctly insert the data. Without the > workaround out of about 75000 records about 300 end up corrupted, > whereas with the 'try-again' method I found no corrupted records > afterwards. I used the same check on the far larger BLOB records and > there was no issue with them. > > Has anyone had the same experience? Any clue on what might have caused > it? It definitely seems related to Os X 10.6, as it worked on 2 distinct > Macs with 10.5 and it fails on both with 10.6. > > Thanks for any help. > > _______________________________________________ > sqlite-users mailing list > sqlite-users@sqlite.org > http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users > > > > > > _______________________________________________ > sqlite-users mailing list > sqlite-users@sqlite.org > http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users > -- Dario Napolitano Liberologico s.r.l. Ai sensi del D. Lgs. n.196 del 30/06/2003 si precisa che le informazioni contenute in questo messaggio sono riservate e ad uso esclusivo del destinatario. Qualora il messaggio in parola Le fosse pervenuto per errore, La preghiamo di eliminarlo senza copiarlo e di non inoltrarlo a terzi, dandocene gentilmente comunicazione. Grazie This message, for the D. Lgs. n.196 of 30/06/2003, may contain confidential and/or privileged information. If you are not the addressee or authorized to receive this for the addressee, you must not use, copy, disclose or take any action based on this message or any information herein. If you have received this message in error, please advise the sender immediately by reply e-mail and delete this message. Thank you for your cooperation. _______________________________________________ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users