I'm using html5sql.com for doing html5 DB stuff :o)
- Really a great module...
However, I got stuck!
At my index.html/index.js I create my database and tables in it.
try {
html5sql.openDatabase("com.dynamicvenues.fairkeyMobile.db","Questionnaire",3*1024*1024);
html5sql.process(
[
"CREATE TABLE IF NOT EXISTS Questionnaire (uid INTEGER, json TEXT, hash TEXT);",
"CREATE TABLE IF NOT EXISTS Answers (id INTEGER PRIMARY KEY, visitor_id TEXT, json TEXT);"
],
function(){
console.log("Success Creating Tables");
},
function(error, statement){
console.error("Error: " + error.message + " when processing " + statement);
}
)
} catch(error) {
alert("Database create failed: "+error.message);
}
And further in the same page I populate one table with data:
jQuery.get(serverHttp+"json.php?exhibitorID="+exhibitorID, function(data){
var html = $(data).map(function() {
return $(this).html();
});
var jsonStr = html[0];
var exhibitorID = html[1];
var hashStr = html[2];
var SQL = "INSERT INTO Questionnaire (uid, json, hash) VALUES ("+exhibitorID+",'"+jsonStr+"','"+hashStr+"')";
try {
html5sql.process(SQL,
function(){
console.log('Inserted 1 row!');
},
function(){
console.error("Error: " + error.message + " when processing " + statement);
}
)
} catch(error) {
alert("Query failed: "+error);
}
Now, in a different page called questionnaire.html/questionnaire.js I'm trying to retrieve the data I stored in the table Questionnaire.
html5sql.process(
["SELECT * FROM Questionnaire;"],
function(transaction, results, rowsArray){
for(var i = 0; i < rowsArray.length; i++){
var uid = rowsArray[i].uid;
var json = rowsArray[i].json;
var hash = rowsArray[i].hash;
console.log("Retrieved rows: "+uid+" - "+json+" "+hash);
}
console.log("Done selecting data");
},
function(error, statement){
console.error(error.message+" Occured while processing: "+statement);
}
);
What am I doing wrong???
Regards,
Daniel
Solved! Inserted: html5sql.openDatabase("com.dynamicvenues.fairkeyMobile.db","Questionnaire",3*1024*1024); Before html5sql.process() at questionnaire.js
Related
I have a cross platform app developed using AngularJS, JS, Phonegap/Cordova, Monaca and Onsen UI.
I have implemented a SQLite Database in the app to store various data to ensure that the app can be used offline. I have done a few simple tests and this is all working as intended.
I now try to create all the tables I will need in the app (28 in total) in my apps first views onDeviceReady() function. For this I create an array of objects that I will pass one by one to the SQLite CREATE statement as below.
Setting up the table values
// Form values
var formValues = [{
tablename: "table_1",
id: "id_1",
desc: "desc_1",
dataType: "TEXT"
}, {
tablename: "table_2",
id: "id_2",
desc: "desc_2",
dataType: "TEXT"
}, {
...
...
...
...
}, {
tablename: "table_28",
id: "id_28",
desc: "desc_28",
dataType: "TEXT"
}];
Creating the tables
function onDeviceReady() {
for (var i = 0; i < formValues.length; i++) {
var createFormValues = 'CREATE TABLE IF NOT EXISTS ' + formValues[i].tablename + ' (' + formValues[i].id + ' INTEGER, ' + formValues[i].desc + ' ' + formValues[i].dataType + ')';
alert("SQL: " + createFormValues +
"\n\nForm: " + formValues +
"\nName: " + formValues[i].tablename +
"\nID: " + formValues[i].id +
"\nDesc: " + formValues[i].desc +
"\nType: " + formValues[i].dataType);
db.transaction(function (tx) { tx.executeSql(createFormValues); });
}
};
When I run the above code, the alert shows that all the information including the SQL statement is OK. However, when I query each table following the for() loop, it says no tables are created EXCEPT the last table.
I then try the following which DOES create all the tables but is obviously less efficient and manageable.
Calling a function
createFormTables("table_1", "id_1", "desc_1", "TEXT");
createFormTables("table_2", "id_2", "desc_2", "TEXT");
createFormTables("...", "...", "...", "...");
createFormTables("table_28", "id_28", "desc_28", "TEXT");
Executing the function
createFormTables: function (tableName, id, description, dataType) {
var sql = 'CREATE TABLE IF NOT EXISTS ' + tableName + ' (' + id + ' INTEGER, ' + description + ' ' + dataType + ')';
alert("Create Form Field SQL: " + sql);
db.transaction(function (tx) { tx.executeSql(sql); });
},
I know that the SQLite statements are executed asynchronously but I dont understand why that would create the tables in the second example and not the first? How do I create the tables using the first example? I can set a $timeout to execute each INSERT statement but this seems unnecessary and will cause delays.
I would use the JavaScript "Object" aproach to avoid conflict when calling function 'createFormTables' with something like:
var QuerySet = function(){
//OPTIONAL: I use JQuery Deferred to catch when an async event has finished
this.defRes = new $.Deferred();
this.defResProm = this.defRes.promise();
};
QuerySet.prototype.createFormTables= function(inputData){
//do your stuff and manage when this.defRes is resolved and results it sends back (if a result is needed)
this.sqlToExecute = "// YOUR SQL QUERY";
var self=this;
$.when(
(new SqlResult(this.sqlToExecute)).execSqlCustomDeferred(), //read below for SqlResult() explanations
self
).done(function(sqlRes,self){
self.defRes.resolve();
});
return this.defResProm;
};
Then in the code:
creatFromTables[i] = (new QuerySet()).createFormTables(inputData);
createFromTables[i].defRes.done(function(res){//do stuff with the result});
Don't need to use $.Deferred() but I think it could be useful if you want to know when all the tables have been created.
And here is sqlResult that is used to call the transaction on the DB itself:
var SqlResult = function(sqlToExecute,bracketValues){
//console.log("SqlResult("+sqlToExecute+','+bracketValues+') starts');
this.sqlToExecute = sqlToExecute;
this.bracketValues =bracketValues;
};
SqlResult.prototype.execSqlCustomDeferred = function(){
var execSqlCustomDeferredRes = $.Deferred();
var execSqlCustomDeferredResProm = execSqlCustomDeferredRes.promise();
//console.log("SqlResult.execSqlCustomDeferred sqlToExecute is: "+this.sqlToExecute);
var sqlToExecuteForTx = this.sqlToExecute;
var bracketValuesForTx = this.bracketValues;
DbManagement.db.transaction(function(tx){
console.log("SqlResult.execSqlCustomDeferred in TX sqlToExecute is: "+sqlToExecuteForTx);
if(bracketValuesForTx!=null){
console.log("SqlResult.execSqlCustomDeferred bracket value is: "+ArrayManagement.arrayToString(bracketValuesForTx));
}
tx.executeSql(sqlToExecuteForTx,bracketValuesForTx,success,error);
function success(tx,rs){
//console.log('before execSqlCustomDeferredRes resolve ' + execSqlCustomDeferredRes.state());
execSqlCustomDeferredRes.resolve(rs);
//console.log('before execSqlCustomDeferredRes resolve after ' + execSqlCustomDeferredRes.state());
}
function error(tx,error){
console.log('execSqlCustomDeferred error ' + error.message);
execSqlCustomDeferredRes.reject(error);
}
});
return execSqlCustomDeferredResProm;
};
for example , i have been using following approach in my cross platform apps to accessing sqlite database as follows
To access database i have made a saperate .js for UserProfile table
function DBUserProfile()
{
this.selectUserName = function(userId, callback)
{
try
{
//Get Data
localDB.transaction(function selectUserProfileData(tx)
{
var objDBDatabaseSchema = new DBDatabaseSchema();
var sqlCommand = 'SELECT username FROM '
+ objDBDatabaseSchema.UserProfileMetaData.USER_PROFILE_TABLE_NAME
+' WHERE engineer_id='
+ '="' + userId + '"';
objDBDatabaseSchema = null;
tx.executeSql(sqlCommand,[],function selectUserNameResult(tx, results)
{
if (results.rows.length > 0 )
{
var userId = results.rows.item(0).username ;
callback(userId);
}
else
{
var userId = "";
callback(userId);
}
}, errorDB);
}, errorDB);
}
catch (e)
{
// TODO: handle exception
console.log("DBUserProfile - selectUserName " + e);
}
};
}
and this is how i use them in a pages
var objDBUserProfile = new DBUserProfile();
objDBUserProfile.selectUserName("3443" , function(id){
//
});
but the above approach is pretty time consuming i have been end up creating lot of models and db files to access tables and lot of new objects , so does anyone has a better approach in jquery to cut down the development time. any suggestions are welcome
I am getting keywords (ExpressJS):
/*
* GET keywords.
*/
router.get('/keywords', function(req, res) {
// Check if user is logged in
if (req.user) {
var db = req.db;
var user = req.user;
db.collection('users').findOne({_id: user._id},
function(err, result) {
// console.log(result.keywords.RFD);
res.json(result.keywords.RFD);
});
}
});
I am updating my MongoDB (ExpressJS/Mongoose):
/*
* POST keyword.
*/
router.post('/addkeyword', function(req, res) {
// Check if logged in
if (req.user) {
var db = req.db;
var user = req.user;
var keywords = validator.stripLow(validator.trim(req.body.keywords));
db.collection('users').update({_id: user._id}, {'$addToSet': { 'keywords.RFD' : keywords } }, function(err, result) {
if (err) throw err;
if (!err) {
console.log('Keyword added: ' + keywords);
};
});
}
});
The addKeyWord function (JS):
function addKeyword(event) {
event.preventDefault();
// Super basic validation - check if empty
var errorCount = 0;
var keywordRead = $('#addKeyword input#inputKeyword').val();
if($('#addKeyword input').val() === '') {
keywordAlert = '<div class="alert alert-danger">Please fill in a keyword.</div>'
$('#alert').html(keywordAlert);
return false;
}
else {
// If it is valid, compile all user info into one object
var newKeyword= {
'keywords': keywordRead,
}
// Use AJAX to post the object to our adduser service
$.ajax({
type: 'POST',
data: newKeyword,
url: '/api/addkeyword',
dataType: 'JSON',
success: populateKeywords(true)
});
}
};
I am populating the page (JavaScript/jQuery):
var keywordContent = '';
$.getJSON( '/api/keywords', function( data ) {
// For each item in our JSON, add a table row and cells to the content string
$.each(data.reverse(), function(){
keywordContent += '<div class="form-group">';
keywordContent += '<span class="label label-success">' + this + '</span>';
keywordContent += ' x';
keywordContent += '</div>';
}).reverse();
// Inject the whole content string into our existing HTML table
$('#myKeywords').html(keywordContent);
});
The problem is that when I add a keyword, the keywords re-populate, and sometimes the jQuery is too fast and does not list the new keyword.
I would like to add some loading/checking to see if the JSON has changed? The population is only accurate if the /addkeyword is fast enough.
If i understood correctly, you want to populate page only after new keyword addition is complete. As node works on single thread model these issues are likely to occur. No problem with node its just non-blocking way of node. For this kind of stuff i would highly suggest looking at async package of node.
You might have to use something like ,
async.series([
function(){ ... },
function(){ ... }
]);
/*
* POST to addkeyword.
*/
router.post('/addkeyword', function(req, res) {
// Check if logged in
if (req.user) {
var db = req.db;
var user = req.user;
var keywords = validator.stripLow(validator.trim(req.body.keywords));
db.collection('users').update({_id: user._id}, {'$addToSet': { 'keywords.RFD' : keywords } },
function(err, result) {
if (err) throw err;
if (!err) {
console.log('Keyword added: ' + keywords );
// the one line I needed is below:
res.end('{"success" : "Updated Successfully", "status" : 200}');
};
});
}
});
I've commented above the one line that was missing and that was needed!
I have a virtual table in sqlite and I'm running queries against it looking for matches of keywords but the count always comes out to 1. The structure is as follows.
var insertStatement2 = "INSERT INTO pagesfts3 (url,content) VALUES (?, ?)";
var createStatement2 = "CREATE VIRTUAL TABLE pagesfts3 USING fts3 (url VARCHAR,content TEXT)";
var selectStatement2 = "SELECT COUNT(*),url FROM pagesfts3 WHERE content MATCH ? GROUP BY url";
try {
var db = openDatabase("search", "1.0", "search engine", 200000);
db.transaction(function(tx) {
//for example use drop table on each load
tx.executeSql(dropStatement, [], null, onError);
tx.executeSql(dropStatement2, [], null, onError);
tx.executeSql(createStatement, [], null, onError);
tx.executeSql(createStatement2, [], null, onError);
});
db.transaction(function(tx) {
});
}
catch (error) {
$('body').prepend('<div class="alert alert-danger">This script requires a SQlite compatible browser<br/> try Safari 4, iOS OS3, Chrome 5, or Opera 10.5</div>');
}
function onError(tx, error) {
alert(error.message);
}
So basically I save a webpage data and its corresponding url. When I go to query the page I run this
var query = $('#query').val().toLowerCase();
var searchResults = $('#queryResult');
searchResults.html('');
db.transaction(function(tx) {
//run static select statment 2 on the virtual table
tx.executeSql(selectStatement2, [query], function(tx, result) {
var dataset = result.rows;
if (dataset.length > 0) {
for (var i = 0, item = null; i < dataset.length; i++) {
item = dataset.item(i);
console.debug(item);
var url = item['url'];
var count = item['COUNT(*)'];
var str = '<p>' + url + ' has the word <b>' + query + '</b></p>';
searchResults.append(str);
}
}else{
searchResults.append('no results');
}
});
});
But the column count(*) is always 1 even though I know they keyword is present more than 1 times. I'm not too familiar with virtual tables so maybe I'm missing something.
I try to create HTML5 table in WebOS using following JavaScript, but the table is not created.
However i can't see any further detail in the log other than the first Mojo.log "Try to create database".
2011-01-25T15:48:50.251507Z [43854] qemux86 user.notice LunaSysMgr: {LunaSysMgrJS}: com.palm.phonegap: Info: Try to create database, palmInitFramework347:2527
Do you have any idea?
Thanks..
var db;
function openDb(){
var shortName = 'mcrm';
var version = '1.0';
var displayName = 'mCRM'
var maxSize = 65536;
db = openDatabase(shortName, version, displayName, maxSize);
try {
db.transaction(
function(transaction) {
Mojo.Log.info("Try to create database");
transaction.executeSql(
'CREATE TABLE IF NOT EXISTS bookmarks'
+ ' (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, '
+ ' resource_id INTEGER NOT NULL '
+ ' resource_type TEXT NOT NULL '
+ ' url TEXT NOT NULL );',
function() {
Mojo.Log.info("DATABASE CREATED");
},
errorHandler
);
}
);
Mojo.Log.info("Is it no error?");
}
function errorHandler(transaction, error) {
Mojo.Log.info("ooopss. Error was ", error.message , " ;Error code:", error.code);
return true;
}
the cause of log file is not giving err message i.e. missing one argument of executeSql
the cause of the error i.e. missing comma at CREATE TABLE statement