3

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 ?

Rupesh Yadav
  • 12,096
  • 4
  • 53
  • 70
cjmling
  • 6,896
  • 10
  • 43
  • 79

6 Answers6

6

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)

TheTechy
  • 172
  • 2
  • 13
6

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.

Sundar R
  • 13,776
  • 6
  • 49
  • 76
JohnP
  • 49,507
  • 13
  • 108
  • 140
  • so does in queryDB() function i'll get the id value with tx.id ? *i'm working on phonegap – cjmling Jan 08 '12 at 07:18
  • Like I said, that depends on phonegap's API (I haven't used it). is `tx` a value that you want to pass to queryDB? or a method that you expect the API to fill in (like a transaction ID). If you want to pass it along, you can use the method I detailed above. – JohnP Jan 08 '12 at 07:30
  • `tx` could be a method that api will fill i guess, http://dev.w3.org/html5/webdatabase/#sqltransactioncallback.... so if I want to pass it along then how I retrieve the value of ID .. is it by tx.id ? – cjmling Jan 08 '12 at 08:59
  • The article you linked to seems to imply its injected for you. Have you tried simply logging to see whether the object is present? A console.log? – JohnP Jan 08 '12 at 09:44
  • ok..ur answer about passing data by wrapping it in a function helped me solving the problem other way around. Thanks :D – cjmling Jan 08 '12 at 09:45
  • hehe..we just answer exactly at the same time ... yeah since 2 hours had been logging and trying different thing..now i got it.. but you can't actually passed id variable like that. coz it will replace tx in queryDB function while tx is required there.... ( don't much have clue about ..as i'm not much good in JS ) – cjmling Jan 08 '12 at 09:47
  • See my answer below which gives you the exact functionality you need. – TheTechy Apr 20 '13 at 09:23
2

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!

Rene Weteling
  • 524
  • 3
  • 8
  • thanks for the explanation Rene but can you explain why you're calling 2 queries? Do you have a simple example? –  Jul 04 '12 at 19:54
0

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);
Jon
  • 2,703
  • 3
  • 18
  • 14
0

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... }
KickerKeeper
  • 265
  • 2
  • 9
0

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