BANanoSQL makes it possible to use 'normal' SQL queries on the IndexedDB database located in the browser.
There are three ways on how to work with BANanoSQL:
1. Event Driven
This is the advised mode to use as it follows the IndexedDB rules. Every open and execute command results in an event, and from there on, you can take the following step. The 'Tag' in the methods is used to guide the process.
Advantage: it can raise an Error Event in case e.g. an SQL is malformed
Disadvantage: if can become quite complex if many queries have to run
The results are posted in events.
The process here is:
2. Wait (from version 1.01)
This is the alternative. It does not raise events but waits until the query has finished. This method has wrappers around the IndexedDB system to call the alaSQL methods async.
Advantage: easy to read and follow in your code
Disadvantages:
- As it waits, and a long query runs, your app may appear to hang. It is unresponsive while waiting
- the calling method can NOT return a value
Does the same as method 1.
3. Event driven with your own callback (2.15+)
This is just like type 1, except you give it your own callback method.
I think all methods have a reason to exist. The second method may be useful to setup your database, or do a lot of INSERT queries, or if the flow is really complex.
The first and third one will give your users the best experience, as while the app is doing complex queries, he can still continue to work with it.
Your choice!
Alain
There are three ways on how to work with BANanoSQL:
1. Event Driven
This is the advised mode to use as it follows the IndexedDB rules. Every open and execute command results in an event, and from there on, you can take the following step. The 'Tag' in the methods is used to guide the process.
Advantage: it can raise an Error Event in case e.g. an SQL is malformed
Disadvantage: if can become quite complex if many queries have to run
The results are posted in events.
B4X:
Sub BANano_Ready()
SQL.Open("SQL", "bananodb")
End Sub
Sub SQL_SQLOpened()
SQL.Execute("CREATE TABLE IF NOT EXISTS flights (flightNo INT, fromCity STRING, toCity STRING, isInTheAir BOOL)", Null, "CREATE")
End Sub
Sub SQL_SQLExecuteError(Tag As String, Reason As String)
Log("ERROR for TAG:" & Tag & " Reason:" & Reason)
End Sub
Sub SQL_SQLExecuteResult(Tag As String, Result As List)
Select Case Tag
Case "CREATE"
SQL.Execute("SELECT COUNT(*) AS myCount FROM flights;", Null, "COUNT")
Case "COUNT"
Dim myCount As Int = 0
If Result.Size > 0 Then
Dim m As Map = Result.Get(0)
myCount = m.Get("myCount")
Log("myCount: " & myCount)
End If
myCount = myCount + 1
SQL.Execute("INSERT INTO flights (flightNo, fromcity, toCity, isInTheAir) VALUES (?, ?, ?, ?)", Array(myCount, "Brussels", "Paris", True), "INSERT")
Case "INSERT"
Log("We are done")
End Select
End Sub
The process here is:
Open -> SQLOpened -> Execute (Tag="CREATE") -> SQLExecuteResult (Case "CREATE") -> Execute (Tag="COUNT) -> SQLExecuteResult (Case "COUNT") -> Execute (Tag="INSERT") -> SQLExecuteResult (Case "INSERT")
2. Wait (from version 1.01)
This is the alternative. It does not raise events but waits until the query has finished. This method has wrappers around the IndexedDB system to call the alaSQL methods async.
Advantage: easy to read and follow in your code
Disadvantages:
- As it waits, and a long query runs, your app may appear to hang. It is unresponsive while waiting
- the calling method can NOT return a value
Does the same as method 1.
B4X:
Sub BANano_Ready()
SQL.OpenWait("SQL", "bananodb")
SQL.ExecuteWait("CREATE TABLE IF NOT EXISTS flights (flightNo INT, fromCity STRING, toCity STRING, isInTheAir BOOL)", Null)
Dim ret As List = SQL.ExecuteWait("SELECT COUNT(*) AS myCount FROM flights;", Null)
Dim MyCount As Int = SingleResult(ret, "myCount")
Log("MyCount Before: " & MyCount)
MyCount = MyCount + 1
SQL.ExecuteWait("INSERT INTO flights (flightNo, fromcity, toCity, isInTheAir) VALUES (?, ?, ?, ?)", Array(MyCount, "Brussels", "Paris", True))
End Sub
' helper method
public Sub SingleResult(lst As List, fieldName As String) As String
If lst <> Null Then
If lst.Size > 0 Then
Dim rec As Map = lst.Get(0)
Return rec.Get(fieldName)
End If
End If
Return "0"
End Sub
3. Event driven with your own callback (2.15+)
This is just like type 1, except you give it your own callback method.
B4X:
Sub SQL_SQLOpened() SQL.ExecuteCallback("CREATE TABLE IF NOT EXISTS flights (flightNo INT, fromCity STRING, toCity STRING, isInTheAir BOOL)", Null, Me, "mycreate")
End Sub
' MUST be this definition. No params can be added or removed!
Sub MyCreate(success As Boolean, Result As List, Reason As String) 'ignore
Log("Creation: " & success)
SQL.Execute("SELECT COUNT(*) AS myCount FROM flights;", Null, "COUNT")
End Sub
I think all methods have a reason to exist. The second method may be useful to setup your database, or do a lot of INSERT queries, or if the flow is really complex.
The first and third one will give your users the best experience, as while the app is doing complex queries, he can still continue to work with it.
Your choice!
Alain
Last edited: