2. create the database
So let's start by making a class. Add a new standard class to the project and name it database. Make sure to add it to the parent folder.
Click on the database tab in the IDE.
Before we can use the database we must first initialize it. The code is different in B4A then in B4J. By using the #-directive you can specify the correct statement.
First add the SQL library to the project : check SQL in the Libraries Manager pane of the IDE.
Declare 2 variables: xui and sqllib.
Private xui As XUI
Public sqllib As SQL
The initialize method takes 4 arguments: the folder, the database name, the make boolean and the reset boolean.
The reset boolean can be used to remove the database from the project and start with a new one. If you are done testing then set it to false!
Replace the initialize code that is in the database class with:
Public Sub Initialize(folder As String,dbname As String, make As Boolean, reset As Boolean)
#If B4J
xui.SetDataFolder(folder)
#End If
If reset = True Then
File.Delete(xui.DefaultFolder,dbname) ' remove db for testing
End If
If File.Exists(xui.DefaultFolder,dbname) = False Then
#If B4J
sqllib.InitializeSQLite(xui.DefaultFolder,dbname,make)
#Else
sqllib.Initialize(xui.DefaultFolder,dbname,make)
#End If
Else
#If B4J
sqllib.InitializeSQLite(xui.DefaultFolder,dbname,make)
#Else
sqllib.Initialize(xui.DefaultFolder,dbname,make)
#End If
End If
Return
End Sub
Now you can declare a variable db in the Class_Globals subroutine of the B4XMainPage tab as a database type (= the name of the database class).
Private db As database
And in the B4XPage_Created subroutine you can initialize the db object:
db.Initialize("mybudget","budget_db",True,False)
We will be using a lot of SQL statements and for those occasions we provide a method.
For a simple SQL statement we make this subroutine (in the database tab):
Public Sub select_query(sql As String) As ResultSet
Private rs As ResultSet = sqllib.ExecQuery(sql)
Return rs
End Sub
For a prepared select query we make this method:
Public Sub select_query_prepared(sql As String, values() As String) As ResultSet
Private rs As ResultSet = sqllib.ExecQuery2(sql,values)
Return rs
End Sub
A prepared statement is used to prevent SQL-injection attacks. The query contains placeholders (?) for the values. These values are inserted in the query after the query was prepared by the database management system. So the contents of the values have no effect on the syntax of the query.
For action queries we use the following subroutine:
Public Sub action_query(sql As String, values As List)
sqllib.BeginTransaction
Try
sqllib.ExecNonQuery2(sql,values)
sqllib.TransactionSuccessful
Catch
Log(LastException.Message)
End Try
sqllib.EndTransaction
Return
End Sub
The transaction statements keep the database in a consistent state. If an action query fails then no changes are made to the database.
The following methods you find below are convenient to have.
The get_last_rowid method selects the last rowid that was added to the table.
The get_num_rows method counts the number of records in a table.
The table_exists method checks if the table exists in the database. If the table doesn't exists you have to create it.
The get_fieldnames method collects the fieldnames from a table. Using this method allows us to make general subroutines that can be used for any table!