Unsolved A strange behavior of if-condition
-
Hi all,
Please take a look at this example:
Window { visible: true width: 640 height: 480 title: qsTr("Hello World") property var db TextField { id: field placeholderText: qsTr("Enter Your Name") hoverEnabled: true } Button { id: srch text: "Search Name" anchors.top: field.bottom onClicked: { if(seekName(field.displayText)) console.log("Found") else console.log("Not Found") } } Button { text: "Store Name" anchors.left: srch.right anchors.leftMargin: 10 anchors.top: field.bottom onClicked: storeData(field.displayText) } Component.onCompleted: initDatabase() function initDatabase() { db = LocalStorage.openDatabaseSync("data", "1.0", "Save Usernames", 1000000) db.transaction( function(tx) { tx.executeSql('CREATE TABLE IF NOT EXISTS data(name TEXT)') }) } function storeData(username) { if(!db) return db.transaction( function(tx) { tx.executeSql('INSERT INTO data VALUES (?)',[username]) }) } function seekName(username) { db.transaction( function(tx) { var result = tx.executeSql('SELECT * from data'); for (var i=0; i<result.rows.length; ++i) if(result.rows.item(i).name === username) return true return false }) } }
If I put the name "Jack" and store it using the Store Name button, it'll be saved in the database. Then if the name is searched by the Search Name button, although the
seekName
function finds it and returns true, the code in theif
part of:if(seekName(field.displayText))
won't be executed and theelse
part will be accomplished! I don't know why? -
Hi,
From the Qt Quick Local Storage QML Types, transaction is not a synchronous operation so you can't do what you want the way you are trying to do it. You should refactor your code to the operation you want in the callback where you execute your SQL statement. Or call another function from there.
-
@SGaist
Thank you for your answer.From the Qt Quick Local Storage QML Types, transaction is not a synchronous operation so you can't do what you want the way you are trying to do it.
What do you mean by that, please? Does it mean the way I've learnt programming can't be valid when I'm dealing with SQL/databases?
You should refactor your code to the operation you want in the callback where you execute your SQL statement.
What callback do you mean? I didn't see a clear function in the link to be symbolized as callback, I suppose.
Or call another function from there.
From where, please? Inside the for loop in the
seekName
function? -
It has nothing to do with SQL programming but with how it's implemented in JavaScript.
The function you wrote containing the for loop is the callback.
You can either do it in the for loop, or after it. That's up to you.
-
You can either do it in the for loop, or after it. That's up to you.
1- I still don't know the reason why the
true
value returned by the function is not gotten and applied by thatif
. It must be to some extent related to SQL, because in a normal JavaScript code, the returned value is gotten and applied properly by the caller a function.2- Apparently, based on a hidden reason, I can't use the method in the code above to return
true
for thatif
condition, and have two alternatives as below.a) Embedding:
function seekName(username) { db.transaction( function(tx) { var result = tx.executeSql('SELECT * from data'); for (var i=0; i<result.rows.length; ++i) if(result.rows.item(i).name === username) { console.log("Found") return } console.log("Not Found") return false }) }
b) Or using another function to write the result.
Right?
-
As already written,
db.transaction
takes a callback. Your function is called at some point in time (even if very quickly).WARNING Note that this won't work as you can't pass username to the callback, it's only for example purpose.
Written a bit differently:
function doSeek(tx) { var result = tx.executeSql('SELECT * from data'); for (var i=0; i<result.rows.length; ++i) if(result.rows.item(i).name === username) { console.log("Found"); return true; } console.log("Not Found"); return false; } function seekName(username) { db.transaction(doSeek); }
Do you see now why you can't get the true/false result ?
[edit: Added some precision on the code content SGaist]
-
Do you see now why you can't get the true/false result ?
No, not yet, sadly! :|
The first paradox:
You said: "transaction is not a synchronous operation so you can't...", apparently the reason for not returning a true/false value from the for loop is related to SQL.
Here, "It has nothing to do with SQL programming but with how it's implemented in JavaScript", seemingly the reason is not SQL, but JavaScript!The second paradox:
In the above code you sent,username
is not defined and if we usefunction doSeek(username) ...
thentx
won't be defined! -
My other question is about the Qt Quick Local Storage reference. Docs explain it too briefly leaving many questions for the reader if they’re new in that.
For example, I cannot find the exact command to modify the content of a specific row in the table. And there might be more questions.What reference do you use to work with Qt Quick Local Storage for QML apps, please?
-
I've added the missing warning about the working state of the code. I wrote it so to show you how the logic is working not how to make it work the way you want as you can't have it anyway.
Before going further: Do you know what a callback is and how it works ?
Maybe this answer on stack overflow might be clearer.
You're use a SQLite database, so you write SQL statement to read and write to your database. You have tutorials all over the web. See for example here.