Comment détecter si sqlite3 a créé un fichier de firebase database?

J’écris un programme qui utilise un fichier de firebase database sqlite3 pour stocker ses données. Si j’ouvre un fichier de firebase database avec

sqlite3_open_v2(filename, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL) 

le fichier de firebase database est créé s’il n’existe pas. Comment savoir si le fichier de firebase database existait avant de l’ouvrir? Le shell sqlite3 utilise le code suivant:

  /* Go ahead and open the database file if it already exists. If the ** file does not exist, delay opening it. This prevents empty database ** files from being created if a user mistypes the database name argument ** to the sqlite command-line tool. */ if( access(data.zDbFilename, 0)==0 ){ open_db(&data, 0); } 

Ce code a toutefois une condition de open_db lorsque le fichier de firebase database est créé par un autre processus après l’appel d’ access et avant l’appel open_db (heure de vérification par rapport à l’heure d’utilisation).

Une autre réponse (que je ne trouve pas pour le moment) suggère de vérifier les champs application_id et user_version . S’ils valent zéro, une firebase database vient d’être créée. J’ai étudié cette approche et constaté que de nombreuses applications ne se donnaient pas la peine de définir ces champs dans les bases de données nouvellement créées. Cette approche est donc au mieux floue et je ne pense pas que cela résout mon problème.

Existe-t-il une méthode permettant de savoir si la firebase database existait avant son ouverture sans impliquer une telle condition? Il est également acceptable si je peux simplement savoir si le fichier de firebase database a été initialisé (par exemple, un fichier tronqué a été rempli avec un en-tête sqlite3) par sqlite3.

Une telle routine a pour but de déterminer si j’ai besoin de créer toutes les tables dont j’ai besoin dans la firebase database. Je ne veux pas écraser accidentellement un autre fichier placé par une autre application.

Exemple de code

Une illustration simplifiée du problème se trouve dans le script bash suivant. Il simule deux applications. Ils travaillent tous les deux de la même manière:

  1. Créer ou ouvrir une firebase database test.db
  2. Si la firebase database n’existait pas auparavant, créez un test table et écrivez-y une seule ligne. La valeur est 1 pour la première application et 2 pour la seconde.
  3. Imprimez le contenu de la firebase database.

Voici le code:

 #!/bin/sh # sleeps are inserted to make the race conditions easier to sortinggger application() { echo Checking if database exists... [ ! -f test.db ] status=$? sleep 2 if (exit $status) then echo Database not found, making tables sqlite3 test.db "CREATE TABLE IF NOT EXISTS test (a);" sleep 2 echo Writing initial record into database sqlite3 test.db "INSERT INTO test VALUES ($1);" sleep 2 else echo Database found, checking if it belongs to me fi echo Printing content of database sqlite3 test.db "SELECT * FROM test;" } rm -f test.db echo First test: app1 and app1 race application 1 & (sleep 1 ; application 1) rm -f test.db echo Second test: app2 and app1 race application 2 & (sleep 1 ; application 1) 

Mon objective est de faire en sorte que les cas suivants ne puissent jamais se produire:

  • Une instance d’application one ouvre le fichier de firebase database, conclut qu’il n’est pas initialisé et l’initialise (en créant la table et en écrivant l’enregistrement initial) même si elle contient déjà des données provenant d’une autre instance de la même application ou d’une autre application. .
  • Un fichier de firebase database appartenant à une application différente est écrit dans.

Si l’ application était programmée correctement, chaque exécution n’initialisera la firebase database que si elle ne l’était pas auparavant. Ainsi, le seul résultat visible est soit une firebase database contenant uniquement la ligne 1 soit une firebase database contenant uniquement la ligne 2 .

Il n’est pas possible de différencier une firebase database nouvellement créée d’une firebase database vide créée précédemment.

Cependant, une firebase database vide est la seule avec ce problème. Toute autre firebase database peut être détectée en vérifiant si la table sqlite_master n’est pas vide. Faites ceci et votre création de table dans une transaction, et il n’y a pas de condition de concurrence critique.

Si votre première écriture dans la firebase database (c’est-à-dire lorsque le fichier est créé) définit l’identifiant d’ application ( Application_id) , alors vous savez que tout fichier portant un autre ID n’est pas le vôtre. (Les identifiants d’application enregistrés sont uniques.)