Stockage De La base de données SQLite sur Android et Phonegap

je développe une application Android Cordova/Phonegap où je veux utiliser une base de données SQLite. J'ai utilisé l'exemple du document officiel documentation .

// Wait for device API libraries to load
//
document.addEventListener("deviceready", onDeviceReady, false);

// Populate the database
//
function populateDB(tx) {
    tx.executeSql('DROP TABLE IF EXISTS DEMO');
    tx.executeSql('CREATE TABLE IF NOT EXISTS DEMO (id unique, data)');
    tx.executeSql('INSERT INTO DEMO (id, data) VALUES (1, "First row")');
    tx.executeSql('INSERT INTO DEMO (id, data) VALUES (2, "Second row")');
}

// Query the database
//
function queryDB(tx) {
    tx.executeSql('SELECT * FROM DEMO', [], querySuccess, errorCB);
}

// Query the success callback
//
function querySuccess(tx, results) {
    var len = results.rows.length;
    console.log("DEMO table: " + len + " rows found.");
    for (var i=0; i<len; i++){
        console.log("Row = " + i + " ID = " + results.rows.item(i).id + " Data =  " + results.rows.item(i).data);
    }
}

// Transaction error callback
//
function errorCB(err) {
    console.log("Error processing SQL: "+err.code);
}

// Transaction success callback
//
function successCB() {
    var db = window.openDatabase("Database", "1.0", "Cordova Demo", 200000);
    db.transaction(queryDB, errorCB);
}

// device APIs are available
//
function onDeviceReady() {
    var db = window.openDatabase("Database", "1.0", "Cordova Demo", 200000);
    db.transaction(populateDB, errorCB, successCB);
}

bien que cela semble fonctionner (la base de données est créée et remplie sans erreur, et je récupère les données écrites avec la requête), je me demande comment la base de données est stockée sur mon appareil. Pour déboguer, j'utilise un téléphone Matériel avec Android 4.1.1.

le la base de données est située sous /data/data/<myapppackage>/app_database/file__0/0000000000000001.db . Maintenant je voulais exporter la base de données et l'analyser manuellement sur mon pc avec SQLiteManager, mais il semble que les modifications ne sont pas écrites dans le fichier db.

Cependant, en examinant le répertoire /data/data/<myapppackage>/app_database/file__0/ j'ai trouvé les deux fichiers temporaires 0000000000000001.db-shm et 0000000000000001.db-wal , dont les horodateurs sont changés chaque fois que j'effectue une opération de base de données, mais jamais le fichier db lui-même.

ma question est, pourquoi sont les changements jamais écrit dans le fichier de base de données persistant? Il ne semble pas y avoir de moyen de fermer une connexion de base de données avec phonegap, et même le fait de tuer l'application manuellement n'écrit pas les changements à la .le fichier db. Je ne suis pas sûr de ce que j'ai fait de mal.

Quelqu'un voit le problème ici?

12
demandé sur qefzec 2013-10-24 19:58:40

3 réponses

tx.executeSql('DROP TABLE IF EXISTS DEMO');

cette ligne ci-dessus supprime la table nommée DEMO chaque fois que vous démarrez votre application mobile PhoneGap

et je voulais juste te dire que j'aime ton code. Il donne un très bon indice sur "ce qu'il faut faire" pour L'application PhoneGap ou Cordova de n'importe qui. Cela aidera grandement quiconque entre dans le monde de SQLite pour la première fois.

votre code est très propre à lire et à comprendre par rapport aux codes écrits sur Cordova / PhoneGap SQLite plugin Site officiel sur GitHub.

mon ami, qui travaille aussi comme CTO d'une entreprise, et a beaucoup d'expérience avec SQLite, m'a dit qu'il n'est pas nécessaire de fermer une connexion de base de données SQLite manuellement, et aussi fortement recommandé SQLite.

et pour toute autre personne à la recherche de SQLite pour information PhoneGap/Cordova -

let's dites que vous avez une table nommée mytable et que vous voulez stocker des valeurs "beautiful" et "dolphin

quand vous voulez effectuer une opération sur le SQLite d'un appareil mobile, tel qu'une tablette ou un téléphone, rappelez-vous de l'appeler de cette façon

ont le suivant dans votre code source

function insertNewLine(tx) 
{
   tx.executeSql("INSERT INTO mytable (word, meaning) VALUES (?,?)", [ var1 , var2 ]);
}

et stocker "beautiful" à l'intérieur de var1 et "dolphin" à l'intérieur de var2 et

faire la déclaration suivante afin d'exécuter la déclaration SQL insert puis enregistrer à l'intérieur de l'appareil.

db.transaction(insertNewLine);   

Ne pas appeler directement insertNewLine(tx)

Ne pas d'appeler directement le tx.executeSql (/*SQL INSERT STATEMENT */); in your JavaScript sourcecode

et ne pas inclure les valeurs directement dans L'énoncé de requête SQL et ensuite exécuter L'énoncé SQL qui comprend le valeurs que vous voulez stocker dans la base de données.

en d'autres termes, ce qui suit est incorrect

tx.executeSql('INSERT INTO mytable (word, meaning) values (beautiful, dolphin)');

ce qui précède est incorrect parce que les valeurs que vous voulez stocker," beautiful "et" dolphin " sont inclus à l'intérieur de la déclaration SQL. Ils doivent être séparés.

ce qui suit est la bonne façon d'exécuter le SQL INSERT

tx.executeSql("INSERT INTO mytable (word, meaning) VALUES (?,?)", [ var1 , var2 ]);
 // Notice that the values you want to store, beautiful and dolphin
 // are separate from the SQL INSERT INTO statement

et puis effectuer la totalité transaction de base de données en incluant ce qui suit dans votre code JavaScript

db.transaction(insertNewLine);

pas le code ci-dessous

tx.executeSql("INSERT....."); // this will not save your values onto the device

ni le code ci-dessous

"
insertNewLine(tx); // this will not save your values onto the device either.  

et pour utiliser la déclaration SELECT SQL, ont le code suivant

// Get all lines in the table
//
function viewthelastglory(tx)  
{
    tx.executeSql( 'SELECT * FROM CUSTOMTABLE', [], querySuccess, errorcode );
}

// Deal with the lines 
//
function querySuccess(tx, results) 
{
   var len = results.rows.length; var  queryresult = "all entries ";

   for (var i = 0 ; i < len ; i++)
   {
       queryresult =  queryresult +  

       " Row - " + i + 
       " Word - " + results.rows.item(i).word + 
       " Meaning - " + results.rows.item(i).meaning;
   }

// and now, you can use the queryresult variable to use the values   
}

function errorcode(errorhaha) 
{
    alert("Error Code " + errorhaha.code + " Error Message " + errorhaha.message);
}

et ensuite, effectuer la transaction de base de données

db.transaction(viewthelastglory);

Si vous essayez d'en choisir un à partir de SQLite, WebSQL et IndexedDB, s'il vous plaît rappelez-vous que j'ai cherché autour de stackoverflow pendant un certain temps et appris que

  • personne n'aime IndexedDB en raison de sa complexité
  • IndexedDB est incompatible avec de nombreux types et versions de systèmes D'exploitation mobiles""
  • WebSQL a été déprécié par W3C
  • WebSQL renvoie 673K de résultats mais SQLite renvoie 1800K de résultats. IndexedDB retourne 300K les résultats sur Google
  • parmi IndexedDB, SQLite et WebSQL, SQLite est le seul à avoir un site officiel.

la commande suivante à la ligne de commande pendant que vous êtes dans le répertoire de votre projet Cordova installera le plugin SQLite dans votre projet Cordova

cordova plugin add https://github.com/brodysoft/Cordova-SQLitePlugin
11
répondu KershawRocks 2014-09-15 03:11:31

la solution est de déboguer votre application avec un émulateur au lieu d'un dispositif physique.

lancez votre application avec emulator au lieu du périphérique physique. Vous trouverez votre fichier database dans /data/data/YOUR_PACKAGE_NAME/app_database/ . Vous pouvez pull le fichier database et parcourir les tableaux et les données.

0
répondu Lekhnath 2013-11-01 05:22:21

dans Wal mode , tout changement est écrit dans le fichier -wal ; le fichier de base de données lui-même n'est pas mis à jour jusqu'à ce qu'un checkpoint soit fait.

S'il y a un fichier -wal , vous devez le copier aussi.

0
répondu CL. 2014-08-04 09:30:49