I have a working PhoneGap database transaction where I am able to run a sql query and process the results. However, in an effort to make it reusable, I need to be abe to pass arguments to the querying function. There should a better way than declaring global variables and accessing them/resetting in the query function. Appreciate any help in converting this:
//update images function
function updateGalleryCovers() {
var db = window.openDatabase("test db", "1.0", "Cordova DB", 200000);
db.transaction(queryDB_u_g, errorCB);
}
//Query the database
function queryDB_u_g(tx) {
var query = 'SELECT cover_img, objectId FROM USER_GALLERY WHERE userId="'+getUserId()+'"';
tx.executeSql(query, [], querySuccess_u_g, errorCB);
}
//Query success callback
function querySuccess_u_g(tx, results) {
var len = results.rows.length;
for (var i=0; i<len; i++){
// process results
}
}
to something like this:
//update images function
function updateGalleryCovers(userid) {
var db = window.openDatabase("test db", "1.0", "Cordova DB", 200000);
db.transaction(queryDB_u_g, userid, errorCB);
}
//Query the database
function queryDB_u_g(tx, userid) {
var query = 'SELECT cover_img, objectId FROM USER_GALLERY WHERE userId="'+userid+'"';
tx.executeSql(query, [], querySuccess_u_g, errorCB);
}
//Query success callback
function querySuccess_u_g(tx, results) {
var len = results.rows.length;
for (var i=0; i<len; i++){
// process results
}
}
Thanks!
The transaction functions are offered by sqlite and not phonegap. Its true that you can't pass extra variables to the functions because of the method signature sqlite accepts.
But here's a work around for the same:
db_conn.transaction( function(tx){ your_function(tx, parameter1, parameter2) }, ErrorCallBack );
Here you are passing a dummy function to the transaction success callback and taking the transaction object along with it.
Hope that helps
Related
I'm currently working on a little app using phonegap and sqllite.
Filling the database works fine; but I need a function which returns me a html-string (for a id).
I have this little snippet from the internet which I "improved" for my purpose, but it doesn't work like expected :(
function getPriceFromDatabase(id) {
var result = [];
// Query the database
//
function queryDB(tx) {
tx.executeSql('SELECT * FROM PRICEFTS WHERE pid MATCH ' + id, [], querySuccess, errorCB1);
}
// Query the success callback
//
function querySuccess(tx, results) {
var len = results.rows.length;
for (var i = 0; i < len; i++) {
result.push('<span class="'+results.rows.item(i).priceart+'">'+results.rows.item(i).price+'</span>');
}
}
// Transaction error callback
//
function errorCB1(err) {
console.log("Error SQL: " + err.code);
}
// Transaction success callback
//
var db = window.openDatabase("sucheDB", "1.0", "Suche DB", 52428800);
db.transaction(queryDB, errorCB1);
return result.join('');
}
Here is my sample event:
$("#price_button").click(function () {
var p = getPriceFromDatabase(88361);
console.log(p);
$('#price').html(p);
})
(I get always 'undefined' as result)
can someone help?
thanks! :)
You should provide the on-success callback to the db.transaction call, like this:
db.transaction(queryDB, errorCB1, querySuccess);
Also this function is probably async, so your return is executed before the transaction could finish.
I'm trying to return the results of a SQL query using SQLite.
The query works fine and I can output the results inside the executeSql function. But when I try to reach the array from my main function (returnSQLArray) it is undefined.
How do I solve this problem?
I'm calling returnSQLArray inside another function where I need the results from the query.
Code:
function returnSQLArray(str)
{
var db = window.openDatabase("Database", "1.0", "Name", 200000);
var result = [];
db.transaction(
function (tx, results) {
tx.executeSql(str, [], function(tx, rs) {
for(var i=0; i<rs.rows.length; i++) {
var row = rs.rows.item(i)
result[i] = {
id: row['id']
}
}
console.log(result[0].id); //Returns the id
});
}
);
console.log(result[0].id); //Undefined
}
Thank you
It's an async issue. db.transaction takes a callback which executes after the sqlite transaction finishes. Your console.log() statement shown at the end of your method is actually happening before result has been populated.
EDIT ADDITION:
functions getPersons() {
returnSQLArray('SELECT * FROM PERSONS', processPersonsResponse);
}
function returnSQLArray(str, callback) {
...
tx.executeSql(str, [], function(tx, rs) { callback(result); });
}
function processPersonsResponse(response) {
//do work with response
}
I am working on a camera app using the PhoneGap.
The thing I am trying to accomplish is, that when my app takes a picture and I store the picture in the app directory, I want to insert an entry in the database also with the name of the file, path and uploaded flag entry.
I am having trouble doing this. And I am unsure where the problem is occurring.
The code used to create database and the Table and then insert the entry is shown below. I call the "insertInTable" function after the file is already saved in the app directory.
function insertInTable(name, path)
{
var db = window.openDatabase('taukydb', '1.0', 'Tauky Database', 200000);
db.transaction(populateDB, errorCB, successCB);
//db.transaction(successCB, errorCB, );
//return();
}
function populateDB(tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS taukytb (name UNIQUE, path, uploaded)');
tx.executeSql('INSERT INTO taukytb (name, path, uploaded) VALUES (filename, filepath, 0)');
}
// Transaction success callback
function successCB() {
alert("Hurrey!!!");
//this is just for testing
var db = window.openDatabase("Database", "1.0", "Cordova Demo", 200000);
db.transaction(queryDB, errorCB);
}
function queryDB(tx) {
tx.executeSql('SELECT * FROM taukytb', [], querySuccess, errorCB);
}
function querySuccess(tx, results) {
var len = results.rows.length;
alert(len);
}
// Transaction error callback
function errorCB1(err) {
alert("Error 11111 processing SQL: "+err.code);
//console.log("Error processing SQL: "+err.code);
}
// Transaction error callback
function errorCB(err) {
alert("Error processing SQL: "+err.code);
//console.log("Error processing SQL: "+err.code);
}
When I run this code, the function "succesCB" never gets called, neither the errorCB is called.
Please have a look at this. I am new to mobile development and I have been stuck on this since sometime now.
Thanking in advance
I have made few changes to make it work.
tx.executeSql('INSERT INTO taukytb (name, path, uploaded) VALUES ("'+filename+'", "'+filepath+'", 0)');
This change will call the successCB as the query executes fine.
function successCB() {
alert("Hurrey!!!");
//this is just for testing
var db = window.openDatabase("Database", "1.0", "Cordova Demo", 200000);
db.transaction(queryDB, errorCB);
}
function queryDB(tx) {
tx.executeSql('SELECT * FROM taukytb', [], querySuccess, errorCB);
}
This method however will not work as you expect as you are creating second database providing the transaction of that but then querying for the table of first database.
Below is the full source example which creates two database with same table in both
https://gist.github.com/3058562
Don't know much about phonegap, but that create table statement seems to be lacking some types.
Also this line:
tx.executeSql('INSERT INTO taukytb (name, path, uploaded) VALUES (filename, filepath, 0)');
what is filename?
I'm trying to make a JS function that counts rows in an SQLite table.
function countRows(){
db.transaction(function (tx){
tx.executeSql('SELECT id FROM table', [], function (tx, results) {
var len = results.rows.length;
alert(len);
});
});
}
The above code displays an alert with numbers of rows in the table. However, I'd like to make a function that would return the number instead of showing the alert box.
I tried:
function countRows(){
db.transaction(function (tx){
tx.executeSql('SELECT id FROM table', [], function (tx, results) {
var len = results.rows.length;
return len;
});
});
}
And then:
var number = countRows();
alert (number); // returns "undefined"
The above example returns "undefined", whereas a parallel example works fine:
function count(){
return 3;
}
var number = count();
alert (number); // returns 3
I want to assign the number to a variable, so I could then make another sql query, count rows in another table, and compare the two results.
In PHP this would be:
$sql1 = mysql_query('SELECT COUNT(*) FROM table1');
$rows1 = mysql_result($sql1, 0);
$sql2 = mysql_query('SELECT COUNT(*) FROM table2');
$rows2 = mysql_result($sql2, 0);
if ($row1>$row2){}
You would be served much better by changing your query.
SELECT COUNT(ID) FROM table
Plus, its an async call so that the call return is returning the callback function. You should pass your own callback function.
function countRows(callback){
db.transaction(function (tx){
tx.executeSql('SELECT id FROM table', [], function (tx, results) {
var len = results.rows.length;
callback(len);
});
});
}
db.transaction is asynchronous. returning value isn't assigned to any variable in code above. Solution is to pass callback or create custom event, which is almost the same.
Something like this:
function countRows(cb){
db.transaction(function (tx){
tx.executeSql('SELECT id FROM table', [], function (tx, results) {
var len = results.rows.length;
cb.call(this, len);
});
});
}
countRows(function (num) {alert(num)});
From a tutorial code like this
function queryDB(tx) {
tx.executeSql('SELECT * FROM DEMO', [], querySuccess, errorCB);
}
function querySuccess(tx, results) {
}
function errorCB(err) {
alert("Error processing SQL: "+err.code);
}
var db = window.openDatabase("Database", "1.0", "PhoneGap Demo", 200000);
db.transaction(queryDB, errorCB);
in db.transaction i want to pass a variable as argument to queryDB function, so the code which i think of should looks like
db.transaction(queryDB(id), errorCB);
How I can actually implement this ? Or its simply gonna work like this and my id will be passed and get in tx ?
Wrap it in a function again
var id = 'THEID';
db.transaction(function(){
queryDB(id)
}, errorCB);
Note - This is assuming that you're making the API. Some APIs / frameworks insert the required information automatically. For example
//the db.transaction method
function transaction(param, callback) {
//do code stuff
callback(someInternalId); //callback is the function you pass as the first parameter
}
So, if you want to pass your own data in the callback, wrap it in a function. Otherwise, the code you are using may be doing this for you automatically.
I like to keep things very simple so I use a limited number of functions when handling storage on phonegap applications that can receive parameters. A lot of the examples I have seen have calls to many sub functions and for me, this is a nightmare when it comes to debugging.
I was caught out an a number of issues around Web SQL but reading the specs really, really helped clarify what I could and couldn't do. (http://www.w3.org/TR/webdatabase/)
Look at this simple code for an insert function:
function dbInsert(param1, param2, dbObj) {
val1 = param1;
val2 = param2;
val3 = String(dbObj.item2);
var sqlTxt = "INSERT INTO demo (geo1, geo2, geo3) VALUES (?, ?, ?)";
db.transaction(function(tx) {tx.executeSql(sqlTxt,[val1,val2,val3])}, errorCB, successCB);
}
Lets just to walk through it. Obviously a standard function which receives parameters which can be anything, in this case an object as well a strings.
sqlTxt is where the fun begins. Write this as you would normally write an insert statement, but where you would normally have the data to be inserted/selected etc in VALUES use the ? placeholder for each field in the database tables you want to pass data into.
Now lets break down the next line:
db.transaction(function(tx) {tx.executeSql(sqlTxt,[val1,val2,val3])}, errorCB, successCB);
When you create a new database, db is the handler to the database object so db.transaction asks to execute a transaction on the database db.
If we write next next section like this you can see it's function that calls tx.executeSql and because it in execute inside the db.transaction method, it will be passed the db handle.
function(tx) {
tx.executeSql(sqlTxt,[val1,val2,val3])
}
Now if we were to parse the sqlTxt it might look like this
INSERT INTO demo (geo1, geo2, geo3) VALUES ('a', 'b', 'c');
and because we are passing the three variable in place of the ? holder, it looks like the line above. And finally you call error and success callback functions.
In your case I would create a queryDB function like this:
function queryDB(id) {
var sqlTxt = "SELECT * FROM DEMO WHERE id=?"
db.transaction(function(tx) {tx.executeSql(sqlTxt,[id])}, errorCB, successCB);
}
In essence, the function grabs the parameter id, passes it into the query in the [id] and executes and returns error or success. Obviously you can extend this to use multiple parameters or if you want to be really clever, you just create a single database transaction function and pass in the sql and the parameters to use as an object or array (Example will be on my blog this weekend)
Ok first of all create a class hat will handle you're db instances (db updates etc) this class will hold a function that you will use for all you're query's
self.db = window.openDatabase( // and so on
then the function:
// execute a query and fetches the data as an array of objects
self.executeQuery = function(string, args, callback, callbackparams) {
var self = this;
//console.log('db execute: '+string);
self.db.transaction(function(tx) {
tx.executeSql(string, args, function(tx, result) {
var retval = [];
for (var i = 0; i < result.rows.length; ++i) {
retval.push(result.rows.item(i));
}
if (callback) {
callback(retval, result, callbackparams);
}
}, self.error);
});
}
then when u have initiated you're class (i named it myDb) go apeshit!
myDb.executeQuery('select l.* from location l inner join item_location il on (il.location_id = l.id and il.item_id = ?)', [item.id], function(locations, res, item){
item.locations = locations;
myDb.executeQuery('select * from media where item_id = ?', [item.id], function(media, res, item){
item.media = media;
// create item.
createItem(item);
}, item);
}, item);
as you can see the executeQuery has 4 params,
query,
params for query,
callback (with 3 params, result, status and myparam)
myparam (for callback)
It took me some time to fix this, but when you've done this! no more annoying db horror!
We can't send any paramenter for queryDB function like "queryDB(id)"
I solved this issue by this way.
var contactId = 33
dbInst.transaction(function(tx){
tx.executeSql('CREATE TABLE IF NOT EXISTS CONTACT_REFERENCE (id unique)');
var sqlStr = 'INSERT INTO CONTACT_REFERENCE (id) VALUES (?)'
tx.executeSql(sqlStr, [contactId]);
}, errorCB, successCB);
I think everyone comes close to answering your question. Really you need one slight modification to JohnP's answer. You should pass in the SQLTransaction Object that carries the executeSQL function. So to build on John's answer:
var id = 'THEID';
db.transaction(function(tx){
queryDB(tx, id)
}, errorCB);
Then where you define the function you can grab your id param with an extra variable.
queryDB: function (tx, id) { ...your code... }
This is a worked solution:
var sqltxt= 'INSERT INTO CONTACTS(id, data) VALUES (?, ?)';
var db = window.openDatabase("Database", "1.0", "Demo", 200000);
db.transaction(function(tx){tx.executeSql('DROP TABLE IF EXISTS CONTACTS');
tx.executeSql('CREATE TABLE IF NOT EXISTS CONTACTS(name unique, password)');
tx.executeSql(sqltxt,[name, pass]);
}, errorCB, successCB);