I'm developing a Android Cordova/Phonegap app where I want to use a SQLite database. I used the example from the official 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);
}
Although this seems to work (the database is created and filled without errors, and I get the written data back with the query), I'm wondering how the database is stored on my device. For debugging I use a hardware phone with Android 4.1.1.
The database is located under /data/data/<myapppackage>/app_database/file__0/0000000000000001.db. Now I wanted to export the database and analyze it manually on my pc with SQLiteManager, but it seems the changes are not written to the db file.
However, when examining the directory /data/data/<myapppackage>/app_database/file__0/ i found the two temporary files 0000000000000001.db-shm and 0000000000000001.db-wal, whose timestamps are changed every time I perform a database operation, but never the db file itself.
My question is, why are the changes never written to the persistent database file? There does not seem to be a way to close a database connection with phonegap, and even killing the app manually doesn't write the changes to the .db file. I'm not sure what I did wrong.
Anyone seeing the problem here?
tx.executeSql('DROP TABLE IF EXISTS DEMO');
This line above deletes the table named DEMO everytime you start your PhoneGap mobile application
And I just wanted to tell you I love your code. It gives a very good clue about "what to do" for anyone's PhoneGap or Cordova application. It will greatly help anyone who is entering the world of SQLite for the first time.
Your code is very clean to read and understand compared to the codes written on Cordova/PhoneGap SQLite plugin official website on GitHub.
My friend, who also works as the CTO of a company, and has a plenty of experience with SQLite, told me that it is not necessary to close a SQLite database connection manually, and also greatly recommended SQLite.
And for anyone else looking for SQLite for PhoneGap/Cordova information -
Let's say you have a table named mytable and want to store values "beautiful" and "dolphin"
When you want to perform an operation on the SQLite of a mobile device, such as a tablet or phone, remember to call it this way
Have the following in your source code
function insertNewLine(tx)
{
tx.executeSql("INSERT INTO mytable (word, meaning) VALUES (?,?)", [ var1 , var2 ]);
}
and store "beautiful" inside var1 and "dolphin" inside var2 and
do the following statement in order to execute the SQL insert statement and then save inside the device.
db.transaction(insertNewLine);
Do not directly call insertNewLine(tx)
Do not directly call tx.executeSql( /* SQL INSERT STATEMENT */ ); in your JavaScript sourcecode
And do not include the values straight into the SQL query statement and then run the SQL statement that includes the values you want to store in the database.
In other words, the following is incorrect
tx.executeSql('INSERT INTO mytable (word, meaning) values (beautiful, dolphin)');
The above is incorrect because the values you want to store, "beautiful" and "dolphin" are included inside the SQL statement. They should be separate.
The following is the correct way to run the INSERT SQL
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
and then perform the entire database transaction by including the following in your JavaScript code
db.transaction(insertNewLine);
not the below code
tx.executeSql("INSERT....."); // this will not save your values onto the device
not the below code either
insertNewLine(tx); // this will not save your values onto the device either.
And to use the SELECT SQL statement, have the following code
// 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);
}
And then, perform the database transaction
db.transaction(viewthelastglory);
If you are trying to choose one from SQLite, WebSQL and IndexedDB, please remember that I searched around stackoverflow for a while and learned that
Nobody likes IndexedDB because of its complexity
IndexedDB is incompatible with many types and versions of mobile OS
WebSQL has been deprecated by W3C
WebSQL returns 673K results but SQLite returns 1800K results. IndexedDB returns 300K results on Google
Among IndexedDB, SQLite and WebSQL, SQLite is the only one with an official website.
The following command at the command line while you are in the directory of your Cordova project will install the SQLite plugin into your Cordova project
cordova plugin add https://github.com/brodysoft/Cordova-SQLitePlugin
The solution is : Debug your app with emulator instead of physical device.
Run your app with emulator instead of physical device. You will find your database file in /data/data/YOUR_PACKAGE_NAME/app_database/. You can pull the database file and browse the tables and data.
In WAL mode, any changes are written to the -wal file; the database file itself does not get updated until a checkpoint is done.
If there is a -wal file, you must copy it, too.
Related
I am new to react native so please forgive me If I ask anything wrong. I am integrating sqlite (https://github.com/andpor/react-native-sqlite-storage) to store data locally on my device and I am able to create table with insert record and fetch but not able to find out where all the queries are stored mean where it create database file in our app.
Below is the code:
let SQLite = require('react-native-sqlite-storage')
let db = SQLite.openDatabase({name: 'user_consultant.db', location:'Library'}, this.openCB, this.errorCB);
db.transaction((tx) => {
tx.executeSql('CREATE TABLE IF NOT EXISTS category (ID Integer PRIMARY KEY AUTOINCREMENT,NAME varchar(25))', [], (tx, results) => {
// Get rows with Web SQL Database spec compliance.
alert(JSON.stringify(results));
},(err) => {
alert('error '+JSON.stringify(err));
});
});
I want to store this table in database and also want to see query in database file with location. Please help me out to find-out the solution.
Thanks in advance.
I'm new to PhoneGap, I'm making an application, it has like 500 words with definition of each word.
I have web developing background, in web developing, we create a database, and work with it, no matter the website is visited or not, data is there.
But in PhoneGap, it likes that we make a database every time that the application ran, and drop the table if it exist next time ( i dont know if i understood it right ).
So, if it's like that, it doesnt make any sense for me to use database at all !!
I want to know is there a way, that when user install the app on the phone, Data transfer automaticly, and it just be there when we need it ? ( not creating the table with the entries every time we need it ! )
Of course you don't have to create the DB at each app start and drop everything when you close the app. You can even version your DB. Here's a brief example:
db = window.openDatabase("mydbname", "",
"App Name", <size_in_bytes>);
console.log("version is: " + db.version);
if (db.version == "") {
// EMPTY STRING -> VERY FIRST ACCESS -> CREATE THE DB!
db.changeVersion("", "1", createDB,
function(error) {
console.log("ERROR DB from empty: " + JSON.stringify(error))
},
function() {
console.log("version 1, done!");
}
);
} else {
// We have the DB!
[...]
}
And you put the CREATE stuff and eventually INSERT stuff in the createDB function.
Everything according to the API:
window.openDatabase(name, version, display_name, size);
I need some database on my phonegap android application. I read about WebSQL and tried it, and I don't know if it stays after I close the app or it must be made every time i open the app. I need to keep data when app closes so i can use it when i open it again. What database should I use?
P.S. If u have some tutorial it would be nice. Thanks
The best option to store data in database for an Android Application using PhoneGap must be SQLite:
Android Storage Options
but you can use too WebSQL:
SQLite database on PhoneGap
See this question suggested by sajad:
How to implement an SQLite database in Phonegap?
and a Tutorial:
Create Android App with SQLite using Phonegap
Follow this tutorial to learn how to use/create SQLite database in phonegrap (from official doc).
var db = window.openDatabase("test", "1.0", "Test DB", 1000000);
This method will create a new SQL Lite Database and return a Database
object. Use the Database Object to manipulate the data.
Syntax + Tutorial:
window.openDatabase(name, version, display_name, size);
Example from the page:
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")');
}
function errorCB(err) {
alert("Error processing SQL: "+err.code);
}
function successCB() {
alert("success!");
}
var db = window.openDatabase("Database", "1.0", "PhoneGap Demo", 200000);
db.transaction(populateDB, errorCB, successCB);
I found this tutorial too.
To view the data stored in the database, follow these steps:
Click on Windows > Open Perspective > DDMS. Go to File Explorer.
Then /data/data/package_name/databases.But here we cannot see the tables and table data.
For viewing the table details Eclipse has a plugin. Download it from http://androidcode-sqlite.blogspot.in/2013/04/sqlitemanager-plugin-for-eclipse-android.html.
Now put the jar in the folder eclipse/dropins/.
Click on Java Build Path > Libraries > Add External JARs > Choose Your Path to the SQLite JAR File! Add it.
Restart the eclipse and now you can see the SQLite Manager plugin on the top right of the File Explorer window.
Click on (database name), then click on “open file in SQLite Manager...”.
Here, click on “Questoid SQLite Manager” tab and you can see your table in “Database Structure” tab.
Then, click on “Browse Data” tab to view your table data.
I ran a sample jQuery mobile app on my mobile IDE, that uses a local database for storing data.
The code statements used are as below. I am running it in a simulator and not on an actual device.
My question is: With these statements, am I using Web SQL or SQLite?
The reason for this confusion is when I debug this app in the mobile IDE, I find it says Web SQL as well as SQLite, which is confusing to me (look at the screen shot of the IDE at end of this post).
var db = openDatabase("Test", "1.0", "Test", 65535);
$("#create").bind("click", function (event) {
db.transaction(function (transaction) {
var sql = "CREATE TABLE customers " +
" (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " +
"lname VARCHAR(100) NOT NULL, " +
"fname VARCHAR(100) NOT NULL)"
transaction.executeSql(sql, undefined, function () {
alert("Table created");
}, error);
});
});
WebSQL is a specification that describes an interface between JavaScript code and a database.
SQLite is the database that you access through WebSQL.
(For compatibility reasons, all WebSQL implementations use SQLite.)
I am new to Phonegap. I am trying to implement an application in Phonegap Android. For the past two days,I am scouting for a proper way of accessing the database and retrieving it from the same.I did not find an answer to my questions
I have learnt that Phonegap does not support SQLLITE but supports the W3C Web SQL Database Specification and W3C Web Storage.
At the same time I noticed few plugins for Phonegap 1.5..which does not exist now. At the same time i found that W3c database provides a limited storage of 5MB for iOS.
I found this SQL Plugin for Phonegap Android PhoneGap-SQLitePlugin-Android Is it advicable to use this or any other method. Please,guide me.
So,if you have any sort of example of accessing the database that can be followed please share it.
I made an app recently that required this, targetting the Android and iOS. You can use a combination of the following ::
1. LocalStorage ::
Check for localStorage
function supports_html5_storage() {
try {
return 'localStorage' in window && window['localStorage'] !== null;
} catch (e) {
return false;
}
}
Set an item into LocalStorage
localStorage.setItem("bar", foo);
or
localStorage["bar"] = foo;
Get an item from LocalStorage
var foo = localStorage.getItem("bar");
or
var foo = localStorage["bar"];
2. SQLite Database (more convenient, more persistive)
Set up your DB
var shortName = 'BHCAppDB';
var version = '1.0';
var displayName = 'BHCAppDB';
var maxSize = 65535;
if (!window.openDatabase){
alert('!! Databases are not supported in this Device !! \n\n We are sorry for the inconvenience and are currently working on a version that will work on your phone');
}
db = openDatabase(shortName, version, displayName,maxSize);
createAllTables(db);
Create your Tables
function createAllTables(db){
db.transaction(function(transaction){
transaction.executeSql("CREATE TABLE IF NOT EXISTS Profile(id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT, gender TEXT,age INTEGER)");
}
Execute an SQL Query
transaction(function(transaction){
var rowCount = 'SELECT * FROM Profile';
transaction.executeSql(rowCount,[],function(transaction,result){
if(result.rows.length == 0){
var sqlString = 'INSERT INTO Profile (name,gender,age) VALUES("自己","Female",18)';
transaction.executeSql(sqlString);
}
});
});
3. Native Storage on all devices
This is the best part of Phonegap. You can call a native plugin class on all the devices using the Phonegap plugin call. During the call, you can pass parameters to the class, and the native class can store your data in the OS itself.
For example :: in iOS, you create a plugin .h & .m class and register it with the Cordova.plist file. Once that's done, you need to send a call to the class from JavaScript using Phonegap. Once the parameters have been received using NSDictionary or any other NSArray type, you can call a CoreData class to store UNLIMITED amounts of data. You'll never run out of memory .
This can be done in a similar fashion for all the rest of the OS's also :)
For Encryption try the following :: SQLCipher
Here is some additional information on working with an existing SQLite database. In this example encrypted.db is that brand new database you create and pragma.
ATTACH DATABASE 'encrypted.db' AS encrypted KEY 'secret'; -- create a new encrypted database
CREATE TABLE encrypted.t1(a,b); -- recreate the schema in the new database (you can inspect all objects using SELECT * FROM sqlite_master)
INSERT INTO encrypted.t1 SELECT * FROM t1; -- copy data from the existing tables to the new tables in the encrypted database
DETACH DATABASE encrypted;