Android Question Pass ResultSet as object and handle it as a ResultSet?

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Making a Sub that puts up a dialog that optionally can also (beside labels, edittext and buttons) show a ResultSet, a list, a 1D string array or a map, all showing in the dialog as a flexible table.
Would it be possible to pass these 4 as an object and handle them as their proper type in the receiving Sub?
I guess this is not possible (especially with the ResultSet), but maybe it is.
I could of course make 4 different Subs or let the passing Sub make the flexible table and pass that to the receiving Sub.

RBS
 

LucaMs

Expert
Licensed User
Longtime User
Well, the Sub should have a parameter declared as Object, of course:

B4X:
Public Sub MyDialog(Data As Object)

Then you should use GetType to detect the type of the object:
B4X:
Dim DataType As String = GetType(Data)

B4X:
Select DataType
    Case ...
    Case ...
End Select

Write logs to read what DataType will contain (strings).
Then in each Case create an object of the type detected; for example, if it were a Map, you would create:
B4X:
Dim mapData As Map = Data

This can help you, in case of Arrays:
https://www.b4x.com/android/forum/threads/checks-on-arrays.39374/#content
 
Upvote 0

Knoppi

Active Member
Licensed User
Longtime User
here is a small example
B4X:
Public Sub Test
    DB_Initialize( File.DirApp, "computer_api.db")
    Dim query As String = "SELECT name FROM sqlite_master where type='table'"
    Dim rs As ResultSet = xSQL.ExecQuery( query)

    Dim mp As Map
    mp.Initialize
    mp.Put( "key1", "value1")
    mp.Put( "key2", "value2")
    mp.Put( "key3", "value3")

    Dim sa() As String = Array As String( "str1", "str2", "str3")

    Dim ls As List
    ls.Initialize
    ls.AddAll( sa)
    
    Log( GetType( rs))
    Log( GetType( mp))
    Log( GetType( ls))
    Log( GetType( sa))
    Log( "__________________")
    
    MyDialog( rs)
    MyDialog( sa)
    MyDialog( mp)
    MyDialog( ls)
    
End Sub

Private Sub MyDialog( Param As Object)
    Dim sb As StringBuilder
    sb.Initialize
    
    Select True
        Case GetType( Param).ToLowerCase.Contains("sqlite.rs")
            Dim rs As ResultSet = Param
            Do While rs.NextRow
                sb.Append( rs.GetString2(0)).Append(CRLF)
            Loop
            
        Case GetType( Param).ToLowerCase.Contains("map")
            Dim mp As Map = Param
            For Each key As String In mp.Keys
                sb.Append( key).Append( "=").Append( mp.Get( key)).Append( CRLF)
            Next
            
        Case GetType( Param).ToLowerCase.Contains("arraylist")
            Dim ls As List = Param
            For Each item As String In ls
                sb.Append( item).Append( CRLF)
            Next
            
        Case GetType( Param).ToLowerCase.Contains("string")
            Dim sa() As String = Param
            For Each item As String In sa
                sb.Append( item).Append( CRLF)
            Next
    End Select
    Log( sb.ToString)
    Log( "__________________")
End Sub
 
Upvote 0

teddybear

Well-Known Member
Licensed User
I'm not sure if I get it, it is possible you define the object having a tag property.
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Well, the Sub should have a parameter declared as Object, of course:

B4X:
Public Sub MyDialog(Data As Object)

Then you should use GetType to detect the type of the object:
B4X:
Dim DataType As String = GetType(Data)

B4X:
Select DataType
    Case ...
    Case ...
End Select

Write logs to read what DataType will contain (strings).
Then in each Case create an object of the type detected; for example, if it were a Map, you would create:
B4X:
Dim mapData As Map = Data

This can help you, in case of Arrays:
https://www.b4x.com/android/forum/threads/checks-on-arrays.39374/#content
Getting the type is no problem, but there is a problem with handling a ResultSet:

B4X:
Dim rs as ResultSet
rs = Data
Log(rs.RowCount)

Will give this error:

java.lang.ClassCastException: b4a.sqlitelight1.table cannot be cast to android.database.Cursor

RBS
 
Upvote 0

teddybear

Well-Known Member
Licensed User
B4X:
Dim rs as ResultSet
rs = Data
Log(rs.RowCount)
java.lang.ClassCastException: b4a.sqlitelight1.table cannot be cast to android.database.Cursor
You have to cast data as ResultSet
rs = Data.As(ResultSet)
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
I have tested the code in B4A, it is ok for compiling and running.
It works indeed in a simple example:

B4X:
Sub Test

    Dim RS As ResultSet
    
    RS = General.cConn.ExecQuery("select 1")
    
    GetResultSetAsObject(RS)

End Sub

Sub GetResultSetAsObject(oObject As Object)
    
    Dim RS As ResultSet = oObject
    
    Log(RS.RowCount)

End Sub
[CODE/]

In my particular situation it doesn't work however and gives me that error.
Maybe because my ResultSet is declared Public in the class that has the Sub that receives the ResultSet as an object.
Will investigate.

RBS
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
It works indeed in a simple example:

B4X:
Sub Test

    Dim RS As ResultSet
   
    RS = General.cConn.ExecQuery("select 1")
   
    GetResultSetAsObject(RS)

End Sub

Sub GetResultSetAsObject(oObject As Object)
   
    Dim RS As ResultSet = oObject
   
    Log(RS.RowCount)

End Sub
[CODE/]

In my particular situation it doesn't work however and gives me that error.
Maybe because my ResultSet is declared Public in the class that has the Sub that receives the ResultSet as an object.
Will investigate.

RBS
Sorry, should have ended the code with [/CODE] instead.

RBS
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
It works indeed in a simple example:

B4X:
Sub Test

    Dim RS As ResultSet
   
    RS = General.cConn.ExecQuery("select 1")
   
    GetResultSetAsObject(RS)

End Sub

Sub GetResultSetAsObject(oObject As Object)
   
    Dim RS As ResultSet = oObject
   
    Log(RS.RowCount)

End Sub
[CODE/]

In my particular situation it doesn't work however and gives me that error.
Maybe because my ResultSet is declared Public in the class that has the Sub that receives the ResultSet as an object.
Will investigate.

RBS
All solved now and this was a simple typo bug and in this particular one case a flexible table was passed and not a ResultSet.
Best to always look for the simple things first!

RBS
 
Upvote 0

MrKim

Well-Known Member
Licensed User
Longtime User
Making a Sub that puts up a dialog that optionally can also (beside labels, edittext and buttons) show a ResultSet, a list, a 1D string array or a map, all showing in the dialog as a flexible table.
Would it be possible to pass these 4 as an object and handle them as their proper type in the receiving Sub?
I guess this is not possible (especially with the ResultSet), but maybe it is.
I could of course make 4 different Subs or let the passing Sub make the flexible table and pass that to the receiving Sub.

RBS
I wrote this a while back - https://www.b4x.com/android/forum/threads/dbrequestmanager-make-recordset-more-useable.130168/
converts a resultset in to a list of maps and it is blazingly fast.
 
Upvote 0
Top