SQLite plugin doesn't work Ionic - Apache Cordova - android

I am developing an Apache Cordova app for Android and IOS using Ionic framework too, for this I need to have a little database in local storage and I wan't to use SQLite. I follow a lot of tutorials and in fact this is very easy -at least it seems-, but I have the follow error:
Uncaught TypeError: Cannot read property 'openDatabase' of undefined (11:52:54:666 | error, javascript)
at (anonymous function) (www/js/app.js:47:29)
at (anonymous function) (www/lib/ionic/js/ionic.bundle.js:53329:19)
at onPlatformReady (www/lib/ionic/js/ionic.bundle.js:2491:24)
at onWindowLoad (www/lib/ionic/js/ionic.bundle.js:2472:7)
After this error, the database is not created, in other words, it doesn't works.
Obviously I resarch about this in the internet and I found a lot of possible solutions, the most aproximated solution that can explain this and I found is this:
TypeError: Cannot read property 'openDatabase' of undefined
But for my doesn't Works :(
To quote from the last link:
It is happening for one of a few reasons:
1.You are not wrapping the $cordovaSQLite methods in the $ionicPlatform.ready() function.
2.You are trying to test this native plugin from a web browser.
3.You have not actually installed the base SQLite plugin into your project.
On my case:
$cordovaSQLite method is inside $ionicPlatform.ready function.
I am testing using a a physical Android device.
I have installed the plugin on my project from the following source:
https://github.com/brodysoft/Cordova-SQLitePlugin-2014.07.git
As I said I research a lot about this and I don't achive solve this situation.
My code:
params.run(function($ionicPlatform, $cordovaSQLite) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if (window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
cordova.plugins.Keyboard.disableScroll(true);
}
if (window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleDefault();
}
db = window.sqlitePlugin.openDatabase({name: "inspeccionesDB.db"});
$cordovaSQLite.execute(db, "CREATE TABLE IF NOT EXISTS table1 (id integer primary key autoincrement not null, company char(255) not null, cif char(20) not null, state char(20) not null, related_ids char(45) not null)");
$cordovaSQLite.execute(db, "CREATE TABLE IF NOT EXISTS table2 (id integer primary key not null, code char(20) not null, firstname char(20) not null, surname char(100) not null, surname1 char(100) not null, nif char(20) not null, expired_passport_dt text not null, is_valid tinyint not null");
$cordovaSQLite.execute(db, "CREATE TABLE IF NOT EXISTS table3 (id integer primary key not null, code char(20), address char(250), location char(100), provincia(250))");
});
});
I will be absolutely thankful for any advice or possible solution.
Thanks in advance to everybody.

You are getting this error because you are trying to get database connection from android but using wrong function openDatabase(). This function will use in case of client (browser). Use openDb() function to get database connection from android.
if (window.cordova) {
// device
dbconn = $cordovaSQLite.openDB({ name: "my.db" , location: 'default'});
$cordovaSQLite.execute(dbconn, "CREATE TABLE IF NOT EXISTS people (id integer primary key, firstname text, lastname text)");
}
else{
// browser
dbconn = window.openDatabase("my.db", '1', 'my', 1024 * 1024 * 100);
$cordovaSQLite.execute(dbconn, "CREATE TABLE IF NOT EXISTS people (id integer primary key, firstname text, lastname text)");
}

Your SQLite file not exist in browser you can add manual code for android.
please refer this link http://gauravstomar.blogspot.in/2011/08/prepopulate-sqlite-in-phonegap.html

Related

Android app, SQLite, FTS3, create virtual table if not exists

Beginner to SQLite/SQL. Building an Android app with FTS3 enabled, so I need to create virtual tables. I can't use this, because (according to my system log) virtual tables don't use IF NOT EXISTS syntax:
// Create the table if it doesn't exist.
db.transaction(function(tx){
tx.executeSql( 'CREATE TABLE IF NOT EXISTS User(UserId INTEGER NOT NULL PRIMARY KEY, FirstName TEXT NOT NULL, LastName TEXT NOT NULL)',[],nullHandler,errorHandler);
},errorHandler,successCallBack);
To confirm that my SQLite plug-in is working as expected, I have been using this instead:
// Create the table if it doesn't exist.
db.transaction(function(tx){
tx.executeSql( 'DROP TABLE User',[],nullHandler,errorHandler);
tx.executeSql( 'CREATE VIRTUAL TABLE User USING fts3 (UserId INTEGER NOT NULL PRIMARY KEY, FirstName TEXT NOT NULL, LastName TEXT NOT NULL)',[],nullHandler,errorHandler);
},errorHandler,successCallBack);
Which works mostly as expected (except that the UserId INTEGER NOT NULL PRIMARY KEY no longer works, returning null every time-- suggestions for a Virtual Table friendly way to add an incrementing integer also very welcome). But I don't want to drop the table every time, I want to keep it. How can I check for the existence of the table User and only create it if it doesn't exist?
According to the CREATE VIRTUAL TABLE documentation, the correct syntax is:
CREATE VIRTUAL TABLE IF NOT EXISTS User USING FTS4(...)
According to the FTS documentation, you cannot explicitly declare an autoincrementing column, but every table has an implicit column called docid or rowid.

Storage of SQLite database using Android and Phonegap

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.

Web SQL automatically defaults to SQLite in Android devices?

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.)

Android: mySQL, create table command

I'm trying to create a table and I've tried so many times to figure this out... for some reason it won't accept this.. it's saying something about the auto_increment
create table if not exists Assignments(
id auto_increment primary key,
class_name VARCHAR(30),
assignment_name VARCHAR(30) not null,
due_date VARCHAR(30) not null,
notes VARCHAR(30));
whats the problem?
EDIT: i am trying to use SQLite eventually but this command was written on my mySQL thru WAMP
First of all, Android uses SQLite, so your mysql tag is slightly incorrect unless I'm missing something you're doing.
Secondly, you would say
CREATE TABLE ASSIGNMENTS(id INTEGER PRIMARY KEY, class_name TEXT, assignment_name TEXT NOT NULL, due_date TEXT NOT NULL, notes TEXT);
"autoincrement" is handled automatically if you set your primary key as an INTEGER type, even though under the covers SQLite uses strings for everything
reference: SQLite datatypes
further reference: INTEGER PRIMARY KEY
Even more reference: "If an INSERT statement attempts to insert a NULL value into a rowid or integer primary key column, the system chooses an integer value to use as the rowid automatically. A detailed description of how this is done is provided separately."
It is autoincrement, not auto_increment

creating android db table

I am new on android. I am trying to create a table in a db using the following code but there is some error
db.beginTransaction();
try {
db.execSQL("CREATE TABLE IF NOT EXISTS `book` (`id` int(11) NOT NULL AUTO_INCREMENT,`title` varchar(100) NOT NULL,`author_name` varchar(100) NOT NULL,`text_b` text NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;");
db.setTransactionSuccessful();
} catch (SQLiteException e) {
Log.d("Maaz", "Exception 2 : SQL Exception 2 " + e.getMessage());
} finally {
db.endTransaction();
}
The above code is giving me the following error
Failure 1 (near "AUTO_INCREMENT": syntax error)
on 0x23c510 when preparing 'CREATE TABLE IF NOT EXISTS `book` (`id` int(11) NOT NULL AUTO_INCREMENT,`title` varchar(100) NOT NULL,`author_name` varchar(100) NOT NULL,`text_b` text NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;'.
Kindly help me. Thanks in advance.
Change AUTO_INCREMENT to AUTOINCREMENT.
Edit:
Try this,
CREATE TABLE IF NOT EXISTS book (
_id INTEGER PRIMARY KEY AUTOINCREMENT,
title varchar(100) NOT NULL,
author_name varchar(100) NOT NULL,
text_b TEXT NOT NULL
);
This Worked at last in my case.
Answer :
CREATE TABLE IF NOT EXISTS book (
_id Integer PRIMARY KEY AUTOINCREMENT,
title varchar(100) NOT NULL,
author_name varchar(100) NOT NULL,
text_b TEXT NOT NULL);
Removing Engine, DEFAULT CHARSET worked for me
what kind of database, it makes a difference for the SQL syntax. You should try to create the database table first in the console editor and then you can paste that syntax in your code. It's also usually not a good idea to create tables from code with a generic execSQL. You should use an ORM or database library or framework for this. A continuous integration server could also create this table unless your are creating it on the client's android device. Hibernate is nice for keeping messy SQL out of your code.
Can you tell us what kind of database?
You can also check out this article:
http://androidforbeginners.blogspot.com/2010/01/creating-multiple-sqlite-database.html
Very close syntax if you are using SQLite
It seems you have quotes surrounding the identifiers (I.e. books). Remove them.

Categories

Resources