Database storage on Android and iOS with Cordova

24

I have developed applications for Android mobile devices with Cordova that have used localStorage to save the data, because they were small amounts (configuration, records and high scores, etc.) and, until now, I have not had any problems.

Now I am developing a small trivia game that would be published on Android and iOS, and I will have a large amount of data (questions and answers). My idea was to download the data from a server when I first started the game and save it in an internal database where I can perform operations with them.

In the website on storage in Cordova different options are mentioned:

  • localStorage
  • WebSQL
  • IndexedDB
  • SQLite (via plugin)

Of those I have discarded IndexedDB (because according to the documentation, it does not work in iOS) and localStorage (because space is limited and I'm afraid that the device can erase the data if it needs space).

And of the rest, WebSQL and SQLite:

  • What are the advantages and disadvantages of each of them?
  • Is there any advantage / inconvenience of using one over the other?
  • Are there integration problems with any of these platforms?

And, although I know that this part can go a little out of the scope of the site, is there an alternative that is not mentioned on that web page and that should be taken into account?

I would value positively if you could add code examples for basic operations: create databases and tables, insert data and search for data.

    
asked by Alvaro Montoro 16.08.2016 в 17:16
source

6 answers

19

And of the rest, WebSQL and SQLite:

  

What are the advantages and disadvantages of each of them?

WebSQL :

  • I regret to inform you that the specification of WebSQL has been canceled by the W3C : link

    " This document was on the W3C Recommendation track but the work has been stopped The specification reached an impasse: all interested implementers have used the same SQL backend ( Sqlite ), but we need multiple independent implementations to proceed along a standardization path. "

    In Spanish:

    " This document was in the Recommendation W3C track, but the specification job has been stopped The specification reached a dead end: all interested implementers have used the same SQL server ( SQLite ), but we need multiple independent implementations to proceed along a normalization path. "

  • Although there is support on iOS, neither Microsoft nor Mozilla have supported it to date, reference: link

  • It looks a lot like the traditional SQL syntax that we're used to.

  • It's relatively new, little documentation on the network compared to SQLite

Script:

      <script type="text/javascript">

         var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
         var msg;

         db.transaction(function (tx) {
            tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS (id unique, log)');
            tx.executeSql('INSERT INTO LOGS (id, log) VALUES (1, "foobar")');
            tx.executeSql('INSERT INTO LOGS (id, log) VALUES (2, "logmsg")');
            msg = '<p>Log message created and row inserted.</p>';
            document.querySelector('#status').innerHTML =  msg;
         });

         db.transaction(function (tx) {
            tx.executeSql('SELECT * FROM LOGS', [], function (tx, results) {
               var len = results.rows.length, i;
               msg = "<p>Found rows: " + len + "</p>";
               document.querySelector('#status').innerHTML +=  msg;

               for (i = 0; i < len; i++){
                  msg = "<p><b>" + results.rows.item(i).log + "</b></p>";
                  document.querySelector('#status').innerHTML +=  msg;
               }
            }, null);
         });

      </script>

HTML:

<div id="status" name="status">Status Message</div>

Reference of the example shown: link

SQLite :

It has enough support, since its launch in 2000, there are hundreds of sites that give you support, examples, documentation, etc, etc, etc. They find it in:

Android7 5
BlackBerry
Windows Phone 8
Google Chrome5
iOS5
Firefox OS
Maemo
MeeGo
Symbian OS5
webOS

Reference: San Wikipedia link

  

Is there any advantage / inconvenience of using one over the other?

The main advantage is that when using SQLite you have the necessary maturity of the global experience of developers who have made solutions with this platform.

  

Are there integration problems with any of these platforms?

Yes, with WebSQL : The storage limit space is defined by the browser, link

To learn and manage SQLite , I recommend you visit link

With respect to Apache Cordova

SQLite Plugin It has 3 variants:

  • cordova-sqlite-storage - is the core version that includes the implementation of sqlite3 . Supports iOS, Android & Windows platforms.
  • cordova-sqlite-ext - extended version that includes REGEXP , supported on Android and iOS.
  • cordova-sqlite-evfree - similar cordova-sqlite-ext but with better memory handling. Available with Commercial license or GPL v3.

More information at: link

Small tutorial on a CRUD :

We create or open a DB:

var myDB = window.sqlitePlugin.openDatabase({name: "mySQLite.db", location: 'default'});

myDB.transaction(function(transaction) {
transaction.executeSql('CREATE TABLE IF NOT EXISTS phonegap_pro (id integer primary key, title text, desc text)', [],
function(tx, result) {
    alert("Table created successfully");
},
function(error) {
alert("Error occurred while creating the table.");
    });
});

Inserting data:

var title="Fredy Guibert";
var desc="Full Stack Web Developer";
myDB.transaction(function(transaction) {
var executeQuery = "INSERT INTO phonegap_pro (title, desc) VALUES (?,?)";
transaction.executeSql(executeQuery, [title,desc]
, function(tx, result) {
    alert('Inserted');
},
function(error){
    alert('Error occurred');
});
});

Select

myDB.transaction(function(transaction) {
transaction.executeSql('SELECT * FROM phonegap_pro', [], function (tx, results) {
var len = results.rows.length, i;
$("#rowCount").append(len);
for (i = 0; i < len; i++){
$("#TableData").append("<tr><td>"+results.rows.item(i).id+"</td><td>"+results.rows.item(i).title+"</td><td>"+results.rows.item(i).desc+"</td></tr>");
}
}, null);
});

Update

$("#update").click(function(){
 var id=$("#id").text();
 var title=$("#title").val();
 var desc=$("#desc").val()
 myDB.transaction(function(transaction) {
 var executeQuery = "UPDATE phonegap_pro SET title=?, desc=? WHERE id=?";
 transaction.executeSql(executeQuery, [title,desc,id],
 //On Success
 function(tx, result) {alert('Updated successfully');},
 //On Error
 function(error){alert('Something went Wrong');});
 });
});

Delete

myDB.transaction(function(transaction) {
 var executeQuery = "DELETE FROM phonegap_pro where id=?";
 transaction.executeSql(executeQuery, [id],
 //On Success
 function(tx, result) {alert('Delete successfully');},
 //On Error
 function(error){alert('Something went Wrong');});
 });

Delete the table:

myDB.transaction(function(transaction) {
 var executeQuery = "DROP TABLE IF EXISTS phonegap_pro";
 transaction.executeSql(executeQuery, [],
 function(tx, result) {alert('Table deleted successfully.');},
 function(error){alert('Error occurred while droping the table.');}
 );
 });

Reference: link

If you are using ionic , you will like this tutorial: link and its respective video explaining detail in detail: link

    
answered by 18.08.2016 / 21:31
source
8

localStorage: Suitable for saving configuration information of the app, that is, everything the user in the configuration window can use.

The data is accessed as if it were a list clave = valor .

WebSQL: I think it's obsolete, not all browsers support it in the same way, it's slow and you can not save too much information.

IndexedDB: on IOS does not support it

SQLite (via plugin) because it would be an alternative if nothing else existed, but currently there are other types of database based on objects, much more optimized in performance.

Supports SQL of the most basic, almost everything that entails, upgrades, updates, deletion of content, add etc .. (each programmer must deal with the syntax SQL )

If the project will use a complex data system when maintaining (updates, adding new functionality, etc.) it can be cumbersome.

NO-SQL: Lately NO-SQL database has been popularized covering all aspects of an app.

For example REALM that is much more optimized than sqlite.

Realm is a database system that uses objects, they are much more understandable, easy to use, you can perform all kinds of actions:

  • Add data
  • Modify data
  • Delete data
  • Relations between objects (tables)
  • Data filtering
  • Versioning upgrade system.
  • Server / client data synchronization system

They are extremely fast since part of the information runs in memory and only saved to disk when necessary.

Look at Realm or Firebase

Documentation realm.io

Support for cordova: realm-js

    
answered by 19.08.2016 в 23:59
8

My recommendation is one, use SQLite . On the official page you get a few very convincing reasons but I'm just going to concentrate on just one

  

Many applications use SQLite as a relevant content cache of an RDBMS. This reduces the latency since many of the queries now occur against the local cache and avoid the round trip in the network. This reduces the network load on the central database server and in many cases means that the application can continue even without a network connection.

It is usually a good idea to design your application in such a way that all ajax calls are made to a remote api (ideally RESTFUL as it fits perfectly with mobile technology) and then insert a cache that automatically stores the data so that it is not necessary to re-consult. The advantage of this architecture is that you can change the storage mechanism or cache in future versions, or simply remove it and your application "always works" regardless of the conditions.

The reason why I do not recommend the others:

localStorage : You already discarded it. The maximum storage size is around 5 Mb and if you expect a larger volume of data that is no longer an option. If the volume of data is less than this, use it! The reason is maximum compatibility with all platforms which is one of the strong points de cordova.

WebSql : It's obsolete .

  

This document was on the W3C recommendation list but all work has ceased. The specification has reached an impass: all interested implementers have used the same SQL backend ( Sqlite ), but we need multiple independent implementations to be able to continue with the standardization work.

As you can see, they have all opted for SQLite, in addition to not supporting Windows Phone and other platforms. Normally I have found that it is very good to use crosswalk in conjunction with cordova (you can get hardware acceleration and capabilities like WebRtc ) and you may find that in the future this API ceases to exist as the crosswalk does is integrate your application with the latest version of Chromium available.

IndexedDB: Does not support IOS, which is one of your requirements, so it does not go into the considerations. Usually when working with applications of cordova tries to obtain maximum compatibility and Android and IOS are always the first two candidates to consider.

In the github repository of the plugin you can find examples of the API. It should be mentioned that this API although it works with SQLite internally is a replacement to the WebSql API with some differences < a href="https://github.com/litehelpers/Cordova-sqlite-storage#deviations"> well documented so the official reference and the tutorials can serve as your source of documentation.

db = window.sqlitePlugin.openDatabase({name: 'prueba.db', location: 'default'});
db.executeSql('INSERT INTO Tabla VALUES (?,?)', ['Dato1', 'Dato2'], 
    function() {
        console.log('Insertado');
    }, 
    function(error) {
        console.log('Error');
});

As you can see it is exactly the same syntax that you can find here

Operations

The detailed list of operations is here

Create table

db.executeSQL('CREATE TABLE IF NOT EXISTS MiTabla (columna1, columna2)')

Insert data

db.executeSql('INSERT INTO MiTabla VALUES (?,?)', ['dato1', 'dato2'])

See

db.executeSql('SELECT columna1 FROM MiTabla')

Update

db.executeSql('UPDATE MiTabla SET columna2 = ? WHERE columna1 = ?', ['actualizado', 'dato1'])

Delete data

db.executeSql('DELETE FROM MiTabla WHERE columna1 = ?', ['dato1'])

Create transaction

db.transaction(function(trans) {
    // Callback con la transacción creada
    trans.executeSQL('....')
}, function(err) {
    // Callback de error
}, function() {
    // Callback despues que ha hecho comit la transacción
    // Si vas a cerrar la base de datos debe ser aquí
});

Operations Batch

db.sqlBatch([
  'CREATE TABLE IF NOT EXISTS MiTabla (columna1, columna2)',
  [ 'INSERT INTO MiTabla VALUES (?,?)', ['dato1', 'dato2'] ],
]);

Close connection

db.close()

The example I give you below is not directly from the plugin because there are several examples already of the subject but of $ cordovaSQLite which is an angular 1 wrapper for said plugin that is used with ionic and Ionic Native used with Angular2 and TypeScript

Ionic and Ng-Cordova

var db = $cordovaSQLite.openDB({ name: 'prueba.db' });
$cordovaSQLite.execute(db, 'INSERT INTO Tabla VALUES (?,?)', ['Dato1', 'Dato2'])
    .then(function(res) {
        console.log('Insertado');
    })
    .catch(function (err) {
        console.error('error');
    });

Ionic Native

import { SQLite } from 'ionic-native';

let db = new SQLite();
db.openDatabase({
    name: 'prueba.db',
    location: 'default'
}).then(() => {
    return db.executeSql('INSERT INTO Tabla VALUES (?,?)', ['Dato1', 'Dato2']);
}).then(() => {
    console.log('Insertado');
}, (err) => {
    console.log('Error');
});;
    
answered by 22.08.2016 в 23:50
4

Hello in my experience I use and I recommend WebSQL. Here you can see the compatibility.

link

I use Cordova or Phonegap and the truth is that I have not had any major problems. You have to know that you have a limit of 50 MB.

SQL with Javascript: Web SQL Database

As I guess many of you already know, an HTML5 specification is Web SQL Database to persist data in a relational database embedded in the web browser (the other alternative is Web Storage, to persist data as a key value). This can have many applications, in my case I have used it to implement the DNDzgz favorites system.

When we try to take advantage of the new features of HTML5 we must bear in mind that each browser can only support some specifications, it is not an all or nothing, so the first thing we should do is check that it supports the specification we want to use , for example:

function supports_local_database() {
return !!window.openDatabase;
}

If openDatabase exists, we will create the connection to the database:

db = openDatabase('dndzgz', '1.0', 'DNDzgz', 65536);

Once the connection is open, we can execute any kind of SQL query (compatible with SQLite), within a transaction. For example create a table:

db.transaction(
function(transaction) {
transaction.executeSql(
'CREATE TABLE IF NOT EXISTS favorites ' +
' (id INTEGER NOT NULL, ' +
' service VARCHAR(255) NOT NULL, ' +
' date DATE NOT NULL,' +
' name VARCHAR(255) NOT NULL, ' +
' latitude REAL NOT NULL, ' +
' longitude REAL NOT NULL, ' +
' PRIMARY KEY (id,service));'
);
}
);

Insert data:

db.transaction(
function(transaction) {
transaction.executeSql(
'INSERT INTO favorites (id, service, date, name, latitude, longitude) VALUES (?, ?, ?, ?, ?, ?);',
[id, service, new Date(), name, latitude, longitude],
callBack,
errorCallBack
);
}
);

Delete data:

db.transaction(
function(transaction) {
transaction.executeSql('DELETE FROM favorites WHERE id=? AND service=?;',
[id,service], null, errorCallBack);
}
);

And of course show them:

db.readTransaction(
function(transaction) {
transaction.executeSql(
'Select * from favorites;', [],
function(transaction, result){
for (var i=0; i < result.rows.length; i++) { var row = result.rows.item(i); alert(row.name); alert(row.service); } }, errorCallBack ); } );

As you can see, to executeSql the query is passed first, followed by an array with the values of the arguments of the query, and finally a callback function and a callback function if there are errors. And there are two types of transactions: transaction and readTransaction, the first is read-write, while the second is read-only.

Anyway, I suppose that the same thing will happen to others, it is quite strange to be pulling queries SQL from javascript. But it can be useful for many cases, starting with downloading responsibilities and loading the server side.

source: danilat.com

Good luck!

    
answered by 18.08.2016 в 21:20
3

SQL Web Database.

API Web SQL stores and data queries using SQL. You can store 50-200 MB of data in SQL Web database, the exact quota limit depends on the platform. Once the limit of WebView is reached, ask the user to grant permission to use the most local space.

Disadvantages or drawbacks

  

Note: This API is not supported by all platforms.

Cordova SQLite Plugin

This Cordova plugin allows the Cordova access application from the underlying native SQLite database, providing an API identical to the SQL Web API. There is no quota limit and you can synchronize the data with iCloud on iOS.

For most cases you will not need to use the Web Storage API and the SQLite plugin.

Note: To store images locally you do not have to use a file plugin. Some developers use the Base64 encoding scheme to store images in SQLite. However, for video, audio and other large files, encoding and decoding consumes a lot of time and memory, therefore it is recommended to save them in files and use the URL of files to display them.

Although you might be familiar with web storage APIs, it's worth revisiting.

How is it how to add, delete, update and clear local storage:

if(localStorage != undefined)
{
 console.log("Local Storage is supported");

 //add
 localStorage.setItem("Website", "SitePoint");

//update or overwrite
localStorage.setItem("Website", "SitePoint.com");

//remove
localStorage.removeItem("Website");

//remove all
 localStorage.clear();
}
else
{
console.log("No support");
}

How is it clear how to add, delete, update and store sessions:

if(sessionStorage != undefined)
{
console.log("session Storage is supported");

 //add
 sessionStorage.setItem("Website", "SitePoint");

//update or overwrite
sessionStorage.setItem("Website", "SitePoint.com");

//remove
  sessionStorage.removeItem("Website");

//remove all
sessionStorage.clear();
}
else
{
console.log("No support");
}

The Cordova SQLite Plugin

SQLite is an embeded DBMS based on the SQL language. A SQLite database with full API is provided by iOS, Android and Windows Phone.

The SQLite Cordova plug-in provides a simple API to create databases and execute queries on SQLite. This plugin exposes an API similar to the SQL Web API. You need to be familiar with SQL (such as MySQL) to write queries.

Here is how to create a database and execute SQL queries in the database.

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

  // Cordova is ready
 function onDeviceReady()
 {
 var db = window.sqlitePlugin.openDatabase({name: "demo.db"});

db.transaction(function(tx) {

    //create table
    tx.executeSql("CREATE TABLE IF NOT EXISTS demo (id integer primary key, data text, data_num integer)", [], function(tx, res){

        //insert data
        tx.executeSql("INSERT INTO demo (id, data, data_num) VALUES (?,?,?)", [1, "test", 100], function(tx,res){

            //retrieve data
            tx.executeSql("SELECT * FROM demo WHERE id = ?", [1], function(tx, res){
                for(var iii = 0; iii < res.rows.length; iii++)
                {
                    alert(res.rows.item(iii).id);
                    alert(res.rows.item(iii).data);
                    alert(res.rows.item(iii).data_num);
                }
            })

        });

    });

}, function(err){

    //errors for all transactions are reported here
    alert("Error: " + err.message)

});
}

Here we first create the database, then call the transaction database object method with a callback. Inside the callback we run the SQL queries. Queries are executed using the executeSql function that returns the response asynchronously.

If any of the queries fail, then the second callback is passed to the transaction method is invoked. Callback of the executeSql that will not trigger if the query fails.

To delete a database, use this code:

//delete database
 window.sqlitePlugin.deleteDatabase({name: "demo.db"}, function(){
alert("Successfully deleted database");
}, function(){
 alert("Error while delete database");
});
  

Cordova SQLite Plugin: The best personal option has many advantages.

I hope it helps you. Greetings.

    
answered by 19.08.2016 в 05:16
2

You can use NgData ORM for sqlite and websql . I use it in my IONIC apps and I'm doing fine. Test and draw your own conclusions.

link

    
answered by 15.09.2016 в 22:50