Android Question Problem with Length function in B4XTable SQL

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Just started to experiment with B4XTable, using the provided example project as provided by Erel in the first post regarding B4XTable.
I added some extra options to the search facility, edited the Subs:
Public Sub BuildQuery
Private Sub ImplUpdateDataFromQuery

B4X:
Public Sub BuildQuery (WithPageLimit As Boolean) As Object()
    
    Dim c As Int
    Dim n As Int
    Dim SortColumn As String
    Dim strFind As String
    Dim sb As StringBuilder

    sb.Initialize
    sb.Append("SELECT rowid")
    
    For Each col As B4XTableColumn In VisibleColumns
        If col.ColumnType = COLUMN_TYPE_VOID Then Continue
        sb.Append(",").Append(col.SQLID)
        If col.InternalSortMode <> "" Then
            SortColumn = " ORDER BY " & col.SQLID & " " & col.InternalSortMode
        End If
    Next
    
    sb.Append(" FROM ").Append(SQLTableName).Append(" ")
    Dim args As List
    args.Initialize
    Dim TotalCount As Int
    
    If iSearchConditions = 0 Then
        TotalCount = CountAll
        mCurrentCount = CountAll
        miCountOfPages = Ceil(mCurrentCount / mRowsPerPage)
    Else
        For Each col As B4XTableColumn In VisibleColumns
            If col.Searchable Then
                For n = 0 To arrCheckConditions(c) - 1
                    strFind = arrConditions(c, n).strSearchText
                    Log("BuildQuery, strFind: " & strFind)
                    If args.Size = 0 Then
                        sb.Append(" WHERE ")
                    Else
                        If arrConditions(c, n).bSQL_OR Then
                            'this used to be all OR
                            sb.Append(" OR ")
                        Else
                            sb.Append(" AND ")
                        End If
                    End If
                    If col.ColumnType = COLUMN_TYPE_INTEGER Or col.ColumnType = COLUMN_TYPE_DOUBLE Then
                        If arrConditions(c, n).strOperator.Length = 0 Then
                            sb.Append(col.SQLID).Append(" = ? ")
                        Else
                            sb.Append(col.SQLID).Append(" ").Append(arrConditions(c, n).strOperator).Append(" ? ")
                        End If
                        args.Add(strFind)
                    Else
                        If arrConditions(c, n).strOperator.StartsWith("length") Then
                            'this doesn't work for some reason as it always produces zero for the length
                            Select Case arrConditions(c, n).strOperator
                                Case "length ="
                                    sb.Append("length(").Append(col.SQLID).Append(") = ? ")
                                Case "length >"
                                    sb.Append("length(").Append(col.SQLID).Append(") > ? ")
                                Case "length <"
                                    sb.Append("length(").Append(col.SQLID).Append(") < ? ")
                                Case "length <>"
                                    sb.Append("length(").Append(col.SQLID).Append(") <> ? ")
                            End Select
                            args.Add(strFind) 'adding the length to look at
                        Else
                            If arrConditions(c,n).bWildCard Then
                                If arrConditions(c,n).bCaseSensitive Then
                                    sb.Append(col.SQLID).Append(" GlOB ? ")
                                    If arrConditions(c,n).bPrefixSearch Then
                                        args.Add(strFind & "*")
                                    Else
                                        args.Add("*" & strFind & "*")
                                    End If
                                Else
                                    sb.Append(col.SQLID).Append(" LIKE ? ")
                                    If arrConditions(c,n).bPrefixSearch Then
                                        args.Add(strFind & "%")
                                    Else
                                        args.Add("%" & strFind & "%")
                                    End If
                                End If
                            Else
                                If arrConditions(c, n).bCaseSensitive Then
                                    If arrConditions(c, n).strOperator.Length = 0 Then
                                        sb.Append(col.SQLID).Append(" = ? ")
                                    Else
                                        sb.Append(col.SQLID).Append(" ").Append(arrConditions(c, n).strOperator).Append(" ? ")
                                    End If
                                    args.Add(strFind)
                                Else
                                    If arrConditions(c, n).strOperator.Length = 0 Then
                                        sb.Append("lower(").Append(col.SQLID).Append(") = ? ")
                                    Else
                                        sb.Append("lower(").Append(col.SQLID).Append(") ").Append(arrConditions(c, n).strOperator).Append(" ? ")
                                    End If
                                    args.Add(strFind.ToLowerCase)
                                End If
                            End If
                        End If
                    End If
                Next
            End If
            c = c + 1
        Next
        TotalCount = -1
    End If
    
    If SortColumn <> "" Then sb.Append(SortColumn)
    
    If WithPageLimit Then
        Dim limit As Int = mRowsPerPage
        If TotalCount < 0 Then limit = limit + 1
        sb.Append($" LIMIT ${mFirstRowIndex}, ${limit}"$) 'LIMIT offset, row_count
    End If
    
    #if B4A
    Dim aargs(args.Size) As String
    For i = 0 To args.Size - 1
        aargs(i) = args.Get(i)
    Next
    #else
    Dim aargs As List = args
    #End If
    Return Array(sb.ToString, aargs, TotalCount)
End Sub

Private Sub ImplUpdateDataFromQuery (Query As String, Args As Object, TotalCount As Int, DontSleep As Boolean)

    Dim i As Int
    Dim iCol As Int
    Dim arrArgs() As String = Args
    
    SQLIndex = SQLIndex + 1
    
    If mRowsPerPage = 0 Then Return
    
    Dim MyIndex As Int = SQLIndex
    If DontSleep = False Then
        Sleep(40)
    End If
    If MyIndex <> SQLIndex Then
        Return
    End If
    VisibleRowIds.Clear
    
    Dim rs As ResultSet = sql1.ExecQuery2(Query, arrArgs)
    Log("ImplUpdateDataFromQuery, rs.RowCount: " & rs.RowCount)

    Dim success As Boolean = True

    If success Then
        Dim RowNumber As Int = 1
        Do While RowNumber <= mRowsPerPage And rs.NextRow
            VisibleRowIds.Add(rs.GetLong("rowid"))
            iCol = 0
            For Each c As B4XTableColumn In VisibleColumns
                Dim lbl As B4XView = GetLabelFromColumn(c, RowNumber)
                Select c.ColumnType
                    Case COLUMN_TYPE_TEXT
                        SetTextToCell(rs.GetString(c.SQLID), lbl, c.Searchable, iCol) 'SetTextToCell was edited to give the extra iCol argument
                    Case COLUMN_TYPE_INTEGER
                        c.Formatter.FormatLabel(rs.GetInt(c.SQLID), lbl)
                    Case COLUMN_TYPE_DOUBLE
                        c.Formatter.FormatLabel(rs.GetDouble(c.SQLID), lbl)
                    Case COLUMN_TYPE_DATE
                        lbl.Text = DateTime.Date(rs.GetLong(c.SQLID))
                End Select
                iCol = iCol + 1
            Next
            RowNumber = RowNumber + 1
        Loop
        
        rs.Close
        
        For i = RowNumber To mRowsPerPage
            iCol = 0
            For Each c As B4XTableColumn In VisibleColumns
                #if B4J
                SetTextToCell("", GetLabelFromColumn(c, i), c.Searchable, iCol)
                #else
                GetLabelFromColumn(c, i).Text = ""
                #End If
                iCol = iCol + 1
            Next
            VisibleRowIds.Add(0)
        Next
        mLastRowIndex = mFirstRowIndex - 2 + RowNumber

        If iSearchConditions > 0 Then
            mCurrentCount = TotalCount
            miCountOfPages = Ceil(mCurrentCount / mRowsPerPage)
        End If
        mCurrentPage = Ceil(mFirstRowIndex / mRowsPerPage) + 1
    Else
        Log(LastException)
    End If

    'this is to get the total number of rows obtained in the search and pass this to the B4XPage
    '-------------------------------------------------------------------------------------------
    If Query.ToLowerCase.Contains(" order by ") = False Then
        If bRunningSearch And Query.ToLowerCase.Contains(" where ") Then
            Dim strWhereClause As String = GetWhereClauseFromQuery(Query)
            Log("ImplUpdateDataFromQuery, SQL: " & "select count(*) from data " & strWhereClause)
            Log("ImplUpdateDataFromQuery, arrArgs(0): " & arrArgs(0))
            Dim SenderFilter As Object = sql1.ExecQueryAsync("SQL", "select count(*) from data " & strWhereClause, arrArgs)
            Wait For (SenderFilter) SQL1_QueryComplete (success As Boolean, rs2 As ResultSet)
        End If
    End If
    
    bRunningSearch = False

    If xui.SubExists(mCallBack, mEventName & "_DataUpdated", 0) Then
        CallSub(mCallBack, mEventName & "_DataUpdated")
    End If
End Sub

All works perfectly fine, except when using the length function, which for some reason always produces zero.
All the above logs give the expected result, so I have no idea what the problem could be.
If I use the same SQL (so with the same data and with the SQLite length function) on a regular DB (so, not the in-memory database used
by B4XTable) then that gives me the expected result.
Any idea what the problem could here?

RBS

RBS
 

Mahares

Expert
Licensed User
Longtime User
except when using the length function, which for some reason always produces zero.
I don't think you can use the LENGTH function when using the in memory data base table because of this statement in the SQLite docs:
For string values, length(X) must read the entire string into memory in order to compute the character length
I tried it with my in memory table before and could not get it to work . But, don't rely on my answer until Erel confirms it or denies it for you.
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
I don't think you can use the LENGTH function when using the in memory data base table because of this statement in the SQLite docs:
For string values, length(X) must read the entire string into memory in order to compute the character length
I tried it with my in memory table before and could not get it to work . But, don't rely on my answer until Erel confirms it or denies it for you.
Yes, I found the same. Getting length from a blob is a lot faster. I didn't see though there is problem getting length from a string in an in-memory DB.
RBS
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
This code works to populate the B4XTable with rows where the 2nd col contains empty strings:
B4X:
Private Sub Button2_Click  'look for empty strings in 2nd col of in mem table
    MyList.Initialize
    Dim o() As Object = B4XTable1.BuildQuery(False)
    Dim s As String ="SELECT *, length(c1) AS ln FROM data WHERE ln = 0"
    o(0)=s
    o(1) =Null
    Dim rs As ResultSet = B4XTable1.sql1.ExecQuery2(o(0), o(1))
    Do While rs.NextRow
        Dim r() As Object = Array(rs.getint("c0"), rs.getstring("c1"),rs.GetString("c2"))
        MyList.Add(r)
    Loop
    B4XTable1.SetData(MyList)
    rs.Close
End Sub
But this below one does not show any records on the table. I don't know why, although they seem to be equivalent.
B4X:
Private Sub Button2_Click  
    MyList.Initialize
    Dim o() As Object = B4XTable1.BuildQuery(False)
    Dim s As String ="SELECT *, length(c1) AS ln FROM data WHERE ln = ?"
    o(0)=s
    o(1)=Array As String(0)  'even if I use Int or Object
    Dim rs As ResultSet = B4XTable1.sql1.ExecQuery2(o(0), o(1))
    Do While rs.NextRow
        Dim r() As Object = Array(rs.getint("c0"), rs.getstring("c1"),rs.GetString("c2"))
        MyList.Add(r)
    Loop
    B4XTable1.SetData(MyList)
    rs.Close
End Sub
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
This code works to populate the B4XTable with rows where the 2nd col contains empty strings:
B4X:
Private Sub Button2_Click  'look for empty strings in 2nd col of in mem table
    MyList.Initialize
    Dim o() As Object = B4XTable1.BuildQuery(False)
    Dim s As String ="SELECT *, length(c1) AS ln FROM data WHERE ln = 0"
    o(0)=s
    o(1) =Null
    Dim rs As ResultSet = B4XTable1.sql1.ExecQuery2(o(0), o(1))
    Do While rs.NextRow
        Dim r() As Object = Array(rs.getint("c0"), rs.getstring("c1"),rs.GetString("c2"))
        MyList.Add(r)
    Loop
    B4XTable1.SetData(MyList)
    rs.Close
End Sub
But this below one does not show any records on the table. I don't know why, although they seem to be equivalent.
B4X:
Private Sub Button2_Click 
    MyList.Initialize
    Dim o() As Object = B4XTable1.BuildQuery(False)
    Dim s As String ="SELECT *, length(c1) AS ln FROM data WHERE ln = ?"
    o(0)=s
    o(1)=Array As String(0)  'even if I use Int or Object
    Dim rs As ResultSet = B4XTable1.sql1.ExecQuery2(o(0), o(1))
    Do While rs.NextRow
        Dim r() As Object = Array(rs.getint("c0"), rs.getstring("c1"),rs.GetString("c2"))
        MyList.Add(r)
    Loop
    B4XTable1.SetData(MyList)
    rs.Close
End Sub
This is interesting and promising. Maybe the problem is with the argument then.

I had noticed that this runs fine as well and gives the right result:

B4X:
    Dim rs As ResultSet = sql1.ExecQuery("select length('1234')")
    rs.Position = 0
    Log("ImplUpdateDataFromQuery, rs.GetInt2(0): " & rs.GetInt2(0))
    rs.Close

RBS
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
This is interesting and promising. Maybe the problem is with the argument then.

I had noticed that this runs fine as well and gives the right result:

B4X:
    Dim rs As ResultSet = sql1.ExecQuery("select length('1234')")
    rs.Position = 0
    Log("ImplUpdateDataFromQuery, rs.GetInt2(0): " & rs.GetInt2(0))
    rs.Close

RBS
Indeed it seems the problem was with the provided argument not being handled properly. No idea why exactly that is.
If I hard code the argument (the length we are looking for) in the SQL then all seems to fine:

B4X:
Public Sub BuildQuery (WithPageLimit As Boolean) As Object()
    
    Dim c As Int
    Dim n As Int
    Dim SortColumn As String
    Dim strFind As String
    Dim sb As StringBuilder

    sb.Initialize
    sb.Append("SELECT rowid")
    
    For Each col As B4XTableColumn In VisibleColumns
        If col.ColumnType = COLUMN_TYPE_VOID Then Continue
        sb.Append(",").Append(col.SQLID)
        If col.InternalSortMode <> "" Then
            SortColumn = " ORDER BY " & col.SQLID & " " & col.InternalSortMode
        End If
    Next
    
    sb.Append(" FROM ").Append(SQLTableName).Append(" ")
    Dim args As List
    args.Initialize
    Dim TotalCount As Int
    
    If iSearchConditions = 0 Then
        TotalCount = CountAll
        mCurrentCount = CountAll
        miCountOfPages = Ceil(mCurrentCount / mRowsPerPage)
    Else
        For Each col As B4XTableColumn In VisibleColumns
            If col.Searchable Then
                For n = 0 To arrCheckConditions(c) - 1
                    strFind = arrConditions(c, n).strSearchText
                    Log("BuildQuery, strFind: " & strFind)
                    If args.Size = 0 Then
                        sb.Append(" WHERE ")
                    Else
                        If arrConditions(c, n).bSQL_OR Then
                            'this used to be all OR
                            sb.Append(" OR ")
                        Else
                            sb.Append(" AND ")
                        End If
                    End If
                    If col.ColumnType = COLUMN_TYPE_INTEGER Or col.ColumnType = COLUMN_TYPE_DOUBLE Then
                        If arrConditions(c, n).strOperator.Length = 0 Then
                            sb.Append(col.SQLID).Append(" = ? ")
                        Else
                            If arrConditions(c, n).strOperator.StartsWith("length") Then
                                'this doesn't work for some reason gives no results
                                Select Case arrConditions(c, n).strOperator
                                    Case "length ="
                                        sb.Append("length(coalesce(").Append(col.SQLID).Append(", '')) = ").Append(strFind).Append(" ")
                                    Case "length >"
                                        sb.Append("length(coalesce(").Append(col.SQLID).Append(", '')) > ").Append(strFind).Append(" ")
                                    Case "length <"
                                        sb.Append("length(coalesce(").Append(col.SQLID).Append(", '')) < ").Append(strFind).Append(" ")
                                    Case "length <>"
                                        sb.Append("length(coalesce(").Append(col.SQLID).Append(", '')) <> ").Append(strFind).Append(" ")
                                End Select
                                'note we don't add the argument here as that is hard coded in the SQL
                            Else
                                sb.Append(col.SQLID).Append(" ").Append(arrConditions(c, n).strOperator).Append(" ? ")
                                args.Add(strFind)
                            End If
                        End If
                    Else
                        If arrConditions(c, n).strOperator.StartsWith("length") Then
                            'this doesn't work for some reason gives no results
                            Select Case arrConditions(c, n).strOperator
                                Case "length ="
                                    sb.Append("length(coalesce(").Append(col.SQLID).Append(", '')) = ").Append(strFind).Append(" ")
                                Case "length >"
                                    sb.Append("length(coalesce(").Append(col.SQLID).Append(", '')) > ").Append(strFind).Append(" ")
                                Case "length <"
                                    sb.Append("length(coalesce(").Append(col.SQLID).Append(", '')) < ").Append(strFind).Append(" ")
                                Case "length <>"
                                    sb.Append("length(coalesce(").Append(col.SQLID).Append(", '')) <> ").Append(strFind).Append(" ")
                            End Select
                            'note we don't add the argument here as that is hard coded in the SQL
                        Else
                            If arrConditions(c,n).bWildCard Then
                                If arrConditions(c,n).bCaseSensitive Then
                                    sb.Append(col.SQLID).Append(" GlOB ? ")
                                    If arrConditions(c,n).bPrefixSearch Then
                                        args.Add(strFind & "*")
                                    Else
                                        args.Add("*" & strFind & "*")
                                    End If
                                Else
                                    sb.Append(col.SQLID).Append(" LIKE ? ")
                                    If arrConditions(c,n).bPrefixSearch Then
                                        args.Add(strFind & "%")
                                    Else
                                        args.Add("%" & strFind & "%")
                                    End If
                                End If
                            Else
                                If arrConditions(c, n).bCaseSensitive Then
                                    If arrConditions(c, n).strOperator.Length = 0 Then
                                        sb.Append(col.SQLID).Append(" = ? ")
                                    Else
                                        sb.Append(col.SQLID).Append(" ").Append(arrConditions(c, n).strOperator).Append(" ? ")
                                    End If
                                    args.Add(strFind)
                                Else
                                    If arrConditions(c, n).strOperator.Length = 0 Then
                                        sb.Append("lower(").Append(col.SQLID).Append(") = ? ")
                                    Else
                                        sb.Append("lower(").Append(col.SQLID).Append(") ").Append(arrConditions(c, n).strOperator).Append(" ? ")
                                    End If
                                    args.Add(strFind.ToLowerCase)
                                End If
                            End If
                        End If
                    End If
                Next
            End If
            c = c + 1
        Next
        TotalCount = -1
    End If
    
    If SortColumn <> "" Then sb.Append(SortColumn)
    
    If WithPageLimit Then
        Dim limit As Int = mRowsPerPage
        If TotalCount < 0 Then limit = limit + 1
        sb.Append($" LIMIT ${mFirstRowIndex}, ${limit}"$) 'LIMIT offset, row_count
    End If
    
    #if B4A
    Dim aargs(args.Size) As String
    For i = 0 To args.Size - 1
        aargs(i) = args.Get(i)
    Next
    #else
    Dim aargs As List = args
    #End If
    Return Array(sb.ToString, aargs, TotalCount)
End Sub

Note we need the coalesce to cope with Null values.

RBS
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
No idea why exactly that is.

If you want the LENGTH funtion to work with a parameterized query, you need to cast the where clause to integer like this example:
B4X:
rs= SQL.ExecQuery2($"SELECT *, LENGTH(Job) AS ln FROM Jobs  WHERE CAST(ln AS INTEGER) > ?  ORDER BY Name"$, Array As String (7))  ' works
The above definitely works. You can probably add your coalesce too.
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
If you want the LENGTH funtion to work with a parameterized query, you need to cast the where clause to integer like this example:
B4X:
rs= SQL.ExecQuery2($"SELECT *, LENGTH(Job) AS ln FROM Jobs  WHERE CAST(ln AS INTEGER) > ?  ORDER BY Name"$, Array As String (7))  ' works
The above definitely works. You can probably add your coalesce too.
Yes, with the cast it works also as parameterized query. Probably best for uniformity to keep it all parameterized, so that Sub now is like this:

B4X:
Public Sub BuildQuery (WithPageLimit As Boolean) As Object()
    
    Dim c As Int
    Dim n As Int
    Dim SortColumn As String
    Dim strFind As String
    Dim sb As StringBuilder

    sb.Initialize
    sb.Append("SELECT rowid")
    
    For Each col As B4XTableColumn In VisibleColumns
        If col.ColumnType = COLUMN_TYPE_VOID Then Continue
        sb.Append(",").Append(col.SQLID)
        If col.InternalSortMode <> "" Then
            SortColumn = " ORDER BY " & col.SQLID & " " & col.InternalSortMode
        End If
    Next
    
    sb.Append(" FROM ").Append(SQLTableName).Append(" ")
    Dim args As List
    args.Initialize
    Dim TotalCount As Int
    
    If iSearchConditions = 0 Then
        TotalCount = CountAll
        mCurrentCount = CountAll
        miCountOfPages = Ceil(mCurrentCount / mRowsPerPage)
    Else
        For Each col As B4XTableColumn In VisibleColumns
            If col.Searchable Then
                For n = 0 To arrCheckConditions(c) - 1
                    strFind = arrConditions(c, n).strSearchText
                    Log("BuildQuery, strFind: " & strFind)
                    If args.Size = 0 Then
                        sb.Append(" WHERE ")
                    Else
                        If arrConditions(c, n).bSQL_OR Then
                            'this used to be all OR
                            sb.Append(" OR ")
                        Else
                            sb.Append(" AND ")
                        End If
                    End If
                    If col.ColumnType = COLUMN_TYPE_INTEGER Or col.ColumnType = COLUMN_TYPE_DOUBLE Then
                        If arrConditions(c, n).strOperator.Length = 0 Then
                            sb.Append(col.SQLID).Append(" = ? ")
                        Else
                            If arrConditions(c, n).strOperator.StartsWith("length") Then
                                Select Case arrConditions(c, n).strOperator
                                    Case "length ="
                                        sb.Append("length(coalesce(").Append(col.SQLID).Append(", '')) = cast(? as integer) ")
                                    Case "length >"
                                        sb.Append("length(coalesce(").Append(col.SQLID).Append(", '')) > cast(? as integer) ")
                                    Case "length <"
                                        sb.Append("length(coalesce(").Append(col.SQLID).Append(", '')) < cast(? as integer) ")
                                    Case "length <>"
                                        sb.Append("length(coalesce(").Append(col.SQLID).Append(", '')) <> cast(? as integer) ")
                                End Select
                                args.Add(strFind)
                            Else
                                sb.Append(col.SQLID).Append(" ").Append(arrConditions(c, n).strOperator).Append(" ? ")
                                args.Add(strFind)
                            End If
                        End If
                    Else
                        If arrConditions(c, n).strOperator.StartsWith("length") Then
                            Select Case arrConditions(c, n).strOperator
                                Case "length ="
                                    sb.Append("length(coalesce(").Append(col.SQLID).Append(", '')) = cast(? as integer) ")
                                Case "length >"
                                    sb.Append("length(coalesce(").Append(col.SQLID).Append(", '')) > cast(? as integer) ")
                                Case "length <"
                                    sb.Append("length(coalesce(").Append(col.SQLID).Append(", '')) < cast(? as integer) ")
                                Case "length <>"
                                    sb.Append("length(coalesce(").Append(col.SQLID).Append(", '')) <> cast(? as integer) ")
                            End Select
                            args.Add(strFind)
                        Else
                            If arrConditions(c,n).bWildCard Then
                                If arrConditions(c,n).bCaseSensitive Then
                                    sb.Append(col.SQLID).Append(" GlOB ? ")
                                    If arrConditions(c,n).bPrefixSearch Then
                                        args.Add(strFind & "*")
                                    Else
                                        args.Add("*" & strFind & "*")
                                    End If
                                Else
                                    sb.Append(col.SQLID).Append(" LIKE ? ")
                                    If arrConditions(c,n).bPrefixSearch Then
                                        args.Add(strFind & "%")
                                    Else
                                        args.Add("%" & strFind & "%")
                                    End If
                                End If
                            Else
                                If arrConditions(c, n).bCaseSensitive Then
                                    If arrConditions(c, n).strOperator.Length = 0 Then
                                        sb.Append(col.SQLID).Append(" = ? ")
                                    Else
                                        sb.Append(col.SQLID).Append(" ").Append(arrConditions(c, n).strOperator).Append(" ? ")
                                    End If
                                    args.Add(strFind)
                                Else
                                    If arrConditions(c, n).strOperator.Length = 0 Then
                                        sb.Append("lower(").Append(col.SQLID).Append(") = ? ")
                                    Else
                                        sb.Append("lower(").Append(col.SQLID).Append(") ").Append(arrConditions(c, n).strOperator).Append(" ? ")
                                    End If
                                    args.Add(strFind.ToLowerCase)
                                End If
                            End If
                        End If
                    End If
                Next
            End If
            c = c + 1
        Next
        TotalCount = -1
    End If
    
    If SortColumn <> "" Then sb.Append(SortColumn)
    
    If WithPageLimit Then
        Dim limit As Int = mRowsPerPage
        If TotalCount < 0 Then limit = limit + 1
        sb.Append($" LIMIT ${mFirstRowIndex}, ${limit}"$) 'LIMIT offset, row_count
    End If
    
    #if B4A
    Dim aargs(args.Size) As String
    For i = 0 To args.Size - 1
        aargs(i) = args.Get(i)
    Next
    #else
    Dim aargs As List = args
    #End If
    Return Array(sb.ToString, aargs, TotalCount)

End Sub

RBS
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
Yes, with the cast it works also as parameterized query
I have tried in recent days to follow your B4XTable threads, but due to the large amount of code you include with many variables, it is difficult to tell what they represent and what you are trying to do, especially without including a project for people to help with. I was wondering if you have thought about trying the B4XTable built in features without having to make complex changes to the library or extracting excerpts from the library. Perhaps, what you want to achieve can be done without making wholesale changes to the lbrary code. That's what I would start with and if you get stuck, many members have a good handle on B4XTable. And if members are unable to help, there is always Erel who always comes to the rescue.
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
I have tried in recent days to follow your B4XTable threads, but due to the large amount of code you include with many variables, it is difficult to tell what they represent and what you are trying to do, especially without including a project for people to help with. I was wondering if you have thought about trying the B4XTable built in features without having to make complex changes to the library or extracting excerpts from the library. Perhaps, what you want to achieve can be done without making wholesale changes to the lbrary code. That's what I would start with and if you get stuck, many members have a good handle on B4XTable. And if members are unable to help, there is always Erel who always comes to the rescue.
I am simply increasing the search options as in the example project (added to the first post from Erel regarding B4XTable) these are quite limited. I wouldn't call it wholesale changes. It mainly involves some added options to the query building Sub. I have also done away with all the search related views as I found it easier to keep this separate from the library.
Happy though to be persuaded to a different approach.
RBS
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
It mainly involves some added options to the query building Sub. I have also done away with all the search related views
Ok. That sounds fair enough. Maybe when you get it the way you want, you can share with the rest of the members a simple project that includes those added options. Who knows, Erel may see them and decides they desreve to be in a B4XTable upgrade.
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Ok. That sounds fair enough. Maybe when you get it the way you want, you can share with the rest of the members a simple project that includes those added options. Who knows, Erel may see them and decides they desreve to be in a B4XTable upgrade.
> you can share with the rest of the members a simple project that includes those added options.

Will do.
RBS
 
Upvote 0
Top