Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/Runtime/XSharp.SQLRdd/RDD/SQLRDD-Main.prg
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ partial class SQLRDD inherit Workarea
return 0
endif
try
return self:_builder:GetOrderKeyNo()
SELF:_command:CommandText := _builder:BuildRowNumberStatement(self:RecNo)
var result := SELF:_command:ExecuteScalar(SELF:_oTd:Name)
var iResult := Convert.ToUInt32(result)
return iResult
catch as Exception
return 0
end try
Expand Down
4 changes: 3 additions & 1 deletion src/Runtime/XSharp.SQLRdd/RDD/SQLRDD-Private.prg
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ partial class SQLRDD
endif
var maxTableSize := _oTd:PageSize * _oTd:BufferSize
var sizeBefore := maxTableSize - _oTd:PageSize
var lForward := nNewPageNo > _currentPageNo
var lForward := nNewPageNo >= _currentPageNo
if self:RowCount + _oTd:PageSize > maxTableSize
// We must delete rows
if lForward
Expand Down Expand Up @@ -605,6 +605,8 @@ partial class SQLRDD
SELF:_command:CommandText := _builder:BuildRowNumberStatement(nRec)
var result := SELF:_command:ExecuteScalar(SELF:_oTd:Name)
var iResult := Convert.ToInt64(result)
// shouldn't this be ToUInt32?

// determine correct page
SELF:_currentPageNo := (INT) ((iResult - 1) / SELF:_oTd:PageSize) + 1
SELF:_ClearTable()
Expand Down
186 changes: 30 additions & 156 deletions src/Runtime/XSharp.SQLRdd/Support/SqlDbTableCommandBuilder.prg
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,37 @@ internal class SqlDbTableCommandBuilder

METHOD BuildRowNumberStatement(nRec as DWORD) AS STRING
var sb := System.Text.StringBuilder{}

// current filters, scopes and conditions must be respected
// to calculate the correct pagenumber !
var currentOrder := _oRdd:CurrentOrder
var whereClauses := List<String>{}
if SELF:_oTable:HasServerFilter .and. !String.IsNullOrEmpty(_oTable:ServerFilter)
whereClauses:Add(_oTable:ServerFilter)
endif
if currentOrder != null
var sWhere := currentOrder:GetScopeClause()
if !String.IsNullOrEmpty(sWhere)
whereClauses:Add(sWhere)
endif
sWhere := currentOrder:SqlWhere
if !String.IsNullOrEmpty(sWhere)
whereClauses:Add(sWhere)
endif
endif
var sWhereClause := SELF:CombineWhereClauses(whereClauses)
sWhereClause := _connection:RaiseStringEvent(_connection, SqlRDDEventReason.WhereClause, _cTable, sWhereClause)

sb:Append(Provider:RowNumberStatement)
sb:Replace(SqlDbProvider.TableNameMacro, Provider:QuoteIdentifier(self:_oTable:RealName))

// not sure if this is a clever solution,
// but WhereMacro is already used for nRec
var cFromWhere := Provider:QuoteIdentifier(self:_oTable:RealName)
if ! String.IsNullOrEmpty(sWhereClause)
cFromWhere += SqlDbProvider.WhereClause+sWhereClause
endif
sb:Replace(SqlDbProvider.TableNameMacro, cFromWhere)

var cOrderby := Functions.List2String(_oRdd:CurrentOrder:OrderList)
if SELF:_oTable:HasRecnoColumn
if ! String.IsNullOrEmpty(cOrderby)
Expand Down Expand Up @@ -320,161 +349,6 @@ internal class SqlDbTableCommandBuilder
endif
return maxVal + 1

method GetOrderKeyNo() as DWORD
/*
SELECT COUNT(*)
FROM table
WHERE
[FILTER],
[SCOPE],
[ORDERCONDITION],
[(K1 {<|>} @K1)
OR (K1 = @K1 AND K2 {<|>} @K2)
OR ...
OR (K1 = @K1 AND ... AND xs_recno <= @xs_recno)]
*/

local nKeyNo as DWORD
local scopeWhere := null as string
local sWhereClause := null as string

var sb := System.Text.StringBuilder{}
var currentOrder := _oRdd:CurrentOrder
var recNoSql := Functions.XsValueToSqlValue(SELF:_oRdd:RecNo)

sb:Append(SqlDbProvider.SelectClause)
sb:Append("count(*)")
sb:Append(SqlDbProvider.FromClause)
sb:Append(Provider.QuoteIdentifier(_oTable:RealName))

var whereClauses := List<String>{}

if SELF:_oTable:HasServerFilter .and. !String.IsNullOrEmpty(_oTable:ServerFilter)
whereClauses:Add(_oTable:ServerFilter)
endif

if currentOrder != null
var cCompareOp := " < "
if currentOrder:Descending
cCompareOp := " > "
endif

scopeWhere := currentOrder:GetScopeClause()
if !String.IsNullOrEmpty(scopeWhere)
whereClauses:Add(scopeWhere)
endif

if !String.IsNullOrEmpty(currentOrder:SqlWhere)
whereClauses:Add(currentOrder:SqlWhere)
endif

var rawParts := currentOrder:SQLKey:Split(<CHAR>{'+'})
var keyParts := List<string>{}

foreach var cPart in rawParts
var cExpr := cPart:Trim()
if !String.IsNullOrEmpty(cExpr)
keyParts:Add(cExpr)
endif
next

if keyParts:Count = 0
return 0
endif

var sbWhere := StringBuilder{}
var sbEquals := StringBuilder{}

var sbValue := StringBuilder{}
sbValue:Append(SqlDbProvider.SelectClause)
sbValue:Append(String.Join(",", keyParts))
sbValue:Append(SqlDbProvider.FromClause)
sbValue:Append(Provider.QuoteIdentifier(_oTable:RealName))
sbValue:Append(SqlDbProvider.WhereClause)
sbValue:Append(SELF:_oTable:RecnoColumn)
sbValue:Append("=")
sbValue:Append(recNoSql)

var reader := _connection:ExecuteReader(sbValue:ToString())
try
if !reader:Read()
return 0
endif

for var nPart := 0 upto keyParts:Count - 1
var cExpr := keyParts[nPart]
var uKeyVal := reader[nPart]
var cKeyVal := Functions.XsValueToSqlValue(uKeyVal)

if nPart = 0
sbWhere:Append("(")
sbWhere:Append(cExpr)
sbWhere:Append(cCompareOp)
sbWhere:Append(cKeyVal)
sbWhere:Append(")")
else
sbWhere:Append(SqlDbProvider.OrClause)
sbWhere:Append("(")
sbWhere:Append(sbEquals:ToString())
sbWhere:Append(SqlDbProvider.AndClause)
sbWhere:Append(cExpr)
sbWhere:Append(cCompareOp)
sbWhere:Append(cKeyVal)
sbWhere:Append(")")
endif

if sbEquals:Length > 0
sbEquals:Append(SqlDbProvider.AndClause)
endif
sbEquals:Append(cExpr)
sbEquals:Append(" = ")
sbEquals:Append(cKeyVal)
next

if sbEquals:Length = 0
return 0
endif

if sbWhere:Length > 0
sbWhere:Append(SqlDbProvider.OrClause)
endif

sbWhere:Append("(")
sbWhere:Append(sbEquals:ToString())
sbWhere:Append(SqlDbProvider.AndClause)
sbWhere:Append(SELF:_oTable:RecnoColumn)
sbWhere:Append(" <= ")
sbWhere:Append(recNoSql)
sbWhere:Append(")")

sWhereClause := sbWhere:ToString()

finally
reader:Dispose()
end try

else
sWhereClause := SELF:_oTable:RecnoColumn + " <= " + recNoSql
endif

if !String.IsNullOrEmpty(sWhereClause)
whereClauses:Add(sWhereClause)
endif

sWhereClause := SELF:CombineWhereClauses(whereClauses)
sWhereClause := _connection:RaiseStringEvent(_connection, SqlRDDEventReason.WhereClause, _cTable, sWhereClause)

if !String.IsNullOrEmpty(sWhereClause)
sb:Append(SqlDbProvider.WhereClause)
sb:Append(sWhereClause)
endif

var stmt := sb:ToString()
var result := _connection:ExecuteScalar(stmt)
nKeyNo := Convert.ToUInt32(result)

return nKeyNo

method ZapStatement() as STRING
var sb := StringBuilder{}
sb:Append(Provider:DeleteAllRowsStatement)
Expand Down
Loading