mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-01 13:11:06 +02:00
* Patch from Luiz Americo
- fixes bug #7925 - optimization for ApplyUpdates - clean InitFieldDefs implementation git-svn-id: trunk@5683 -
This commit is contained in:
parent
f3f8a76559
commit
a166a31b61
@ -57,7 +57,9 @@ type
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
TSqliteCallback = function (UserData:Pointer; Columns:longint; Values:PPchar; ColumnNames:PPchar):longint;cdecl;
|
TSqliteCallback = function (UserData:Pointer; Columns:longint; Values:PPchar; ColumnNames:PPchar):longint;cdecl;
|
||||||
|
TGetSqlStrFunction = function (APChar: PChar): String;
|
||||||
|
|
||||||
|
|
||||||
{ TCustomSqliteDataset }
|
{ TCustomSqliteDataset }
|
||||||
|
|
||||||
TCustomSqliteDataset = class(TDataSet)
|
TCustomSqliteDataset = class(TDataSet)
|
||||||
@ -104,6 +106,7 @@ type
|
|||||||
FBeginItem: PDataRecord;
|
FBeginItem: PDataRecord;
|
||||||
FEndItem: PDataRecord;
|
FEndItem: PDataRecord;
|
||||||
FCacheItem: PDataRecord;
|
FCacheItem: PDataRecord;
|
||||||
|
FGetSqlStr: array of TGetSqlStrFunction;
|
||||||
function SqliteExec(AHandle: Pointer; Sql:PChar):Integer;virtual; abstract;
|
function SqliteExec(AHandle: Pointer; Sql:PChar):Integer;virtual; abstract;
|
||||||
procedure InternalCloseHandle;virtual;abstract;
|
procedure InternalCloseHandle;virtual;abstract;
|
||||||
function InternalGetHandle: Pointer; virtual; abstract;
|
function InternalGetHandle: Pointer; virtual; abstract;
|
||||||
@ -229,6 +232,10 @@ type
|
|||||||
property OnEditError;
|
property OnEditError;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function Num2SqlStr(APChar: PChar): String;
|
||||||
|
function Char2SqlStr(APChar: PChar): String;
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
@ -237,6 +244,30 @@ uses
|
|||||||
const
|
const
|
||||||
SQLITE_OK = 0;//sqlite2.x.x and sqlite3.x.x defines this equal
|
SQLITE_OK = 0;//sqlite2.x.x and sqlite3.x.x defines this equal
|
||||||
|
|
||||||
|
function Num2SqlStr(APChar: PChar): String;
|
||||||
|
begin
|
||||||
|
if APChar = nil then
|
||||||
|
begin
|
||||||
|
Result:='NULL';
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
Result:=StrPas(APChar);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function Char2SqlStr(APChar: PChar): String;
|
||||||
|
begin
|
||||||
|
if APChar = nil then
|
||||||
|
begin
|
||||||
|
Result:='NULL';
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
//todo: create custom routine to directly transform PChar -> SQL str
|
||||||
|
Result:=StrPas(APChar);
|
||||||
|
if Pos('''',Result) > 0 then
|
||||||
|
Result:=AnsiReplaceStr(Result,'''','''''');
|
||||||
|
Result:=''''+Result+'''';
|
||||||
|
end;
|
||||||
|
|
||||||
// TDSStream
|
// TDSStream
|
||||||
|
|
||||||
constructor TDSStream.Create(const ActiveItem: PDataRecord; FieldIndex:Integer);
|
constructor TDSStream.Create(const ActiveItem: PDataRecord; FieldIndex:Integer);
|
||||||
@ -919,12 +950,17 @@ end;
|
|||||||
procedure TCustomSqliteDataset.SetDetailFilter;
|
procedure TCustomSqliteDataset.SetDetailFilter;
|
||||||
function FieldToSqlStr(AField:TField):String;
|
function FieldToSqlStr(AField:TField):String;
|
||||||
begin
|
begin
|
||||||
case AField.DataType of
|
if not AField.IsNull then
|
||||||
ftString,ftMemo: Result:='"'+AField.AsString+'"';//todo: handle " caracter properly
|
begin
|
||||||
ftDateTime,ftDate,ftTime:Str(AField.AsDateTime,Result);
|
case AField.DataType of
|
||||||
|
ftString,ftMemo: Result:='"'+AField.AsString+'"';//todo: handle " caracter properly
|
||||||
|
ftDateTime,ftDate,ftTime:Str(AField.AsDateTime,Result);
|
||||||
|
else
|
||||||
|
Result:=AField.AsString;
|
||||||
|
end;//case
|
||||||
|
end
|
||||||
else
|
else
|
||||||
Result:=AField.AsString;
|
Result:='NULL';
|
||||||
end;//case
|
|
||||||
end;//function
|
end;//function
|
||||||
|
|
||||||
var
|
var
|
||||||
@ -1034,25 +1070,9 @@ begin
|
|||||||
ExecSQL(FSql);
|
ExecSQL(FSql);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function GetSqlStr(IsString: boolean; APChar: PChar): String;
|
|
||||||
begin
|
|
||||||
if APChar = nil then
|
|
||||||
begin
|
|
||||||
Result:='NULL';
|
|
||||||
Exit;
|
|
||||||
end;
|
|
||||||
Result:=StrPas(APChar);
|
|
||||||
if IsString then
|
|
||||||
begin
|
|
||||||
if Pos('''',Result) > 0 then
|
|
||||||
Result:=AnsiReplaceStr(Result,'''','''''');
|
|
||||||
Result:=''''+Result+'''';
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TCustomSqliteDataset.ApplyUpdates:Boolean;
|
function TCustomSqliteDataset.ApplyUpdates:Boolean;
|
||||||
var
|
var
|
||||||
CounterFields,CounterItems,StatementsCounter:Integer;
|
iFields,iItems,StatementsCounter:Integer;
|
||||||
SqlTemp,WhereKeyNameEqual,ASqlLine,TemplateStr:String;
|
SqlTemp,WhereKeyNameEqual,ASqlLine,TemplateStr:String;
|
||||||
begin
|
begin
|
||||||
if not UpdatesPending then
|
if not UpdatesPending then
|
||||||
@ -1076,10 +1096,10 @@ begin
|
|||||||
// Delete Records
|
// Delete Records
|
||||||
if FDeletedItems.Count > 0 then
|
if FDeletedItems.Count > 0 then
|
||||||
TemplateStr:='DELETE FROM '+FTableName+WhereKeyNameEqual;
|
TemplateStr:='DELETE FROM '+FTableName+WhereKeyNameEqual;
|
||||||
for CounterItems:= 0 to FDeletedItems.Count - 1 do
|
for iItems:= 0 to FDeletedItems.Count - 1 do
|
||||||
begin
|
begin
|
||||||
SqlTemp:=SqlTemp+(TemplateStr+
|
SqlTemp:=SqlTemp+(TemplateStr+
|
||||||
StrPas(PDataRecord(FDeletedItems[CounterItems])^.Row[FPrimaryKeyNo])+';');
|
StrPas(PDataRecord(FDeletedItems[iItems])^.Row[FPrimaryKeyNo])+';');
|
||||||
inc(StatementsCounter);
|
inc(StatementsCounter);
|
||||||
//ApplyUpdates each 400 statements
|
//ApplyUpdates each 400 statements
|
||||||
if StatementsCounter = 400 then
|
if StatementsCounter = 400 then
|
||||||
@ -1093,18 +1113,18 @@ begin
|
|||||||
// Update changed records
|
// Update changed records
|
||||||
if FUpdatedItems.Count > 0 then
|
if FUpdatedItems.Count > 0 then
|
||||||
TemplateStr:='UPDATE '+FTableName+' SET ';
|
TemplateStr:='UPDATE '+FTableName+' SET ';
|
||||||
for CounterItems:= 0 to FUpdatedItems.Count - 1 do
|
for iItems:= 0 to FUpdatedItems.Count - 1 do
|
||||||
begin
|
begin
|
||||||
ASqlLine:=TemplateStr;
|
ASqlLine:=TemplateStr;
|
||||||
for CounterFields:= 0 to Fields.Count - 2 do
|
for iFields:= 0 to Fields.Count - 2 do
|
||||||
begin
|
begin
|
||||||
ASqlLine:=ASqlLine + (Fields[CounterFields].FieldName +' = '+
|
ASqlLine:=ASqlLine + (Fields[iFields].FieldName +' = '+
|
||||||
GetSqlStr((Fields[CounterFields].DataType in [ftString,ftMemo]),
|
FGetSqlStr[iFields](PDataRecord(FUpdatedItems[iItems])^.Row[iFields])+',');
|
||||||
PDataRecord(FUpdatedItems[CounterItems])^.Row[CounterFields])+',');
|
|
||||||
end;
|
end;
|
||||||
ASqlLine:=ASqlLine + (Fields[Fields.Count - 1].FieldName +' = '+
|
iFields:=Fields.Count - 1;
|
||||||
GetSqlStr((Fields[Fields.Count - 1].DataType in [ftString,ftMemo]),PDataRecord(FUpdatedItems[CounterItems])^.Row[Fields.Count - 1])+
|
ASqlLine:=ASqlLine + (Fields[iFields].FieldName +' = '+
|
||||||
WhereKeyNameEqual+StrPas(PDataRecord(FUpdatedItems[CounterItems])^.Row[FPrimaryKeyNo])+';');
|
FGetSqlStr[iFields](PDataRecord(FUpdatedItems[iItems])^.Row[iFields])+
|
||||||
|
WhereKeyNameEqual+StrPas(PDataRecord(FUpdatedItems[iItems])^.Row[FPrimaryKeyNo])+';');
|
||||||
SqlTemp:=SqlTemp + ASqlLine;
|
SqlTemp:=SqlTemp + ASqlLine;
|
||||||
inc(StatementsCounter);
|
inc(StatementsCounter);
|
||||||
//ApplyUpdates each 400 statements
|
//ApplyUpdates each 400 statements
|
||||||
@ -1121,24 +1141,22 @@ begin
|
|||||||
if FAddedItems.Count > 0 then
|
if FAddedItems.Count > 0 then
|
||||||
begin
|
begin
|
||||||
TemplateStr:='INSERT INTO '+FTableName+ ' (';
|
TemplateStr:='INSERT INTO '+FTableName+ ' (';
|
||||||
for CounterFields:= 0 to Fields.Count - 1 do
|
for iFields:= 0 to Fields.Count - 2 do
|
||||||
begin
|
begin
|
||||||
TemplateStr:=TemplateStr + Fields[CounterFields].FieldName;
|
TemplateStr:=TemplateStr + Fields[iFields].FieldName+',';
|
||||||
if CounterFields <> Fields.Count - 1 then
|
|
||||||
TemplateStr:=TemplateStr+',';
|
|
||||||
end;
|
end;
|
||||||
TemplateStr:=TemplateStr+') VALUES (';
|
TemplateStr:= TemplateStr+Fields[Fields.Count - 1].FieldName+') VALUES (';
|
||||||
end;
|
end;
|
||||||
for CounterItems:= 0 to FAddedItems.Count - 1 do
|
for iItems:= 0 to FAddedItems.Count - 1 do
|
||||||
begin
|
begin
|
||||||
ASqlLine:=TemplateStr;
|
ASqlLine:=TemplateStr;
|
||||||
for CounterFields:= 0 to Fields.Count - 2 do
|
for iFields:= 0 to Fields.Count - 2 do
|
||||||
begin
|
begin
|
||||||
ASqlLine:=ASqlLine + (GetSqlStr((Fields[CounterFields].DataType in [ftString,ftMemo]),
|
ASqlLine:=ASqlLine + (FGetSqlStr[iFields](PDataRecord(FAddedItems[iItems])^.Row[iFields])+',');
|
||||||
PDataRecord(FAddedItems[CounterItems])^.Row[CounterFields])+',');
|
|
||||||
end;
|
end;
|
||||||
ASqlLine:=ASqlLine + (GetSqlStr((Fields[Fields.Count -1].DataType in [ftString,ftMemo]),
|
//todo: see if i can assume iFields = Fields.Count-2 safely
|
||||||
PDataRecord(FAddedItems[CounterItems])^.Row[Fields.Count - 1])+');');
|
iFields:=Fields.Count - 1;
|
||||||
|
ASqlLine:=ASqlLine + (FGetSqlStr[iFields](PDataRecord(FAddedItems[iItems])^.Row[iFields])+');');
|
||||||
SqlTemp:=SqlTemp + ASqlLine;
|
SqlTemp:=SqlTemp + ASqlLine;
|
||||||
inc(StatementsCounter);
|
inc(StatementsCounter);
|
||||||
//ApplyUpdates each 400 statements
|
//ApplyUpdates each 400 statements
|
||||||
@ -1254,6 +1272,7 @@ begin
|
|||||||
for i := 0 to BufferCount - 1 do
|
for i := 0 to BufferCount - 1 do
|
||||||
PPDataRecord(Buffers[i])^:=FBeginItem;
|
PPDataRecord(Buffers[i])^:=FBeginItem;
|
||||||
Resync([]);
|
Resync([]);
|
||||||
|
DoAfterScroll;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCustomSqliteDataset.TableExists: Boolean;
|
function TCustomSqliteDataset.TableExists: Boolean;
|
||||||
|
@ -95,7 +95,7 @@ procedure TSqlite3Dataset.InternalInitFieldDefs;
|
|||||||
var
|
var
|
||||||
vm:Pointer;
|
vm:Pointer;
|
||||||
ColumnStr:String;
|
ColumnStr:String;
|
||||||
i,FieldSize:Integer;
|
i,ColumnCount,FieldSize:Integer;
|
||||||
AType:TFieldType;
|
AType:TFieldType;
|
||||||
begin
|
begin
|
||||||
{$ifdef DEBUG}
|
{$ifdef DEBUG}
|
||||||
@ -105,7 +105,12 @@ begin
|
|||||||
FieldDefs.Clear;
|
FieldDefs.Clear;
|
||||||
sqlite3_prepare(FSqliteHandle,PChar(FSql),-1,@vm,nil);
|
sqlite3_prepare(FSqliteHandle,PChar(FSql),-1,@vm,nil);
|
||||||
sqlite3_step(vm);
|
sqlite3_step(vm);
|
||||||
for i:= 0 to sqlite3_column_count(vm) - 1 do
|
ColumnCount:=sqlite3_column_count(vm);
|
||||||
|
//Set BufferSize
|
||||||
|
FRowBufferSize:=(SizeOf(PPChar)*ColumnCount);
|
||||||
|
//Prepare the array of pchar2sql functions
|
||||||
|
SetLength(FGetSqlStr,ColumnCount);
|
||||||
|
for i:= 0 to ColumnCount - 1 do
|
||||||
begin
|
begin
|
||||||
ColumnStr:= UpperCase(StrPas(sqlite3_column_decltype(vm,i)));
|
ColumnStr:= UpperCase(StrPas(sqlite3_column_decltype(vm,i)));
|
||||||
if (ColumnStr = 'INTEGER') or (ColumnStr = 'INT') then
|
if (ColumnStr = 'INTEGER') or (ColumnStr = 'INT') then
|
||||||
@ -170,13 +175,17 @@ begin
|
|||||||
FieldSize:=0;
|
FieldSize:=0;
|
||||||
end;
|
end;
|
||||||
FieldDefs.Add(StrPas(sqlite3_column_name(vm,i)), AType, FieldSize, False);
|
FieldDefs.Add(StrPas(sqlite3_column_name(vm,i)), AType, FieldSize, False);
|
||||||
|
//Set the pchar2sql function
|
||||||
|
if AType in [ftString,ftMemo] then
|
||||||
|
FGetSqlStr[i]:=@Char2SqlStr
|
||||||
|
else
|
||||||
|
FGetSqlStr[i]:=@Num2SqlStr;
|
||||||
{$ifdef DEBUG}
|
{$ifdef DEBUG}
|
||||||
writeln(' Field[',i,'] Name: ',sqlite3_column_name(vm,i));
|
writeln(' Field[',i,'] Name: ',sqlite3_column_name(vm,i));
|
||||||
writeln(' Field[',i,'] Type: ',sqlite3_column_decltype(vm,i));
|
writeln(' Field[',i,'] Type: ',sqlite3_column_decltype(vm,i));
|
||||||
{$endif}
|
{$endif}
|
||||||
end;
|
end;
|
||||||
sqlite3_finalize(vm);
|
sqlite3_finalize(vm);
|
||||||
FRowBufferSize:=(SizeOf(PPChar)*FieldDefs.Count);
|
|
||||||
{$ifdef DEBUG}
|
{$ifdef DEBUG}
|
||||||
writeln(' FieldDefs.Count: ',FieldDefs.Count);
|
writeln(' FieldDefs.Count: ',FieldDefs.Count);
|
||||||
{$endif}
|
{$endif}
|
||||||
|
@ -57,9 +57,6 @@ implementation
|
|||||||
uses
|
uses
|
||||||
sqlite,db;
|
sqlite,db;
|
||||||
|
|
||||||
var
|
|
||||||
DummyAutoIncFieldNo:Integer;
|
|
||||||
|
|
||||||
//function sqlite_last_statement_changes(dbhandle:Pointer):longint;cdecl;external 'sqlite' name 'sqlite_last_statement_changes';
|
//function sqlite_last_statement_changes(dbhandle:Pointer):longint;cdecl;external 'sqlite' name 'sqlite_last_statement_changes';
|
||||||
|
|
||||||
function GetAutoIncValue(NextValue: Pointer; Columns: Integer; ColumnValues: PPChar; ColumnNames: PPChar): integer; cdecl;
|
function GetAutoIncValue(NextValue: Pointer; Columns: Integer; ColumnValues: PPChar; ColumnNames: PPChar): integer; cdecl;
|
||||||
@ -77,6 +74,7 @@ begin
|
|||||||
Result:=1;
|
Result:=1;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{
|
||||||
function GetFieldDefs(TheDataset: Pointer; Columns: Integer; ColumnValues: PPChar; ColumnNames: PPChar): integer; cdecl;
|
function GetFieldDefs(TheDataset: Pointer; Columns: Integer; ColumnValues: PPChar; ColumnNames: PPChar): integer; cdecl;
|
||||||
var
|
var
|
||||||
FieldSize:Word;
|
FieldSize:Word;
|
||||||
@ -84,6 +82,8 @@ var
|
|||||||
AType:TFieldType;
|
AType:TFieldType;
|
||||||
ColumnStr:String;
|
ColumnStr:String;
|
||||||
begin
|
begin
|
||||||
|
//Prepare the array of pchar2sql functions
|
||||||
|
SetLength(TCustomSqliteDataset(TheDataset).FGetSqlStr,Columns);
|
||||||
// Sqlite is typeless (allows any type in any field)
|
// Sqlite is typeless (allows any type in any field)
|
||||||
// regardless of what is in Create Table, but returns
|
// regardless of what is in Create Table, but returns
|
||||||
// exactly what is in Create Table statement
|
// exactly what is in Create Table statement
|
||||||
@ -155,10 +155,11 @@ begin
|
|||||||
FieldSize:=0;
|
FieldSize:=0;
|
||||||
end;
|
end;
|
||||||
TDataset(TheDataset).FieldDefs.Add(StrPas(ColumnNames[i]), AType, FieldSize, False);
|
TDataset(TheDataset).FieldDefs.Add(StrPas(ColumnNames[i]), AType, FieldSize, False);
|
||||||
|
//Set
|
||||||
end;
|
end;
|
||||||
Result:=-1;
|
Result:=-1;
|
||||||
end;
|
end;
|
||||||
|
}
|
||||||
|
|
||||||
{ TSqliteDataset }
|
{ TSqliteDataset }
|
||||||
|
|
||||||
@ -179,17 +180,104 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSqliteDataset.InternalInitFieldDefs;
|
procedure TSqliteDataset.InternalInitFieldDefs;
|
||||||
|
var
|
||||||
|
ColumnCount,i:Integer;
|
||||||
|
FieldSize:Word;
|
||||||
|
AType:TFieldType;
|
||||||
|
vm:Pointer;
|
||||||
|
ColumnNames,ColumnValues:PPChar;
|
||||||
|
ColumnStr:String;
|
||||||
begin
|
begin
|
||||||
FieldDefs.Clear;
|
FieldDefs.Clear;
|
||||||
sqlite_exec(FSqliteHandle,PChar('PRAGMA empty_result_callbacks = ON;PRAGMA show_datatypes = ON;'),nil,nil,nil);
|
FAutoIncFieldNo:=-1;
|
||||||
DummyAutoIncFieldNo:=-1;
|
sqlite_compile(FSqliteHandle,PChar(FSql),nil,@vm,nil);
|
||||||
FSqliteReturnId:=sqlite_exec(FSqliteHandle,PChar(FSql),@GetFieldDefs,Self,nil);
|
sqlite_step(vm,@ColumnCount,@ColumnValues,@ColumnNames);
|
||||||
FAutoIncFieldNo:=DummyAutoIncFieldNo;
|
//Prepare the array of pchar2sql functions
|
||||||
|
SetLength(FGetSqlStr,ColumnCount);
|
||||||
|
//Set BufferSize
|
||||||
|
FRowBufferSize:=(SizeOf(PPChar)*ColumnCount);
|
||||||
|
// Sqlite is typeless (allows any type in any field)
|
||||||
|
// regardless of what is in Create Table, but returns
|
||||||
|
// exactly what is in Create Table statement
|
||||||
|
// here is a trick to get the datatype.
|
||||||
|
// If the field contains another type, may have problems
|
||||||
|
for i:= 0 to ColumnCount - 1 do
|
||||||
|
begin
|
||||||
|
ColumnStr:= UpperCase(StrPas(ColumnNames[i + ColumnCount]));
|
||||||
|
if (ColumnStr = 'INTEGER') or (ColumnStr = 'INT') then
|
||||||
|
begin
|
||||||
|
if AutoIncrementKey and
|
||||||
|
(UpperCase(StrPas(ColumnNames[i])) = UpperCase(PrimaryKey)) then
|
||||||
|
begin
|
||||||
|
AType:= ftAutoInc;
|
||||||
|
FAutoIncFieldNo:=i;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
AType:= ftInteger;
|
||||||
|
FieldSize:=SizeOf(LongInt);
|
||||||
|
end else if Pos('VARCHAR',ColumnStr) = 1 then
|
||||||
|
begin
|
||||||
|
AType:= ftString;
|
||||||
|
FieldSize:=0;
|
||||||
|
end else if Pos('BOOL',ColumnStr) = 1 then
|
||||||
|
begin
|
||||||
|
AType:= ftBoolean;
|
||||||
|
FieldSize:=SizeOf(WordBool);
|
||||||
|
end else if Pos('AUTOINC',ColumnStr) = 1 then
|
||||||
|
begin
|
||||||
|
AType:= ftAutoInc;
|
||||||
|
FieldSize:=SizeOf(LongInt);
|
||||||
|
if FAutoIncFieldNo = -1 then
|
||||||
|
FAutoIncFieldNo:= i;
|
||||||
|
end else if (Pos('FLOAT',ColumnStr)=1) or (Pos('NUMERIC',ColumnStr)=1) then
|
||||||
|
begin
|
||||||
|
AType:= ftFloat;
|
||||||
|
FieldSize:=SizeOf(Double);
|
||||||
|
end else if (ColumnStr = 'DATETIME') then
|
||||||
|
begin
|
||||||
|
AType:= ftDateTime;
|
||||||
|
FieldSize:=SizeOf(TDateTime);
|
||||||
|
end else if (ColumnStr = 'DATE') then
|
||||||
|
begin
|
||||||
|
AType:= ftDate;
|
||||||
|
FieldSize:=SizeOf(TDateTime);
|
||||||
|
end else if (ColumnStr = 'TIME') then
|
||||||
|
begin
|
||||||
|
AType:= ftTime;
|
||||||
|
FieldSize:=SizeOf(TDateTime);
|
||||||
|
end else if (ColumnStr = 'LARGEINT') then
|
||||||
|
begin
|
||||||
|
AType:= ftLargeInt;
|
||||||
|
FieldSize:=SizeOf(LargeInt);
|
||||||
|
end else if (ColumnStr = 'TEXT') then
|
||||||
|
begin
|
||||||
|
AType:= ftMemo;
|
||||||
|
FieldSize:=0;
|
||||||
|
end else if (ColumnStr = 'CURRENCY') then
|
||||||
|
begin
|
||||||
|
AType:= ftCurrency;
|
||||||
|
FieldSize:=SizeOf(Double);
|
||||||
|
end else if (ColumnStr = 'WORD') then
|
||||||
|
begin
|
||||||
|
AType:= ftWord;
|
||||||
|
FieldSize:=SizeOf(Word);
|
||||||
|
end else
|
||||||
|
begin
|
||||||
|
AType:=ftString;
|
||||||
|
FieldSize:=0;
|
||||||
|
end;
|
||||||
|
FieldDefs.Add(StrPas(ColumnNames[i]), AType, FieldSize, False);
|
||||||
|
//Set the pchar2sql function
|
||||||
|
if AType in [ftString,ftMemo] then
|
||||||
|
FGetSqlStr[i]:=@Char2SqlStr
|
||||||
|
else
|
||||||
|
FGetSqlStr[i]:=@Num2SqlStr;
|
||||||
|
end;
|
||||||
|
sqlite_finalize(vm, nil);
|
||||||
{
|
{
|
||||||
if FSqliteReturnId <> SQLITE_ABORT then
|
if FSqliteReturnId <> SQLITE_ABORT then
|
||||||
DatabaseError(SqliteReturnString,Self);
|
DatabaseError(SqliteReturnString,Self);
|
||||||
}
|
}
|
||||||
FRowBufferSize:=(SizeOf(PPChar)*FieldDefs.Count);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSqliteDataset.GetRowsAffected: Integer;
|
function TSqliteDataset.GetRowsAffected: Integer;
|
||||||
|
Loading…
Reference in New Issue
Block a user