B4J Question RDC2 - Columns in DBResult returns null - why?

miker2069

Active Member
Licensed User
Longtime User
First attempt at using RDC2 and testing with a simple example. I'm running the jRDC v2.1. It connects to my backend mariadb okay, seems to execute my sql statement (I just setup a simple "select * from table"). I can print the column names to log in the jRDC, so I know it's iterating through them properly, however in the client side (which is also B4J) the result.columns in my JobDone event is null. I do get back the result.rows and I can iterate over those. I'm wondering why the columns is coming back null? I believe I'm using the correct versions of the modules. I'm using DBRequestManagerResumableSubs.zip from here (The DBRequestManager.bas doesn't seem to work in B4J as it references a BitMap and I don't think there is such an object type in B4J - I think it's Image). Any event I'm using the ResumableSubs version.

The only thing I can think of is that something funky is happening in HandleJob. I'm simply just testing out dumping the result of a query to log before incorprating into my project. It might be worth mentioning that I am using the B4RSerializator in this project as well (I don't think there should be a conflict b/w the B4XSerializator but I thought I'd mention it).

I am also running everything in release mode (I do have two instances of B4J up, one for my client and the other for jRDC).

Thoughts?

My simple client code is below:


B4X:
    Sub Process_Globals
    Private reqManager As DBRequestManager
    Type DBResult (Tag As Object, columns As Map, Rows As List)
    Type DBCommand (Name As String, Parameters() As Object)

End Sub

Sub AppStart (Form1 As Form, Args() As String)
  
    'test
    reqManager.Initialize(Me, "http://localhost:17178/rdc")
    Dim cmd As DBCommand
    cmd.Initialize
    cmd.Name = "select_ir"
  
    reqManager.ExecuteQuery(cmd, 0, Null)
  
End Sub

Sub JobDone(Job As HttpJob)
    If Job.Success = False Then
        Log("Error: " & Job.ErrorMessage)
    Else
        If Job.JobName = "DBRequest" Then
            Dim result As DBResult = reqManager.HandleJob(Job)
            'work with result
            Log(result.Rows.Size) 'returns correct number of rows

            If result.columns = Null Then 'always null - why?
                Log("Columns is null")
                Return
            End If

            Dim sb As StringBuilder
            sb.Initialize
            For Each col In result.Columns.Keys
                sb.Append(col).Append(TAB)
            Next
            Log(sb.ToString)
          
            For Each row() As Object In result.Rows
                Dim sb As StringBuilder
                sb.Initialize
                For Each record As Object In row
                    sb.Append(record).Append(TAB)
                Next
                Log(sb.ToString)
            Next
        End If
    End If
    Job.Release
End Sub
 

miker2069

Active Member
Licensed User
Longtime User
Doing some tinkering - I modified the jRDC to set the columns map to the resp.tag. In my client I actually get the map properly.
I decided to try just return the columns map instead of the actual resp DBRESULT. I can get the columns map on the client just fine. It's very wierd that as part of DBRESULT the columns member comes back null. I also tried adding a columns2 to the DBRESULT type and setting that appropriately - I can get that as well. Wierd that I'm always getting columns=null when used as is.

I've totally deleted the jRDC folder/project (thinking there's something skewed with it) and recreated. Still same behavior.
 
Upvote 0

miker2069

Active Member
Licensed User
Longtime User
After more tinkering (since this issue was irking me as it didn't make sense that I could add additional members to DBRESULT as set it properly) with this it seems like I see the problem. in the jRDC (which I downloaded) I have DBRESULT defined as:

B4X:
'jRDC Type definition for DBResult .  columns is with an upper case 'C'
Type DBResult (Tag As Object, Columns As Map,Rows As List)

In my client code I have it defined as:
B4X:
'client side Type definition for DBResult - notice the lowercase 'c' in columns - this breaks serialization
Type DBResult (Tag As Object, columns As Map,Rows As List)

Notice that in my client code columns is with a lower case 'c' vs. upper case 'C' in the jRDC Type Def of DBRESULT. Apparently case matters when passing through the B4XSerializator. Not sure if that's by design or a bug, but definitely worth noting that case for custom types should be maintained on both sides of the client/server connection when serializing.
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Apparently case matters when passing through the B4XSerializator.
It's not the B4XSerializator, nor is it a bug. As per this post: "The type field names are case sensitive."
 
Upvote 0

miker2069

Active Member
Licensed User
Longtime User
Yeah I see that now - I paid attention to all the other case sensitive warnings (i.e. such as in the config.properties file). However it looks like the cause of all this is the IDE.

In my process globals I had (the type def line was copied and pasted from the forum):
B4X:
Sub Process_Globals
    Type DBResult (tag As Object,Columns As Map,Rows As List)

    private columns() as string

End Sub

After uppercasing Columns in the Type Def and then moving the cursor off of that line, the IDE lowercased it. So it looked like the following:

B4X:
Sub Process_Globals
    Type DBResult (tag As Object,columns As Map,Rows As List)

    private columns() as string

End Sub

So the IDE was lowercasing the Columns member of DBResult automatically and I didn't visually catch that it was doing that. I verified that the IDE will match the case of similar named process global variables even in TypeDef. I had columns defined in my project prior to testing out RDC so it was just bad luck on my part. It was baffling why it didn't work since I copied and pasted the typedef lines from examples in forum.

Obviously an easy fix is to set it to:

B4X:
Sub Process_Globals
    Type DBResult (tag As Object,Columns As Map,Rows As List)

    private Columns() as string

End Sub

This may not be a bug, but it's definitely something to be aware of.
 
Upvote 0
Top