B4J Library [B4X] [B4XLib] SD_SQL (direct access to MySQL, MariaDB, MS SQL, FireBird)

Star-Dust

Expert
Licensed User
Longtime User
Well, I'll give a quick summary.
To access MySql you had to import a driver or connector in C which is impossible for me because I ignore the language and compile with Host Builder.

So I decided to create a collector/driver from scratch in B4X... and it seems to work... I still have to improve and finalize ResultSet and it will take a week or more.... but it works, logs in, authenticates and reads the data

B4X:
db.Initialize(Me,"db")
db.Connect("192.168.1.103","root","password")
  
Wait For db_Connected (Success As Boolean, Message As String)
If Success Then    db.executeQuery("SHOW DATABASES")

A little piece of code:
Sub Class_Globals
    Private host As String
    Private port As Int
    Private client As Socket
    Private aStream As AsyncStreams

    Private mCakkBack As Object
    Private mEventName As String
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize(CallBack As Object, EventName As String)
    mCakkBack=CallBack
    mEventName=EventName & "_"
    port=3306
End Sub

Public Sub Connect(Address As String,username As String, password As String)
    host=Address
    user=username
    pass=password
    client.Initialize("client")
    client.Connect(host,port,3000)
End Sub


 
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
Given the many requests I have received to develop a version for iOS I imagined a more enthusiastic welcome from the forum.

I realized that I understand IT well but not people well ?
 
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
Update.

Completed the MySql connector written entirely in B4X. Tried with all types and with different tables and databases. It seems to work correctly.
I just need to improve the resultSet to not keep the data in the ram memory as I receive it. But I have time to work on it...
 

mikhatri

Member
Hi, how to get error on Connection and display in msgbox. already error show in log(). but i want to show it in msgbox.

MYSQL Connection:
    MYSQL.Connect("org.mariadb.jdbc.Driver", _
            $"jdbc:mariadb://${MyLocation}/bhairav_mall_db"$, _
            DBUsername, _
            DBPassword)
           
    Wait For MYSQL_Ready(Success As Boolean)
    If Success Then
        Log("Cnnection Success")
    Else
        Log(LastException)
        MsgboxAsync("Error in Connection. Please setup your host ip address properly.","")
    End If

i want to "Wait For MYSQL_Error(Message As String)" somethink like this...
 

Julio Quijas

New Member
Licensed User
Longtime User
Hi, I am using a translator to ask my question, I am new and I hope I am doing the query correctly and thanks in advance for the help, I hope it is understood correctly. I have two functions that are called from Activity_Create(), the Cargar_Servicios() function and the Cargar_Mesas() function, each function makes a different query to the DB. When the Cargar_Servicios() function is being executed and it reaches the line wait for MYSQL_Ready(Success As Boolean) it jumps to the Cargar_Mesas() function without finishing the Cargar_Servicios() function, how can I make it wait and finish the Cargar_Servicios() function before starting the Cargar_Mesas() function?

B4X:
Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    
    If FirstTime Then
        formatter.Initialize
        Dim DefaultFormat As B4XFormatData = formatter.GetDefaultFormat
        DefaultFormat.MaximumFractions = 2
        DefaultFormat.MinimumFractions = 2
        DefaultFormat.Prefix = "$ "
        Dim NegativeFormat As B4XFormatData = formatter.CopyFormatData(DefaultFormat)
        NegativeFormat.TextColor = xui.Color_Red
        NegativeFormat.Prefix = "$ ("
        NegativeFormat.Postfix = ")"
        NegativeFormat.FormatFont = xui.CreateDefaultBoldFont(15)
        formatter.AddFormatData(NegativeFormat, formatter.MIN_VALUE, 0, False)
    End If
    
    phone1.SetScreenOrientation(0)
    Activity.LoadLayout("Principal")
    'PnlFondo.Visible=False
    
    pv=True
    
    scServicios.ChipPropertiesGlobal.xFont=xui.CreateDefaultBoldFont(18)
    scServicios.ChipPropertiesGlobal.Height=60
    scServicios.ChipPropertiesGlobal.TextGap=10
    
    slvMesas.ButtonsGridListVisible=False
    slvMesas.ButtonAddVisible=False
    slvMesas.ButtonExitVisible=False
    slvMesas.FilterVisible=False
    slvMesas.TurnToList
    
    Cargar_Servicios
    Cargar_Mesas(0)
End Sub

Sub Cargar_Servicios() As ResumableSub
    Dim MYSQL As SD_SQL
    MYSQL.Initialize(Me,"MYSQL")
    MYSQL.Connect("com.mysql.jdbc.Driver", $"jdbc:mysql://${Main.Configuracion_Red.serv}:${Main.Configuracion_Red.port}/${Main.Configuracion_Red.db}?useSSL=false"$,Main.Configuracion_Red.usr,Main.Configuracion_Red.pwd)
    wait for MYSQL_Ready(Success As Boolean)
    If Success=True Then
        If pv=True Then
            Dim RS As SD_ResultSet = MYSQL.ExecQuery("SELECT id,den,imga FROM v_usuarios_servicios WHERE dk=0 AND usrid=1")
            Do While RS.NextRow
                If (RS.GetBytes("imga")<>Null) Then
                    ImagenServicio(RS.GetBytes("imga"))
                Else
                    tmpimg=LoadBitmap(File.DirAssets,"vacioC.jpg")
                End If
                
                scServicios.AddChip(RS.GetString("den"),tmpimg,RS.GetString("id"))
            Loop   
            RS.Close
            
            'Dim RS As SD_ResultSet = MYSQL.ExecQuery("SELECT imga FROM t_cat_servicios WHERE dk=0 and id=" & scServicios.GetChip(0).Tag)
            'Do While RS.NextRow
            '    If (RS.GetBytes("imga")<>Null) Then
            '        ImagenServicio(RS.GetBytes("imga"))
            '    Else
            '        tmpimg=LoadBitmap(File.DirInternal,"vacioC.jpg")
            '    End If
            'Loop   
            'RS.Close
        End If
        'PnlFondo.Visible=True
    Else
        Msgbox("No se pudo conectar PRINCIPAL","FALLO")
    End If
    Return Null
End Sub

Sub Cargar_Mesas(ns As Int)
    Dim MYSQL2 As SD_SQL
    MYSQL2.Initialize(Me,"MYSQL")
    MYSQL2.Connect("com.mysql.jdbc.Driver", $"jdbc:mysql://${Main.Configuracion_Red.serv}:${Main.Configuracion_Red.port}/${Main.Configuracion_Red.db}?useSSL=false"$,Main.Configuracion_Red.usr,Main.Configuracion_Red.pwd)
    wait for MYSQL2_Ready (Success As Boolean)
    If Success=True Then
        slvMesas.ClearAll
        Dim RS As SD_ResultSet = MYSQL2.ExecQuery("SELECT * FROM v_mesa_activa WHERE idserv=" & scServicios.GetChip(ns).Tag)
        Do While RS.NextRow
            slvMesas.AddItem(RS.GetString("idmesa"),scServicios.GetChip(ns).Icon,RS.GetString("nomm") & " " & RS.GetString("idmesa"),RS.GetString("idcon"),RS.GetString("idconmesa"))
            'slvMesas.AddItemNoImage(RS.GetString("idmesa"),RS.GetString("nomm") & " " & RS.GetString("idmesa"),RS.GetString("idcon"),RS.GetString("idconmesa"))
        Loop
        RS.Close
        slvMesas.Invalidate
        If pv=True Then
            scServicios.SetSelections(Array As Int(0))
            pv=False
        End If
    End If
End Sub
 

Star-Dust

Expert
Licensed User
Longtime User
This question is not related to the functioning of the library, so you should ask in the main forum next time. Here you can ask questions related to the library's internal engine or its operation.

The answer to your question is related to the use of WAIT FOR. Below you will find the correct code. The correct steps are colored

B4X:
Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
   
    If FirstTime Then
        formatter.Initialize
        Dim DefaultFormat As B4XFormatData = formatter.GetDefaultFormat
        DefaultFormat.MaximumFractions = 2
        DefaultFormat.MinimumFractions = 2
        DefaultFormat.Prefix = "$ "
        Dim NegativeFormat As B4XFormatData = formatter.CopyFormatData(DefaultFormat)
        NegativeFormat.TextColor = xui.Color_Red
        NegativeFormat.Prefix = "$ ("
        NegativeFormat.Postfix = ")"
        NegativeFormat.FormatFont = xui.CreateDefaultBoldFont(15)
        formatter.AddFormatData(NegativeFormat, formatter.MIN_VALUE, 0, False)
    End If
   
    phone1.SetScreenOrientation(0)
    Activity.LoadLayout("Principal")
    'PnlFondo.Visible=False
   
    pv=True
   
    scServicios.ChipPropertiesGlobal.xFont=xui.CreateDefaultBoldFont(18)
    scServicios.ChipPropertiesGlobal.Height=60
    scServicios.ChipPropertiesGlobal.TextGap=10
   
    slvMesas.ButtonsGridListVisible=False
    slvMesas.ButtonAddVisible=False
    slvMesas.ButtonExitVisible=False
    slvMesas.FilterVisible=False
    slvMesas.TurnToList
   
    WAIT FOR (Cargar_Servicios) COMPLETE (Success As Boolean)
    Cargar_Mesas(0)
End Sub

Sub Cargar_Servicios() As ResumableSub
    Dim MYSQL As SD_SQL
    MYSQL.Initialize(Me,"MYSQL")
    MYSQL.Connect("com.mysql.jdbc.Driver", $"jdbc:mysql://${Main.Configuracion_Red.serv}:${Main.Configuracion_Red.port}/${Main.Configuracion_Red.db}?useSSL=false"$,Main.Configuracion_Red.usr,Main.Configuracion_Red.pwd)
    wait for MYSQL_Ready(Success As Boolean)
    If Success=True Then
        If pv=True Then
            Dim RS As SD_ResultSet = MYSQL.ExecQuery("SELECT id,den,imga FROM v_usuarios_servicios WHERE dk=0 AND usrid=1")
            Do While RS.NextRow
                If (RS.GetBytes("imga")<>Null) Then
                    ImagenServicio(RS.GetBytes("imga"))
                Else
                    tmpimg=LoadBitmap(File.DirAssets,"vacioC.jpg")
                End If
               
                scServicios.AddChip(RS.GetString("den"),tmpimg,RS.GetString("id"))
            Loop  
            RS.Close
           
            'Dim RS As SD_ResultSet = MYSQL.ExecQuery("SELECT imga FROM t_cat_servicios WHERE dk=0 and id=" & scServicios.GetChip(0).Tag)
            'Do While RS.NextRow
            '    If (RS.GetBytes("imga")<>Null) Then
            '        ImagenServicio(RS.GetBytes("imga"))
            '    Else
            '        tmpimg=LoadBitmap(File.DirInternal,"vacioC.jpg")
            '    End If
            'Loop  
            'RS.Close
        End If
        'PnlFondo.Visible=True
    Else
        Msgbox("No se pudo conectar PRINCIPAL","FALLO")
    End If
    Return True
End Sub

Sub Cargar_Mesas(ns As Int)
    Dim MYSQL2 As SD_SQL
    MYSQL2.Initialize(Me,"MYSQL")
    MYSQL2.Connect("com.mysql.jdbc.Driver", $"jdbc:mysql://${Main.Configuracion_Red.serv}:${Main.Configuracion_Red.port}/${Main.Configuracion_Red.db}?useSSL=false"$,Main.Configuracion_Red.usr,Main.Configuracion_Red.pwd)
    wait for MYSQL2_Ready (Success As Boolean)
    If Success=True Then
        slvMesas.ClearAll
        Dim RS As SD_ResultSet = MYSQL2.ExecQuery("SELECT * FROM v_mesa_activa WHERE idserv=" & scServicios.GetChip(ns).Tag)
        Do While RS.NextRow
            slvMesas.AddItem(RS.GetString("idmesa"),scServicios.GetChip(ns).Icon,RS.GetString("nomm") & " " & RS.GetString("idmesa"),RS.GetString("idcon"),RS.GetString("idconmesa"))
            'slvMesas.AddItemNoImage(RS.GetString("idmesa"),RS.GetString("nomm") & " " & RS.GetString("idmesa"),RS.GetString("idcon"),RS.GetString("idconmesa"))
        Loop
        RS.Close
        slvMesas.Invalidate
        If pv=True Then
            scServicios.SetSelections(Array As Int(0))
            pv=False
        End If
    End If
End Sub
 

Mashiane

Expert
Licensed User
Longtime User
Hi

Im trying this, however I get errors.

B4X:
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.

and

B4X:
Not connected: java.sql.SQLException: No suitable driver found for jdbc:mysql:33068//179.x.x.x/dbname?useSSL=false

I'm using port 33068 for MySQL and, #AdditionalJar: mysql-connector-java-8.4.0.jar with mysql 8.

I would appreciate some advise. Thanks.

PS:

B4X:
MYSQL.Connect("com.mysql.jdbc.Driver", $"jdbc:mysql:33068//${MyLocation}/${MyDataBaseName}?useSSL=false"$,  MyUsername, MyPassword)