Skip to content
Permalink
Browse files

let TSQLDBStatement.FetchAllToBinary handle ftUnknown results

(e.g. from SQLite3 computed fields)
  • Loading branch information...
Arnaud Bouchez
Arnaud Bouchez committed May 29, 2019
1 parent 58dbb39 commit 0a60edf6f6df52ecefa920499112ddb63d602ce3
Showing with 46 additions and 48 deletions.
  1. +32 −27 SynDB.pas
  2. +11 −6 SynDBVCL.pas
  3. +0 −10 SynOleDB.pas
  4. +2 −4 SynSQLite3.pas
  5. +1 −1 SynopseCommit.inc
@@ -2348,8 +2348,8 @@ TSQLDBStatement = class(TInterfacedObject, ISQLDBRows, ISQLDBStatement)
/// the prepared SQL statement, with all '?' changed into the supplied
// parameter values
property SQLWithInlinedParams: RawUTF8 read GetSQLWithInlinedParams;
/// the current row after Execute call, corresponding to Column*() methods
// - contains 0 in case of no (more) available data, or a number >=1
/// the current row after Execute/Step call, corresponding to Column*() methods
// - contains 0 before initial Step call, or a number >=1 during data retrieval
property CurrentRow: Integer read fCurrentRow;
/// the total number of data rows retrieved by this instance
// - is not reset when there is no more row of available data (Step returns
@@ -3439,7 +3439,7 @@ function ToText(Field: TSQLDBFieldType): PShortString; overload;

/// retrieve the ready-to-be displayed text of a given Database field
// type enumeration
function TSQLDBFieldTypeToString(aType: TSQLDBFieldType): string;
function TSQLDBFieldTypeToString(aType: TSQLDBFieldType): TShort16;

{$ifdef WITH_PROXY}
/// retrieve the ready-to-be displayed text of proxy commands implemented by
@@ -3467,14 +3467,11 @@ function ToText(cmd: TSQLDBProxyConnectionCommand): PShortString;
end;
{$endif}

function TSQLDBFieldTypeToString(aType: TSQLDBFieldType): string;
var PS: PShortString;
function TSQLDBFieldTypeToString(aType: TSQLDBFieldType): TShort16;
begin
if cardinal(aType)<=cardinal(high(aType)) then begin
PS := ToText(aType);
result := Ansi7ToString(@PS^[3],ord(PS^[0])-2);
end else
result := IntToStr(ord(aType));
if aType<=high(aType) then
result := TrimLeftLowerCaseToShort(ToText(aType)) else
FormatShort16('#%',[ord(aType)],result);
end;

function OracleSQLIso8601ToDate(Iso8601: RawUTF8): RawUTF8;
@@ -7126,16 +7123,16 @@ procedure TSQLDBStatement.ColumnsToBinary(W: TFileBufferWriter;
VDouble: double;
VCurrency: currency absolute VDouble;
VDateTime: TDateTime absolute VDouble;
colType: TSQLDBFieldType;
ft: TSQLDBFieldType;
begin
for F := 0 to length(ColTypes)-1 do
if not GetBitPtr(Null, F) then begin
colType := ColTypes[F];
if colType<ftInt64 then begin // ftUnknown,ftNull
colType := ColumnType(F); // per-row column type (SQLite3 only)
W.Write1(ord(colType));
ft := ColTypes[F];
if ft<ftInt64 then begin // ftUnknown,ftNull
ft := ColumnType(F); // per-row column type (SQLite3 only)
W.Write1(ord(ft));
end;
case colType of
case ft of
ftInt64:
W.WriteVarInt64(ColumnInt(F));
ftDouble: begin
@@ -7156,7 +7153,7 @@ procedure TSQLDBStatement.ColumnsToBinary(W: TFileBufferWriter;
W.Write(ColumnBlob(F));
else
raise ESQLDBException.CreateUTF8('%.ColumnsToBinary: Invalid ColumnType(%)=%',
[self,ColumnName(F),ord(colType)]);
[self,ColumnName(F),ord(ft)]);
end;
end;
end;
@@ -7167,8 +7164,9 @@ procedure TSQLDBStatement.ColumnsToBinary(W: TFileBufferWriter;
function TSQLDBStatement.FetchAllToBinary(Dest: TStream; MaxRowCount: cardinal;
DataRowPosition: PCardinalDynArray): cardinal;
var F, FMax, FieldSize, NullRowSize: integer;
StartPos: cardinal;
StartPos: Int64;
W: TFileBufferWriter;
ft: TSQLDBFieldType;
ColTypes: TSQLDBFieldTypeDynArray;
Null: TByteDynArray;
begin
@@ -7184,8 +7182,11 @@ function TSQLDBStatement.FetchAllToBinary(Dest: TStream; MaxRowCount: cardinal;
dec(FMax);
for F := 0 to FMax do begin
W.Write(ColumnName(F));
ColTypes[F] := ColumnType(F,@FieldSize);
W.Write1(ord(ColTypes[F]));
ft := ColumnType(F,@FieldSize);
if (ft=ftUnknown) and (CurrentRow=0) and Step then
ft := ColumnType(F,@FieldSize); // e.g. SQLite3 -> fetch and guess
ColTypes[F] := ft;
W.Write1(ord(ft));
W.WriteVarUInt32(FieldSize);
end;
// initialize null handling
@@ -7211,9 +7212,11 @@ function TSQLDBStatement.FetchAllToBinary(Dest: TStream; MaxRowCount: cardinal;
SetBitPtr(pointer(Null),F);
NullRowSize := (F shr 3)+1;
end;
W.WriteVarUInt32(NullRowSize);
if NullRowSize>0 then
if NullRowSize>0 then begin
W.WriteVarUInt32(NullRowSize);
W.Write(pointer(Null),NullRowSize);
end else
W.Write1(0); // = W.WriteVarUInt32(0)
// then write data values
ColumnsToBinary(W,pointer(Null),ColTypes);
inc(result);
@@ -8330,6 +8333,7 @@ procedure TSQLDBProxyStatementAbstract.IntHeaderProcess(Data: PByte; DataLen: in
procedure TSQLDBProxyStatementAbstract.IntFillDataCurrent(var Reader: PByte;
IgnoreColumnDataSize: boolean);
var F,Len: Integer;
ft: TSQLDBFieldType;
begin // format match TSQLDBStatement.FetchAllToBinary()
if fDataCurrentRowNullLen>0 then
FillCharFast(fDataCurrentRowNull[0],fDataCurrentRowNullLen,0);
@@ -8345,13 +8349,14 @@ procedure TSQLDBProxyStatementAbstract.IntFillDataCurrent(var Reader: PByte;
for F := 0 to fColumnCount-1 do
if GetBitPtr(pointer(fDataCurrentRowNull),F) then
fDataCurrentRowValues[F] := nil else begin
fDataCurrentRowColTypes[F] := fColumns[F].ColumnType;
if fDataCurrentRowColTypes[F]<ftInt64 then begin
fDataCurrentRowColTypes[F] := TSQLDBFieldType(Reader^);
ft := fColumns[F].ColumnType;
if ft<ftInt64 then begin // per-row column type (SQLite3 only)
ft := TSQLDBFieldType(Reader^);
inc(Reader);
end;
fDataCurrentRowColTypes[F] := ft;
fDataCurrentRowValues[F] := Reader;
case fDataCurrentRowColTypes[F] of
case ft of
ftInt64:
Reader := GotoNextVarInt(Reader);
ftDouble, ftCurrency, ftDate:
@@ -8364,7 +8369,7 @@ procedure TSQLDBProxyStatementAbstract.IntFillDataCurrent(var Reader: PByte;
inc(Reader,Len); // jump string/blob content
end;
else raise ESQLDBException.CreateUTF8('%.IntStep: Invalid ColumnType(%)=%',
[self,fColumns[F].ColumnName,ord(fDataCurrentRowColTypes[F])]);
[self,fColumns[F].ColumnName,ord(ft)]);
end;
end;
fDataCurrentRowValuesSize := PtrUInt(Reader)-PtrUInt(fDataCurrentRowValuesStart);
@@ -281,16 +281,21 @@ procedure TSynBinaryDataSet.InternalInitFieldDefs;
for F := 0 to fDataAccess.ColumnCount-1 do
with fDataAccess.Columns[F] do begin
case ColumnType of
SynTable.ftInt64: DBType := ftLargeint;
SynTable.ftDate: DBType := ftDateTime;
SynTable.ftInt64:
DBType := ftLargeint;
SynTable.ftDate:
DBType := ftDateTime;
SynTable.ftUTF8:
if ColumnDataSize=0 then
DBType := ftDefaultMemo else
DBType := ftWideString; // means UnicodeString for Delphi 2009+
SynTable.ftBlob: DBType := ftBlob;
SynTable.ftDouble, SynTable.ftCurrency: DBType := ftFloat;
else raise EDatabaseError.CreateFmt(
'GetFieldData ColumnType=%s',[TSQLDBFieldTypeToString(ColumnType)]);
SynTable.ftBlob:
DBType := ftBlob;
SynTable.ftDouble, SynTable.ftCurrency:
DBType := ftFloat;
else
raise EDatabaseError.CreateFmt(
'GetFieldData ColumnType=%s',[TSQLDBFieldTypeToString(ColumnType)]);
end;
FieldDefs.Add(UTF8ToString(ColumnName),DBType,ColumnDataSize);
end;
@@ -1423,16 +1423,6 @@ function TOleDBStatement.CheckParam(Param: Integer; NewType: TSQLDBFieldType;
result^.VStatus := 0;
end;

function TSQLDBFieldTypeToString(aType: TSQLDBFieldType): string;
var PS: PShortString;
begin
if cardinal(aType)<=cardinal(high(aType)) then begin
PS := GetEnumName(TypeInfo(TSQLDBFieldType),ord(aType));
result := Ansi7ToString(@PS^[3],ord(PS^[0])-2);
end else
result := IntToStr(ord(aType));
end;

function TOleDBStatement.CheckParam(Param: Integer; NewType: TSQLDBFieldType;
IO: TSQLDBParamInOutType; ArrayCount: integer): POleDBStatementParam;
begin
@@ -4145,10 +4145,9 @@ function TSQLDataBase.ExecuteNoException(const aSQL: RawUTF8): boolean;
var R: TSQLRequest;
Timer: TPrecisionTimer;
begin
if (self=nil) or (DB=0) then begin
result := false;
result := false;
if (self=nil) or (DB=0) then
exit; // avoid GPF in case of call from a static-only server
end;
Timer.Start;
Lock(aSQL); // run one statement -> we can trust IsCacheable()
try
@@ -4980,7 +4979,6 @@ procedure TSQLRequest.Execute(aDB: TSQLite3DB; const aSQL: RawUTF8);
end;

function TSQLRequest.ExecuteNoException(aDB: TSQLite3DB; const aSQL: RawUTF8): boolean;
var req: integer;
begin
result := false;
if (aDB<>0) and (aSQL<>'') then
@@ -1 +1 @@
'1.18.5232'
'1.18.5233'

0 comments on commit 0a60edf

Please sign in to comment.
You can’t perform that action at this time.