B4J Library [B4X] jRDC2 - B4J implementation of RDC (Remote Database Connector)

Status
Not open for further replies.

RDC is a middleware server that makes it simple to safely connect clients and remote SQL database servers.

jRDC2 is the latest version. All new projects should use this version.

jRDC2 is made of two components:

- B4J server. The server receives the requests from the clients, issues the SQL commands against the database and returns the results.
In many cases the server will be hosted on the same computer that hosts the database server.
- Client module. The client which is compatible with B4A, B4J and B4i is responsible for sending the requests and handling the responses.

jRDC2 can work with any database that provides a JDBC driver. All popular databases are supported.
It is much more powerful than the PHP based solution and it has excellent performance.
It is also safer as the SQL commands are set in the server side.

Server configuration

1. Add the relevant JDBC jar file to the additional libraries folder.
2. Add a reference to this jar with:
B4X:
#AdditionalJar: mysql-connector-java-5.1.27-bin
3. Edit config.properties file that is located in the Files tab.


For example:

SS-2013-08-04_16.10.20.png


Note that the configuration fields are case sensitive.

Updates

- v2.21 - Date and time fields are automatically converted to ticks (long numbers) in SELECT queries.

DriverClass / JdbcUrl - The values of these two fields are specific to each database platform. You will usually find the specification together with the required driver jar file.

User / Password - Database user and password.

ServerPort - The Java server will listen to this provided port.

Debug - Option not used any more. It is automatically enabled when you run the server in debug mode (from the IDE).

SQL Commands - A list of commands. Each command starts with 'sql.'. The commands can include question marks (parameterised queries). Question marks will be replaced with the values provided by the Android clients. Note that the command name is case sensitive and it doesn't include the 'sql.' prefix.

4. Run the program and test it locally by putting this link in the local browser: http://localhost:17178/test

Note that the server port must be open for incoming connections in the firewall.

Client configuration

1. Add to Main module (must be in Main module):
B4X:
Sub Process_Globals
   Type DBResult (Tag As Object, Columns As Map, Rows As List)
   Type DBCommand (Name As String, Parameters() As Object)
   Private const rdcLink As String = "http://192.168.0.6:17178/rdc"
End Sub
Change the link with the ip address or host name of the server hosting jRDC2. It must end with /rdc.

2. Add DBRequestManager class to your project.
It depends on RandomAccessFile and OkHttpUtils2 libraries (or the matching libraries in B4J or B4i).

3. Add these two subs:
B4X:
Sub CreateRequest As DBRequestManager
   Dim req As DBRequestManager
   req.Initialize(Me, rdcLink)
   Return req
End Sub

Sub CreateCommand(Name As String, Parameters() As Object) As DBCommand
   Dim cmd As DBCommand
   cmd.Initialize
   cmd.Name = Name
   If Parameters <> Null Then cmd.Parameters = Parameters
   Return cmd
End Sub

A new DBRequestManager is created for each request.

Example of sending a SELECT request:
B4X:
Sub GetRecord (id As Int)
   Dim req As DBRequestManager = CreateRequest
   Dim cmd As DBCommand = CreateCommand("select_animal", Array(id))
   Wait For (req.ExecuteQuery(cmd, 0, Null)) JobDone(j As HttpJob)
   If j.Success Then
       req.HandleJobAsync(j, "req")
       Wait For (req) req_Result(res As DBResult)
       'work with result
       req.PrintTable(res)
   Else
       Log("ERROR: " & j.ErrorMessage)
   End If
   j.Release
End Sub
The select_animal command is defined in the config file:
B4X:
sql.select_animal=SELECT name, image, id FROM animals WHERE id = ?

Note that you can make multiple requests at the same time.
The result is a DBResult object.

Example of sending an INSERT request:
B4X:
Sub InsertRecord (Name As String)
   Dim cmd As DBCommand = CreateCommand("insert_animal", Array(Name, Null))
   Dim j As HttpJob = CreateRequest.ExecuteBatch(Array(cmd), Null)
   Wait For(j) JobDone(j As HttpJob)
   If j.Success Then
       Log("Inserted successfully!")
   End If
   j.Release
End Sub
In this case a single command was sent. You can send multiple commands at once.
The insert_animal command is defined in the config file:
B4X:
sql.create_table=CREATE TABLE IF NOT EXISTS animals (\
     id INTEGER PRIMARY KEY AUTO_INCREMENT,\
     name CHAR(30) NOT NULL,\
     image BLOB)
sql.insert_animal=INSERT INTO animals VALUES (null, ?,?)


Notes

- Running a B4J server program on your hosted server: [server] Run a Server on a VPS
- There are three utility methods in DBRequestManager: FileToBytes, ImageToBytes and BytesToImage. You can use them when working with blobs.
- Extending jRDC2 to support B4R: https://www.b4x.com/android/forum/threads/rdc-based-on-mqtt.72416/#content

Updates

v2.23 - Adds support for CLOB fields (large strings).
v2.22 - Fixes an issue with null time values.
v2.21 - Date and time fields are converted to ticks (long numbers) automatically in select queries.
Note that the VERSION1 code is excluded by default. It is only relevant if there are clients running the old RDC code.


Please start a new thread for any question you have.
 

Attachments

  • DBRequestManager.bas
    4.4 KB · Views: 4,921
  • jRDC2.zip
    5.5 KB · Views: 201
Last edited:

micro

Well-Known Member
Licensed User
Hi to all
I'm running same test with JRDC2 and i have same problems with mysql driver, with sqlite all ok.
How I create a empty mysql db?
And where i put the empty db created?
Thanks
 

Dey

Active Member
Licensed User
Hello to all
I'm successfully using RCD V0.9
connected to the server PC and smartphone wifi
I am not clear if I switch to jRDC2?


B4X:
'Non-UI application (console / server application)
#Region  Project Attributes
    #CommandLineArgs:
    #MergeLibraries: True
#End Region

'change based on the jdbc jar file
'#AdditionalJar: mysql-connector-java-5.1.27-bin
#AdditionalJar: sqlite-jdbc-3.7.2.jar
'#AdditionalJar: postgresql-9.4.1207

Sub Process_Globals
    Public srvr As Server
    Public rdcConnector1 As RDCConnector
    Public const VERSION As Float = 2.1
    Type DBCommand (Name As String, Parameters() As Object)
    Type DBResult (Tag As Object, Columns As Map, Rows As List)
End Sub

Sub AppStart (Args() As String)
    srvr.Initialize("")
    rdcConnector1.Initialize
    srvr.Port = rdcConnector1.serverPort
    srvr.AddHandler("/test", "TestHandler", False)
    srvr.AddHandler("/rdc", "RDCHandler", False)
    srvr.Start
    Log($"jRDC is running (version = $1.2{VERSION})"$)
    StartMessageLoop
End Sub


B4X:
Waiting for debugger to connect...
Program started.
2016-03-18 14:05:33.528:INFO::main: Logging initialized @2479ms
mar 18, 2016 2:05:33 PM com.mchange.v2.log.MLog <clinit>
INFORMAZIONI: MLog clients using java 1.4+ standard logging.
mar 18, 2016 2:05:33 PM com.mchange.v2.c3p0.C3P0Registry banner
INFORMAZIONI: Initializing c3p0-0.9.2.1 [built 20-March-2013 11:16:28 +0000; debug? true; trace: 10]
2016-03-18 14:05:33.706:INFO:oejs.Server:main: jetty-9.3.z-SNAPSHOT
2016-03-18 14:05:33.729:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@27efef64{/,file:///G:/Developer/Android/Samples/RDC%20V2/jRDC2/jRDC/Objects/www,AVAILABLE}
2016-03-18 14:05:33.731:INFO:oejs.AbstractNCSARequestLog:main: Opened G:\Developer\Android\Samples\RDC V2\jRDC2\jRDC\Objects\logs\b4j-2016_03_18.request.log
2016-03-18 14:05:33.765:INFO:oejs.ServerConnector:main: Started ServerConnector@56235b8e{HTTP/1.1,[http/1.1]}{0.0.0.0:17178}
2016-03-18 14:05:33.766:INFO:oejs.Server:main: Started @2717ms
Emulated network latency: 100ms
jRDC is running (version = 2.1)
 

Haris Hafeez

Active Member
Licensed User
jRDC v2.1 is released (first post). It fixes an issue with numeric types breaking the response.
I am still getting errors when the sql includes numeric columns. I am however using mysql so the fix might have fixed it for other DBs (this link explains similar issue but with oracle and postgresql).

For now the workaround is to use the mysql cast function to cast any numeric values to char. Haven't tested other data types yet.
 

Dey

Active Member
Licensed User
Question
JRDC2 Async works with a class?
I have problems in this case:(
No Async is ok:)
Thank you
 

rwblinn

Well-Known Member
Licensed User
Just to clarify, RDC is made of a server and clients components. DBRequestManager module is the client implementation and it is supported by B4A, B4i and B4J.
The version download from this post attachment contains type bitmap (sub Public Sub ImageToBytes(Image As Bitmap) As Byte())
which are not supported by B4J = images instead.

Question: Is there a B4J version available using Image?
 

Erel

Administrator
Staff member
Licensed User
Replace the subs with these subs:
B4X:
'Converts an image to a bytes array (for BLOB fields).
Public Sub ImageToBytes(Image As Image) As Byte()
   Dim out As OutputStream
   out.InitializeToBytesArray(0)
   Image.WriteToStream(out)
   out.Close
   Return out.ToBytesArray
End Sub
'Converts a bytes array to an image (for BLOB fields).
Public Sub BytesToImage(bytes() As Byte) As Image
   Dim In As InputStream
   In.InitializeFromBytesArray(bytes, 0, bytes.Length)
   Dim bmp As Image
   bmp.Initialize2(In)
   Return bmp
End Sub
 

dars

New Member
Licensed User
Hi,
I'm new here, and trying to find B4XSerializator lib.
Any suggestion is appreciated.

rgds.
dar.
 

achtrade

Active Member
Licensed User
I still didnt get it. :( Dont know where I am going wrong. I copied the sql connector jar in www folder of my server. I set the url to shared ip address of my server still not able to connect to Mysql db on server by running jar in local computer. tried both the ports in the URL but it didnt work. any suggestion is appreciated.

I have the same problem, I don't get it either. This tutorial is not detailed enough, mainly in the server installation side. I didn't get the answer in the threat suggested for Erel.

I'm using RDC without problem, should I switch to jRDC2 ?
 

shashkiranr

Active Member
Licensed User
I have the same problem, I don't get it either. This tutorial is not detailed enough, mainly in the server installation side. I didn't get the answer in the threat suggested for Erel.

I'm using RDC without problem, should I switch to jRDC2 ?

I am running multiple B4J webservers now. If you want I can create a detailed tutorial. are you running B4J server in a VPS?

Best,
SK
 
Status
Not open for further replies.
Top