SQLite “base de données d'image de disque est incorrect”

Je vais avoir des problèmes avec une application où la base de données SQLite est corrompu. Il y avait l'étrange cas du présent auparavant, mais il semble être devenu beaucoup plus fréquent après la sortie d'iOS 7.1.

Je suis en utilisant le SQLite wrapper par Matteo Bertozzi que vous pouvez trouver ici: https://github.com/ConnorD/simple-sqlite

La base de données est corrompu et crache de l'erreur database disk image is malformed, certaines requêtes peuvent être exécutées, mais les données existantes se foiré.

J'ai cherché haut et bas et ne peut pas trouver une solution, je suis en espérant que quelqu'un ici a quelques idées, car c'est en train de devenir un problème commun après la mise à jour d'iOS.

J'ai essayé de réparation de ces commandes:

[sqlite executeNonQuery:@"pragma integrity_check"];
[sqlite executeNonQuery:@"reindex nodes"];
[sqlite executeNonQuery:@"reindex pristine"];

Et le résultat a été:

SQLite Step Failed: database disk image is malformed
SQLite Prepare Failed: unable to identify the object to be reindexed
 - Query: reindex nodes
SQLite Prepare Failed: unable to identify the object to be reindexed
 - Query: reindex pristine`

Avec quelques autres de creuser, j'ai trouvé ce problème: Les Données de base et iOS 7: comportement Différent de magasin persistant qui mentionne des problèmes avec SQLite après iOS7.

Mais je n'ai aucune idée de comment l'utiliser NSPersistentStore, donc j'ai essayé de courir [sqlite executeNonQuery:@"pragma journal_mode = DELETE"]; et il a juste dit SQLite Step Failed: unknown error.

Est quelqu'un d'autre connaît le présent, ou me diriger dans la bonne direction?

Dans l'intervalle, j'ai l'impression que c' NSPersistentStore est quelque chose que j'ai potentiellement devriez faire.. doivent regarder qui.

edit:

De ce que j'ai trouvé, vous utilisez uniquement NSPersistentStore lorsque la base de données n'est pas d'être mis à jour, dont la mienne est régulièrement.

Voici comment j'ouvre la base de données:

sqlite = [[Sqlite alloc] init];

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"HomeOpenDatabase8.sql"];

if (![sqlite open:writableDBPath]) {
    NSLog(@"DB Not Writable");
    return;
} else {
    NSLog(@"All good");
}

Donc je suppose que j'ai besoin de trouver un moyen de mettre en pragma journal_mode = DELETE de cette façon..?

edit 2:

Je ne suis pas persuadé que c'est à voir avec le journal_mode que je ne suis pas en utilisant Core Data - retour à la planche à dessin.

Le plus grand drapeau pour moi, c'est cette erreur popping up si peu de temps après iOs 7.1 a été libéré, il peut certainement pas être une coïncidence.. je vais continuer à essayer de reproduire le problème sur mon appareil.

Sont il y a certaines mesures que vous pouvez effectuer pour reproduire la corruption de manière fiable?
Je n'ai pas été capable de reproduire moi-même qui est une énorme douleur, je crois que je vais continuer d'essayer. Je ne suis plus persuadé que c'est la journal_mode soit que je ne suis pas en utilisant Core Data, donc retour à la case départ.
Pourquoi êtes-vous de jouer avec les pragmas à tous?
Je suppose que vous avez accidentellement commencé à accéder à la DB en mode multithread. Même lorsque "thread-safe", SQLite ne peut pas supporter le plein multi-threading, vous avez, au minimum, fournir la synchronisation externe pour s'assurer que les deux fils ne fonctionnent pas sur la DB simultanément. Aussi loin que je peux dire, tous les "thread-safe" n'est de permettre à des vérifications qui permettront GÉNÉRALEMENT de lever une erreur si vous tentez d'accéder simultanément.
Vous avez raison. J'ai ajouté de verrouillage à ma DB service d'accès DB SQLite par un seul thread et ça fonctionne maintenant.

OriginalL'auteur Batnom | 2014-03-25