When I use Web SQL,I am in trouble - javascript

I tried to insert some data into web sql database.But I met a problem.
My code :
database();
for(var i=0;i<m.length;i++){
showid = m[i].id;
showtitle = m[i].title;
insert();
}
function database(){
//open the database
db = window.openDatabase("youyanchu", "1.0","youyanchu",500000);
db.transaction(function(tx) {
var table = tx.executeSql("CREATE TABLE showList (id int PRIMARY KEY, title NVARCHAR, finishDate NVARCHAR, status NVARCHAR, tkCount NVARCHAR )");
});
}
//INTEGER NOT NULL PRIMARY KEY
function insert(){
db.transaction(function(ar) {
ar.executeSql("INSERT INTO showList (id, title,finishDate,status) values(?,?,?,?)", [showid,showtitle,'aaa','bbb']);
});
}
m.length is 3 and "m" should be
aaa = {'id':'999','title':'ninini'}
bbb = {'id':'888','title':'ninini'}
ccc = {'id':'777','title':'ninini'}
At last,just "ccc" display in the web sql.
How to insert all data into the database?What mistake I made in the code?

Since tx.executeSql is asynchronous, I believe your loop finishes before the first insert runs.
Hence showid and showtitle will always have the last values of the object m
Try this instead:
for(var i=0;i<m.length;i++){
insert(m[i].id, m[i].title);
}
function insert(id, title){
db.transaction(function(tx) {
txexecuteSql("INSERT INTO showList (id, title,finishDate,status) values(?,?,?,?)", [id, title,'aaa','bbb']);
});
}

Related

I want to return the result when all the queries in the loop is done(express.js, react.js, mysql)

I'm working on a side project using react and express.
I want to send the drop data of 7 days of a specific item in my database in the list for search.
So I wrote the code like this.
Use date(droped_at) = date(date_add(now(),interval -*${i}* DAY) and for loop.
for (var i = 1; i < 8; i++) {
var resultSql1 = `SELECT T.channel_name, T.channel_number, T.VALUE, T.num from(SELECT itemId, channel_name, channel_number, COUNT(*) AS VALUE, ROW_NUMBER() over(order by value DESC) NUM FROM item_drop_exception WHERE itemId = (SELECT itemId FROM item_exception WHERE itemid = '${id}') AND date(droped_at) = date(date_add(now(),interval -${i} DAY)) GROUP BY channel_name, channel_number) T WHERE T.NUM<=3 ORDER BY T.num ORDER BY T.NUM`
db.query(resultSql1, id, (err, data) => {
if (!err) {
list1.push(data);
if (list1.length == 7) {
res.send(list1);
}
}
else {
res.send(err);
}
})
}
But it doesn't work.
I know the method is wrong.
I think the next loop is going on before the query results come in, but I don't know what to do.
Is it right to bring in seven days of data like that?
I want to send the data to the front when all results are the append and complete.
It's not easy because I'm self-taught, I need help.
The query has a small error.
You have a double ORDER BY t.NUM at the end, so when you remove it the query runs. But if it gets you the right result, is only answerable , fi we had data
So
var resultSql1 = `SELECT T.channel_name, T.channel_number, T.VALUE, T.num from(SELECT itemId, channel_name, channel_number, COUNT(*) AS VALUE, ROW_NUMBER() over(order by value DESC) NUM FROM item_drop_exception WHERE itemId = (SELECT itemId FROM item_exception WHERE itemid = '${id}') AND date(droped_at) = date(date_add(now(),interval -${i} DAY)) GROUP BY channel_name, channel_number) T WHERE T.NUM<=3 ORDER BY T.num`
Would give you a result for every days
Turn your function call into a promise, then await it inside each loop, ensuring each db query runs one by one.
const { promisify } = require('util');
const dbQueryAsync = promisify(db.query);
async function getData(req, res) {
var { id } = req.params;
var list = [];
for (var i = 1; i < 8; i++) {
var resultSql1 = `SELECT ... `;
try {
var data = await dbQueryAsync(resultSql1, id);
list.push(data);
} catch(err) {
res.send(err);
}
}
res.send(list);
);

Accesing variable in nodejs module

Im' trying to build my first module in nodejs.
I have this code working perfectly :
var express = require('express');
var router = express.Router();
var sqlite3 = require('sqlite3').verbose();
var db;
var io = require('socket.io-client');
const notifier = require('node-notifier');
/* GET home page. */
router.get('/', function(req, res, next) {
createDb();
socket = io.connect('http://localhost:4000');
socket.on('connect', () => {
console.log("socket connected");
});
socket.on('message', (contenu) => {
console.log('message received');
console.log(contenu);
notifier.notify(contenu.contenu);
});
socket.emit('message', { contenu : 'test'});
res.render('index', { title: 'Accueil' });
});
/* SQLite */
function createDb() {
console.log("createDb chain");
db = new sqlite3.Database('./database_institut-villebon.db', createTable);
}
function createTable() {
console.log("createTable etudiants");
db.run("DROP TABLE IF EXISTS etudiants");
db.run("CREATE TABLE IF NOT EXISTS etudiants (Nom TEXT, NumeroGroupe INTEGER, NumeroCandidat INTEGER PRIMARY KEY, Filiere TEXT)", insertRows);
}
function insertRows() {
console.log("insertRows in etudiants");
var stmt = db.prepare("INSERT INTO etudiants VALUES (?,?,?,?)");
for (var i = 0; i < 3; i++) {
stmt.run("John Doe",i,i,"S");
}
stmt.finalize(readAllRows);
}
function readAllRows() {
console.log("readAllRows etudiants");
db.all("SELECT rowid AS id, Nom, NumeroGroupe, NumeroCandidat, Filiere FROM etudiants", function(err, rows) {
rows.forEach(function (row) {
console.log(row.id + ": " + row.NumeroCandidat +","+ row.Filiere);
});
closeDb();
});
}
function closeDb() {
console.log("closeDb");
db.close();
}
function runChain() {
createDb();
}
module.exports = router;
But when i try to put it in a module it say that the table "etudiants" doesn't exist ...
This is my module :
var sqlite3 = require('sqlite3').verbose();
"use strict";
/* SQLite */
var BddUtils = function () {
console.log("createDb chain");
this.database = new sqlite3.Database('./database_institut-villebon.db');
}
BddUtils.prototype.closeDb = function () {
console.log("closeDb");
this.database.close();
}
BddUtils.prototype.readAllRows = function() {
console.log("readAllRows etudiants");
this.database.all("SELECT rowid AS id, Nom, NumeroGroupe, NumeroCandidat, Filiere FROM etudiants", function(err, rows) {
rows.forEach(function (row) {
console.log(row.id + ": " + row.NumeroCandidat +","+ row.Filiere);
});
this.database.closeDb();
});
}
BddUtils.prototype.insertRows = function() {
console.log("insertRows in etudiants");
var stmt = this.database.prepare("INSERT INTO etudiants VALUES (?,?,?,?)");
for (var i = 0; i < 3; i++) {
stmt.run("John Doe",i,i,"S");
}
//stmt.finalize(this.readAllRows());
}
BddUtils.prototype.createTable = function () {
console.log("createTable etudiants");
this.database.run("DROP TABLE IF EXISTS etudiants");
this.database.run("CREATE TABLE IF NOT EXISTS etudiants (Nom TEXT, NumeroGroupe INTEGER, NumeroCandidat INTEGER PRIMARY KEY, Filiere TEXT)", this.insertRows());
}
BddUtils.prototype.init = function () {
this.createTable();
}
exports.BddUtils = exports = new BddUtils();
I have been looking for an issue and i found that if I don't drop the table everything works !
So i suppose that the "insertRows" function is called before the create table... but it's a callback function ....
Any help will be appreciate, thanks in advance.
EDIT : I'm maybe on something :
The context of the function (the this object inside the function) is
the statement object. Note that it is not possible to run the
statement again because it is automatically finalized after running
for the first time. Any subsequent attempts to run the statement again
will fail.
If execution was successful, the this object will contain two
properties named lastID and changes which contain the value of the
last inserted row ID and the number of rows affected by this query
respectively. Note that lastID only contains valid information when
the query was a successfully completed INSERT statement and changes
only contains valid information when the query was a successfully
completed UPDATE or DELETE statement. In all other cases, the content
of these properties is inaccurate and should not be used. The .run()
function is the only query method that sets these two values; all
other query methods such as .all() or .get() don't retrieve these
values.
So it's possible that my this.database is not in the current context anymore... don't know how to proceed..
It looks like you need to wrap your CREATE TABLE statement into a Database.serialize() function.
Database#serialize([callback])
Puts the execution mode into serialized. This means that at most one
statement object can execute a query at a time. Other statements wait
in a queue until the previous statements are executed.
This ensures the CREATE TABLE statement gets executed in isolation.
The example that comes from the documentation:
db.serialize(function() {
// These two queries will run sequentially.
db.run("CREATE TABLE foo (num)");
db.run("INSERT INTO foo VALUES (?)", 1, function() {
// These queries will run in parallel and the second query will probably
// fail because the table might not exist yet.
db.run("CREATE TABLE bar (num)");
db.run("INSERT INTO bar VALUES (?)", 1);
});
});
Solved by using db.serialized()
BddUtils.prototype.createTable = function () {
var db = this.database;
db.serialize(function() {
console.log("createTable etudiants");
db.run("DROP TABLE IF EXISTS etudiants");
db.run("CREATE TABLE IF NOT EXISTS etudiants (Nom TEXT, NumeroGroupe INTEGER, NumeroCandidat INTEGER PRIMARY KEY, Filiere TEXT)");
var stmt = db.prepare("INSERT INTO etudiants VALUES (?,?,?,?)");
for (var i = 0; i < 3; i++) {
stmt.run("John Doe",i,i,"S");
}
stmt.finalize(function(){
console.log("readAllRows etudiants");
db.all("SELECT rowid AS id, Nom, NumeroGroupe, NumeroCandidat, Filiere FROM etudiants", function(err, rows) {
rows.forEach(function (row) {
console.log(row.id + ": " + row.NumeroCandidat +","+ row.Filiere);
});
db.close();
});
});
})
}

Calling SQL in JavaScript for loop

I am writing a set of functions in JavaScript where a user can either add a new trip or edit an existing trip. Each trip can have (0-n) guns associated to that trip. Either way, the save and edit function both call rangeSaveGun. When called from “save new trip” function, this function (below) executes perfectly. The new record is added to the DB and displayed. However, when called from “edit trip” function, the SQL is exactly the same as shown in alert(sql), but the record never saves to the DB. Any idea why? In both scenarios, this is only called to add new guns to the trip (not to edit existing guns).
My question: In the below function, why is the row not being inserted into the DB when this exact same function is called from the “Edit” function instead of the “New” function? Either way the “sql” text is exactly the same (as verified in the “alert”). What am I missing? Both the "new" and the "edit" functions are called via a button click, and simply save or edit the trip and then call this rangeSaveGun function at the end.
I am already using the standard workaround to ensure closure. I can confirm that all 3 variables (tripNum, input2temp, and input3temp) are showing the expected values in all scenarios. All values are numbers.
function rangeSaveGun(tripNum)
{
var tbl2 = document.getElementById("mytable2");
var rowCount=tbl2.rows.length;
for (var i = 1; i < rowCount; i++) {
var el = document.getElementById("GunVal"+i)
if(el != null)
{
(function(i){
var input2temp = document.getElementById("GunVal"+i).value;
var input3temp = document.getElementById("Rounds"+i).value;
var sql = 'INSERT INTO RangeShot (TripID, GunID, Rounds) VALUES ('+tripNum+', '+input2temp+', '+input3temp+')';
db.transaction(function (tx) {tx.executeSql(sql, [])});
alert(sql);
})(i);
}
}
}
I found the problem. It actually was due to me calling an INSERT statement which was still running while another UPDATE statement was running. The DB was locked by the first write statement, and so the second write statement was never executed. I had to re-write my "update" function to call items in different order.
One other thing I ended up changing was to change the buttontype from "submit" to "button".
function rangeUpdateRecord()
{
db.transaction(function (tx) {
var input1temp = document.getElementById("Name").value;
var input2temp = document.getElementById("Address").value;
var input3temp = document.getElementById("Lat").value;
var input4temp = document.getElementById("Lng").value;
var input5temp = document.getElementById("Duration").value;
var input6temp = document.getElementById("Date2").value;
var input7temp = document.getElementById("StartTime").value;
var input8temp = document.getElementById("Notes").value;
var idupdate = $("#id").val();
var tbl2 = document.getElementById("mytable2");
var rowCount=tbl2.rows.length;
for (var i = 1; i < rowCount; i++) {
var el = document.getElementById("GunVal"+i);
if(el != null)
{
(function(i){
var input2temp = document.getElementById("GunVal"+i).value;
var input3temp = document.getElementById("Rounds"+i).value;
var sql = 'INSERT INTO RangeShot (TripID, GunID, Rounds) VALUES ('+idupdate+', '+input2temp+', '+input3temp+');';
db.transaction(function (tx) {tx.executeSql(sql)});
//alert(sql);
})(i);
}
}
db.transaction(function (tx) {
tx.executeSql('UPDATE RangeTrip SET Name = ?, Address = ?, Lat = ?, Lng = ?, Duration = ?, Date2 = ?, StartTime = ?, Notes = ? WHERE id=?', [input1temp, input2temp, input3temp, input4temp, input5temp, input6temp, input7temp, input8temp, Number(idupdate)],rangeLoadAndReset(),onError);
});
});
}

SQL Insert Statement not Working in Javascript

I'm trying to get my WebSQL database to popluate using a JSON array (Object is called myJSONObject, array is called costcodes).
The function runs on click, the database successfully creates, but the data is not inserted into the database. It doesn't even throw and error, it just doesn't do anything.
My initial thought was that the data isn't escaped properly, but I don't know exactly where/how to escape it. So I'm stumped.
localDB = null;
function initDB()
{
if (localDB==null)
{
var shortName = 'Costcode';
var version = '1.0';
var displayName = 'Costcode';
var maxSize = 217802; // in bytes
localDB = window.openDatabase(shortName, version, displayName, maxSize);
}
}
function buildTable()
{
var sQuery = 'CREATE TABLE IF NOT EXISTS Costcode ('+
'id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,' +
'cost_code_no VARCHAR NULL,' +
'row_unique_no VARCHAR NULL,' +
'cost_class_no VARCHAR NULL,' +
'Table_Version VARCHAR DEFAULT "1.0");';
try
{
initDB();
localDB.transaction(function(transaction)
{
transaction.executeSql(sQuery, []);
console.log('sucess');
});
}
catch (e)
{
alert("Error: Unable to create table 'x" + "' " + e + ".");
return;
}
}
function exeSQLFast()
{
initDB();
localDB.transaction(function(transaction)
{
for (var x = 0; x <myJSONObject.costcodes.length; x++)
{
var costcodeno = myJSONObject.costcodes[x].cost_code_no;
var rowuniqueid = myJSONObject.costcodes[x].row_unique_id;
var costclassno = myJSONObject.costcodes[x].cost_class_no;
console.log(costcodeno);
console.log(rowuniqueid);
console.log(costclassno);
transaction.executeSql('INSERT INTO Costcode (cost_code_no, row_unique_id, cost_class_no) VALUES (? , ? , ?)',
[costcodeno,
rowuniqueid,
costclassno]
, function(transaction, results)
{
console.log(costcodeno);
console.log('hooray');
}
)};
}
)}
</script>
</head>
<body onLoad="buildTable();">
<input type="button" onClick="exeSQLFast();" value='button'>
</body>
</html>
The console log shows that the variables are all being properly defined, but it's not running the insert statement. Any ideas?
Here's an example of myJSONObject.costcodes[2]
cost_class_no: " 3"
cost_code_no: " 1000"
row_unique_id: 335
That looks like a problem doesn't it...
The problem was that I called the row_unique_no column row_unique_id in the insert statement. Now I feel stupid.
But if anyone is curious how to populate a WebSQL database properly, this is how you do it. Just don't mistype the column names.

on page load javascript check value from HTML5 webstorage table's field

When my page loads, I create a database with fields and data is successfully loaded in all the fields.
In my webstorage database their is a column favourite and its type is integer. when my database is filling data in all fields this, the favourite field is field with 0 values.
After this there I display only one button in my page whose code is:
<img id="fav_image" onclick="addFav()" src="icons/star_fav_empty_icon.png" />
When I click this image, it changes the value from 0 to 1 in the favourite field in database.
As you see on id 3 favourite value is 1 in abc table
After changing image value, its function is also changed ...
... which I'm doing like this:
function addFav()
{
var pageId = a;
db.transaction(function(tx) {
tx.executeSql(updateFav,[1,pageId], showEmpty , onError);
});
document.getElementById('fav_image').src="icons/star_fav_icon_fill.png";
document.getElementById('fav_image').setAttribute( "onClick", "javascript:
removeFav();" );
}
function removeFav()
{
var pageId = a;
db.transaction(function(tx) {
tx.executeSql(updateFav,[0,pageId], showEmpty , onError);
});
document.getElementById('fav_image').src="icons/star_fav_empty_icon.png";
document.getElementById('fav_image').setAttribute( "onClick", "javascript: addFav();"
);
}
According to me, everything is working fine here.
I need to check the favourite value when page is loaded and show the image and onClick function according to the favourite value:
if the value is 0, then show empty star image with the addFav() function
if the value is 1, then show filled star image with the RemoveFav() function
I get the favourite value from the database using this function:
function checkfav()
{
var cID = a;
var b;
var getFavBool = 0;
//fav.innerHTML = '';
db.transaction(function(tx) {
tx.executeSql(selectfavStatement, [cID], function(tx, result) {
dataset = result.rows.item(0);
getFavBool = dataset['favourite'];
b = parseInt(getFavBool,10);
if(b==1)
{
fav.innerHTML = b;
return b;
}
else
{
fav.innerHTML = b;
return b;
}
});
});
}
I hope you get the idea of what I am trying to say...
I only added the checkfav() function whose code is:
function checkfav()
{
//this is a ID to which i want to get the result.
var cID = a;
db.transaction(function(tx) {
tx.executeSql("selectfavStatement", [cID], function (tx, result) {
var len = result.rows.length, i;
dataset = result.rows;
for (var i = 0, item = null; i < len; i++){
item = dataset.item(i);
var favID = item['favourite'];
//now this line is only to show result on HTML page. (optional)
document.getElementById('fav').innerHTML = item['favourite'];
if(favID==1)
{
document.getElementById('fav_image').src="icons/star_fav_icon_fill.png";
document.getElementById('fav_image').setAttribute( "onClick", "javascript: addFav();" );
}
else if(favID==0)
{
document.getElementById('fav_image').src="icons/star_fav_empty_icon.png";
document.getElementById('fav_image').setAttribute( "onClick", "javascript: removeFav();" );
}
}
});
});
}

Categories

Resources