I'm using Cordova
with jQuery and jQuery Mobile to develop a hybrid app. In this app I need to save data that I get from a server.
The data is a JSON
. I chose this SQLite plugin for Cordova to save the content in tables for easy access.
I make an AJAX-GET
call to get the data I need and call the function below with the parameters: content
is the JSON
; myAction
is a string(sync
or update
); upt
is an integer
(unix timestamp).
function syncQueries(content, myAction, upt){
//JSON
var uid = content.content[0].uid;
var name = content.content[0].name;
var now = Math.round(Date.now()/1000);
if (typeof content.content[0].kurzbeschreibung != 'undefined'){
var kurzbeschreibung = content.content[0].kurzbeschreibung;
}
if (typeof content.content[0].hauptkategorie != 'undefined'){
var parentID = content.content[0].hauptkategorie;
}
if (typeof content.content[0].unterkategorie != 'undefined'){
var parentID = content.content[0].unterkategorie;
}
if(content.content[0].beschreibung.match(/<img/)){
var beschreibung = findImgTag(content.content[0].beschreibung);
} else {
var beschreibung = content.content[0].beschreibung;
}
//sync data
if(myAction == 'update'){
db.transaction(function(tx){
if(content.content[0].tabelle == 'hauptkategorie'){
tx.executeSql("UPDATE hauptkategorie SET name = '"+name+"', beschreibung = '"+beschreibung+"', last_update = '"+now+"' WHERE pid = "+uid, [], function(tx){
tx.executeSql('UPDATE last_update_haupt SET update_time = '+upt+', last_success = '+now+', sync = 0 WHERE pid = '+uid ,[], function(){
sync++;
});
console.log(content.content[0].tabelle +': '+uid);
});
} else if(content.content[0].tabelle == 'unterkategorie'){
tx.executeSql("UPDATE unterkategorie SET name = '"+name+"', beschreibung = '"+beschreibung+"', parentid = '"+parentID+"', last_update = '"+now+"' WHERE pid = "+uid, [], function(tx){
tx.executeSql('UPDATE last_update_unter SET update_time = '+upt+', last_success = '+now+', sync = 0 WHERE pid = '+uid ,[], function(){
sync++;
});
console.log(content.content[0].tabelle +': '+uid);
});
} else if(content.content[0].tabelle == 'loesung'){
tx.executeSql("UPDATE loesung SET name = '"+name+"', kurzbeschreibung = '"+kurzbeschreibung+"', beschreibung = '"+beschreibung+"', subparentid = '"+parentID+"', last_update = '"+now+"' WHERE pid = "+uid, [], function(tx){
tx.executeSql('UPDATE last_update_loesung SET update_time = '+upt+', last_success = '+now+', sync = 0 WHERE pid = '+uid ,[], function(){
sync++;
});
console.log(content.content[0].tabelle +': '+uid);
});
}
},function(e){
console.error('ERROR: '+e.message);
$.mobile.loading('hide');
});
} else if(myAction == 'sync'){
db.transaction(function(tx){
if(content.content[0].tabelle == 'hauptkategorie'){
tx.executeSql('INSERT INTO hauptkategorie (pid, name, beschreibung, last_update) VALUES (?,?,?,?)', [uid, name, beschreibung, now], function(tx){
tx.executeSql('INSERT INTO last_update_haupt (pid, update_time, last_success, sync) VALUES (?,?,?,?)', [uid, upt, now, 0], function(){
sync++;
});
console.log(content.content[0].tabelle +': '+uid);
});
} else if(content.content[0].tabelle == 'unterkategorie'){
tx.executeSql('INSERT INTO unterkategorie (pid, name, beschreibung, parentid, last_update) VALUES (?,?,?,?,?)', [uid, name, beschreibung, parentID, now], function(tx){
tx.executeSql('INSERT INTO last_update_unter (pid, update_time, last_success, sync) VALUES (?,?,?,?)', [uid, upt, now, 0], function(){
sync++;
});
console.log(content.content[0].tabelle +': '+uid);
});
} else if(content.content[0].tabelle == 'loesung'){
tx.executeSql('INSERT INTO loesung (pid, name, kurzbeschreibung, beschreibung, subparentid, last_update) VALUES (?,?,?,?,?,?)', [uid, name, kurzbeschreibung, beschreibung, parentID, now], function(tx){
tx.executeSql('INSERT INTO last_update_loesung (pid, update_time, last_success, sync) VALUES (?,?,?,?)', [uid, upt, now, 0], function(){
sync++;
});
console.log(content.content[0].tabelle +': '+uid);
});
}
},function(e){
console.error('ERROR: '+e.message);
$.mobile.loading('hide');
});
}
//sync pictures
if(content.content[0].grafik == 1){
db.executeSql('UPDATE '+content.content[0].tabelle+' SET bild = 1 WHERE pid = '+content.content[0].uid,[],function(){
file_info(content.content[0].tabelle, content.content[0].uid);
console.log(content.content[0].uid+', '+content.content[0].tabelle);
},function(e){
console.error('ERROR: '+e.message);
$.mobile.loading('hide');
});
} else {
db.executeSql('SELECT * FROM '+content.content[0].tabelle+' WHERE pid = '+content.content[0].uid,[],function(res){
if(res.rows.item(0).bild == 1){
file_info(content.content[0].tabelle, content.content[0].uid);
}
},function(e){
console.error('ERROR: '+e.message);
$.mobile.loading('hide');
},function(){
syncEnd();
});
}
}
The function findImgTag
takes a string, looks for <img>
tags, downloads the images to the device storage and replaces them with a local path for offline usage. The return value is the string with replaces <img>
tags.
Sync++
is to keep track of the amount of entries for the function syncEnd
. syncEnd
just hides the mobileLoader
when the database is synchronized with the server.
The function fileInfo
downloads pictures that are not inside the HTML text.
To ensure that the data is successfully inserted into the table I make an other INSERT
into a different table that lists when an entry was updated(server side timestamp) and when the last successful insert was (now).
I read on Stack Overflow that you shouldn't make nested transactions but I haven't found an other way to ensure the INSERT
or UPDATE
was successful since jQuery is asynchronous.
My question: Is there a better way to do the INSERT
and UPDATE
and are there any other improvements I could make to the code?
content
? \$\endgroup\${"content":[{"uid": integer, "name": string, "beschreibung": string, "grafik": integer, "hauptkategorie": integer, "deleted": integer, "timestamp": integer, "tabelle": string}]}
\$\endgroup\$