mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-22 02:29:52 +02:00
* Patch from Luiz Americo Pereira Camara
- Fix the position of the record after an Insert when the cursor does not match the ActiveBuffer - Implement BookmarkValid and CompareBookmarks - Add ExecCallback function which mimetizes the original sqlite callback system git-svn-id: trunk@5985 -
This commit is contained in:
parent
7e62e2cfc1
commit
156719af03
@ -23,7 +23,6 @@ unit customsqliteds;
|
|||||||
|
|
||||||
{$Mode ObjFpc}
|
{$Mode ObjFpc}
|
||||||
{$H+}
|
{$H+}
|
||||||
{ $Define USE_SQLITEDS_INTERNALS}
|
|
||||||
{ $Define DEBUG}
|
{ $Define DEBUG}
|
||||||
{ $Define DEBUGACTIVEBUFFER}
|
{ $Define DEBUGACTIVEBUFFER}
|
||||||
|
|
||||||
@ -55,10 +54,21 @@ type
|
|||||||
function Read(var Buffer; Count: Longint): Longint; override;
|
function Read(var Buffer; Count: Longint): Longint; override;
|
||||||
function Seek(Offset: Longint; Origin: Word): Longint; override;
|
function Seek(Offset: Longint; Origin: Word): Longint; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TSqliteCallback = function (UserData:Pointer; Columns:longint; Values:PPchar; ColumnNames:PPchar):longint;cdecl;
|
|
||||||
TGetSqlStrFunction = function (APChar: PChar): String;
|
|
||||||
|
|
||||||
|
//callback types
|
||||||
|
TSqliteCdeclCallback = function (UserData:Pointer; Count:LongInt; Values:PPChar; Names:PPChar):LongInt;cdecl;
|
||||||
|
TSqliteCallback = function (UserData:Pointer; Count:LongInt; Values:PPChar; Names:PPChar):LongInt of Object;
|
||||||
|
TCallbackInfo = record
|
||||||
|
Proc: TSqliteCallback;
|
||||||
|
Data: Pointer;
|
||||||
|
end;
|
||||||
|
PCallbackInfo = ^TCallbackInfo;
|
||||||
|
|
||||||
|
TRecordState = (rsAdded,rsDeleted,rsUpdated);
|
||||||
|
TRecordStateSet = set of TRecordState;
|
||||||
|
TQueryUpdatesCallback = procedure (UserData: Pointer; Values: PPChar; ABookmark: TBookmark; RecordState: TRecordState) of Object;
|
||||||
|
|
||||||
|
TGetSqlStrFunction = function (APChar: PChar): String;
|
||||||
|
|
||||||
{ TCustomSqliteDataset }
|
{ TCustomSqliteDataset }
|
||||||
|
|
||||||
@ -70,10 +80,12 @@ type
|
|||||||
FCurrentItem: PDataRecord;
|
FCurrentItem: PDataRecord;
|
||||||
{$endif}
|
{$endif}
|
||||||
FInternalActiveBuffer: PDataRecord;
|
FInternalActiveBuffer: PDataRecord;
|
||||||
|
FInsertBookmark: PDataRecord;
|
||||||
FBufferSize: Integer;
|
FBufferSize: Integer;
|
||||||
FExpectedAppends: Integer;
|
FExpectedAppends: Integer;
|
||||||
FExpectedDeletes: Integer;
|
FExpectedDeletes: Integer;
|
||||||
FExpectedUpdates: Integer;
|
FExpectedUpdates: Integer;
|
||||||
|
FOnCallback: TSqliteCallback;
|
||||||
FSaveOnClose: Boolean;
|
FSaveOnClose: Boolean;
|
||||||
FSaveOnRefetch: Boolean;
|
FSaveOnRefetch: Boolean;
|
||||||
FAutoIncrementKey: Boolean;
|
FAutoIncrementKey: Boolean;
|
||||||
@ -98,7 +110,7 @@ type
|
|||||||
FAddedItems: TFPList;
|
FAddedItems: TFPList;
|
||||||
FDeletedItems: TFPList;
|
FDeletedItems: TFPList;
|
||||||
FOrphanItems: TFPList;
|
FOrphanItems: TFPList;
|
||||||
FSqliteReturnId: Integer;
|
FReturnCode: Integer;
|
||||||
FSqliteHandle: Pointer;
|
FSqliteHandle: Pointer;
|
||||||
FDataAllocated: Boolean;
|
FDataAllocated: Boolean;
|
||||||
FRowBufferSize: Integer;
|
FRowBufferSize: Integer;
|
||||||
@ -108,7 +120,7 @@ type
|
|||||||
FEndItem: PDataRecord;
|
FEndItem: PDataRecord;
|
||||||
FCacheItem: PDataRecord;
|
FCacheItem: PDataRecord;
|
||||||
FGetSqlStr: array of TGetSqlStrFunction;
|
FGetSqlStr: array of TGetSqlStrFunction;
|
||||||
function SqliteExec(AHandle: Pointer; Sql:PChar):Integer;virtual; abstract;
|
function SqliteExec(Sql:PChar; ACallback: TSqliteCdeclCallback; Data: Pointer):Integer;virtual; abstract;
|
||||||
procedure InternalCloseHandle;virtual;abstract;
|
procedure InternalCloseHandle;virtual;abstract;
|
||||||
function InternalGetHandle: Pointer; virtual; abstract;
|
function InternalGetHandle: Pointer; virtual; abstract;
|
||||||
procedure GetSqliteHandle;
|
procedure GetSqliteHandle;
|
||||||
@ -127,6 +139,8 @@ type
|
|||||||
//TDataSet overrides
|
//TDataSet overrides
|
||||||
function AllocRecordBuffer: PChar; override;
|
function AllocRecordBuffer: PChar; override;
|
||||||
function CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream; override;
|
function CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream; override;
|
||||||
|
procedure DoAfterInsert; override;
|
||||||
|
procedure DoBeforeInsert; override;
|
||||||
procedure FreeRecordBuffer(var Buffer: PChar); override;
|
procedure FreeRecordBuffer(var Buffer: PChar); override;
|
||||||
procedure GetBookmarkData(Buffer: PChar; Data: Pointer); override;
|
procedure GetBookmarkData(Buffer: PChar; Data: Pointer); override;
|
||||||
function GetBookmarkFlag(Buffer: PChar): TBookmarkFlag; override;
|
function GetBookmarkFlag(Buffer: PChar): TBookmarkFlag; override;
|
||||||
@ -158,6 +172,8 @@ type
|
|||||||
public
|
public
|
||||||
constructor Create(AOwner: TComponent); override;
|
constructor Create(AOwner: TComponent); override;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
function BookmarkValid(ABookmark: TBookmark): Boolean; override;
|
||||||
|
function CompareBookmarks(Bookmark1, Bookmark2: TBookmark): Longint; override;
|
||||||
function GetFieldData(Field: TField; Buffer: Pointer): Boolean; override;
|
function GetFieldData(Field: TField; Buffer: Pointer): Boolean; override;
|
||||||
function GetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean): Boolean; override;
|
function GetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean): Boolean; override;
|
||||||
function Locate(const KeyFields: string; const KeyValues: Variant; Options: TLocateOptions) : boolean; override;
|
function Locate(const KeyFields: string; const KeyValues: Variant; Options: TLocateOptions) : boolean; override;
|
||||||
@ -167,15 +183,17 @@ type
|
|||||||
function ApplyUpdates: Boolean;
|
function ApplyUpdates: Boolean;
|
||||||
function CreateTable: Boolean;
|
function CreateTable: Boolean;
|
||||||
function CreateTable(const ATableName: String): Boolean;
|
function CreateTable(const ATableName: String): Boolean;
|
||||||
|
procedure ExecCallback(const ASql: String; UserData: Pointer = nil);
|
||||||
procedure ExecSQL;
|
procedure ExecSQL;
|
||||||
procedure ExecSQL(const ASql:String);
|
procedure ExecSQL(const ASql:String);
|
||||||
procedure ExecSQLList;
|
procedure ExecSQLList;
|
||||||
procedure ExecuteDirect(const ASql: String);virtual;abstract;
|
procedure ExecuteDirect(const ASql: String);virtual;abstract;
|
||||||
|
procedure QueryUpdates(RecordStates: TRecordStateSet; Callback: TQueryUpdatesCallback; UserData: Pointer=nil);
|
||||||
function QuickQuery(const ASql:String):String;overload;
|
function QuickQuery(const ASql:String):String;overload;
|
||||||
function QuickQuery(const ASql:String;const AStrList: TStrings):String;overload;
|
function QuickQuery(const ASql:String;const AStrList: TStrings):String;overload;
|
||||||
function QuickQuery(const ASql:String;const AStrList: TStrings;FillObjects:Boolean):String;virtual;abstract;overload;
|
function QuickQuery(const ASql:String;const AStrList: TStrings;FillObjects:Boolean):String;virtual;abstract;overload;
|
||||||
procedure RefetchData;
|
procedure RefetchData;
|
||||||
function SqliteReturnString: String; virtual;abstract;
|
function ReturnString: String; virtual;abstract;
|
||||||
function TableExists: Boolean;
|
function TableExists: Boolean;
|
||||||
function TableExists(const ATableName:String):Boolean;
|
function TableExists(const ATableName:String):Boolean;
|
||||||
function UpdatesPending: Boolean;
|
function UpdatesPending: Boolean;
|
||||||
@ -183,19 +201,12 @@ type
|
|||||||
procedure SetCurrentItem(Value:PDataRecord);
|
procedure SetCurrentItem(Value:PDataRecord);
|
||||||
property FCurrentItem: PDataRecord read FFCurrentItem write SetCurrentItem;
|
property FCurrentItem: PDataRecord read FFCurrentItem write SetCurrentItem;
|
||||||
{$endif}
|
{$endif}
|
||||||
{$ifdef USE_SQLITEDS_INTERNALS}
|
|
||||||
property BeginItem: PDataRecord read FBeginItem;
|
|
||||||
property EndItem: PDataRecord read FEndItem;
|
|
||||||
property UpdatedItems: TFPList read FUpdatedItems;
|
|
||||||
property AddedItems: TFPList read FAddedItems;
|
|
||||||
property DeletedItems: TFPList read FDeletedItems;
|
|
||||||
{$endif}
|
|
||||||
property ExpectedAppends: Integer read FExpectedAppends write SetExpectedAppends;
|
property ExpectedAppends: Integer read FExpectedAppends write SetExpectedAppends;
|
||||||
property ExpectedUpdates: Integer read FExpectedUpdates write SetExpectedUpdates;
|
property ExpectedUpdates: Integer read FExpectedUpdates write SetExpectedUpdates;
|
||||||
property ExpectedDeletes: Integer read FExpectedDeletes write SetExpectedDeletes;
|
property ExpectedDeletes: Integer read FExpectedDeletes write SetExpectedDeletes;
|
||||||
property IndexFields[Value: Integer]: TField read GetIndexFields;
|
property IndexFields[Value: Integer]: TField read GetIndexFields;
|
||||||
property RowsAffected: Integer read GetRowsAffected;
|
property RowsAffected: Integer read GetRowsAffected;
|
||||||
property SqliteReturnId: Integer read FSqliteReturnId;
|
property ReturnCode: Integer read FReturnCode;
|
||||||
property SqliteHandle: Pointer read FSqliteHandle;
|
property SqliteHandle: Pointer read FSqliteHandle;
|
||||||
property SqliteVersion: String read GetSqliteVersion;
|
property SqliteVersion: String read GetSqliteVersion;
|
||||||
property SQLList:TStrings read FSqlList;
|
property SQLList:TStrings read FSqlList;
|
||||||
@ -203,6 +214,7 @@ type
|
|||||||
property AutoIncrementKey: Boolean read FAutoIncrementKey write FAutoIncrementKey;
|
property AutoIncrementKey: Boolean read FAutoIncrementKey write FAutoIncrementKey;
|
||||||
property IndexFieldNames: string read FIndexFieldNames write FIndexFieldNames;
|
property IndexFieldNames: string read FIndexFieldNames write FIndexFieldNames;
|
||||||
property FileName: String read FFileName write SetFileName;
|
property FileName: String read FFileName write SetFileName;
|
||||||
|
property OnCallback: TSqliteCallback read FOnCallback write FOnCallback;
|
||||||
property PrimaryKey: String read FPrimaryKey write FPrimaryKey;
|
property PrimaryKey: String read FPrimaryKey write FPrimaryKey;
|
||||||
property SaveOnClose: Boolean read FSaveOnClose write FSaveOnClose;
|
property SaveOnClose: Boolean read FSaveOnClose write FSaveOnClose;
|
||||||
property SaveOnRefetch: Boolean read FSaveOnRefetch write FSaveOnRefetch;
|
property SaveOnRefetch: Boolean read FSaveOnRefetch write FSaveOnRefetch;
|
||||||
@ -248,11 +260,20 @@ const
|
|||||||
SQLITE_OK = 0;
|
SQLITE_OK = 0;
|
||||||
SQLITE_ROW = 100;
|
SQLITE_ROW = 100;
|
||||||
|
|
||||||
|
NullString = 'NULL';
|
||||||
|
|
||||||
|
|
||||||
|
function CallbackDispatcher(UserData:Pointer; Count:LongInt; Values:PPchar; Names:PPchar):LongInt;cdecl;
|
||||||
|
begin
|
||||||
|
with PCallbackInfo(UserData)^ do
|
||||||
|
Result:= Proc(Data,Count,Values,Names);
|
||||||
|
end;
|
||||||
|
|
||||||
function Num2SqlStr(APChar: PChar): String;
|
function Num2SqlStr(APChar: PChar): String;
|
||||||
begin
|
begin
|
||||||
if APChar = nil then
|
if APChar = nil then
|
||||||
begin
|
begin
|
||||||
Result:='NULL';
|
Result:=NullString;
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
Result:=StrPas(APChar);
|
Result:=StrPas(APChar);
|
||||||
@ -262,7 +283,7 @@ function Char2SqlStr(APChar: PChar): String;
|
|||||||
begin
|
begin
|
||||||
if APChar = nil then
|
if APChar = nil then
|
||||||
begin
|
begin
|
||||||
Result:='NULL';
|
Result:=NullString;
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
//todo: create custom routine to directly transform PChar -> SQL str
|
//todo: create custom routine to directly transform PChar -> SQL str
|
||||||
@ -399,6 +420,22 @@ begin
|
|||||||
Result:= TDSStream.Create(PPDataRecord(ActiveBuffer)^,Field.FieldNo - 1);
|
Result:= TDSStream.Create(PPDataRecord(ActiveBuffer)^,Field.FieldNo - 1);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCustomSqliteDataset.DoAfterInsert;
|
||||||
|
begin
|
||||||
|
//an append or an insert in an empty dataset
|
||||||
|
if EOF then
|
||||||
|
FInsertBookmark:=FEndItem
|
||||||
|
else
|
||||||
|
FInsertBookmark:=FInternalActiveBuffer;
|
||||||
|
inherited DoAfterInsert;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCustomSqliteDataset.DoBeforeInsert;
|
||||||
|
begin
|
||||||
|
FInternalActiveBuffer:=PPDataRecord(ActiveBuffer)^;
|
||||||
|
inherited DoBeforeInsert;
|
||||||
|
end;
|
||||||
|
|
||||||
destructor TCustomSqliteDataset.Destroy;
|
destructor TCustomSqliteDataset.Destroy;
|
||||||
begin
|
begin
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
@ -417,6 +454,48 @@ begin
|
|||||||
Dispose(FEndItem);
|
Dispose(FEndItem);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TCustomSqliteDataset.BookmarkValid(ABookmark: TBookmark): Boolean;
|
||||||
|
var
|
||||||
|
TempItem: PDataRecord;
|
||||||
|
begin
|
||||||
|
Result:=False;
|
||||||
|
TempItem:=FBeginItem^.Next;
|
||||||
|
while TempItem <> FEndItem do
|
||||||
|
begin
|
||||||
|
if TempItem = PPDataRecord(ABookmark)^ then
|
||||||
|
begin
|
||||||
|
Result:=True;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
TempItem:=TempItem^.Next;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCustomSqliteDataset.CompareBookmarks(Bookmark1, Bookmark2: TBookmark
|
||||||
|
): Longint;
|
||||||
|
var
|
||||||
|
TempItem: PDataRecord;
|
||||||
|
begin
|
||||||
|
if PPDataRecord(Bookmark1)^ = PPDataRecord(Bookmark2)^ then
|
||||||
|
begin
|
||||||
|
Result:=0;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
//assume Bookmark1 < Bookmark2
|
||||||
|
Result:=-1;
|
||||||
|
TempItem:=PPDataRecord(Bookmark1)^^.Previous;
|
||||||
|
while TempItem <> FBeginItem do
|
||||||
|
begin
|
||||||
|
if TempItem = PPDataRecord(Bookmark2)^ then
|
||||||
|
begin
|
||||||
|
//Bookmark1 is greater than Bookmark2
|
||||||
|
Result:=1;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
TempItem:=TempItem^.Previous;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TCustomSqliteDataset.CopyCacheToItem(AItem: PDataRecord);
|
procedure TCustomSqliteDataset.CopyCacheToItem(AItem: PDataRecord);
|
||||||
var
|
var
|
||||||
i:Integer;
|
i:Integer;
|
||||||
@ -622,14 +701,13 @@ begin
|
|||||||
CopyCacheToItem(NewItem);
|
CopyCacheToItem(NewItem);
|
||||||
|
|
||||||
//insert in the linked list
|
//insert in the linked list
|
||||||
FCurrentItem^.Previous^.Next:=NewItem;
|
FInsertBookmark^.Previous^.Next:=NewItem;
|
||||||
NewItem^.Next:=FCurrentItem;
|
NewItem^.Next:=FInsertBookmark;
|
||||||
NewItem^.Previous:=FCurrentItem^.Previous;
|
NewItem^.Previous:=FInsertBookmark^.Previous;
|
||||||
FCurrentItem^.Previous:=NewItem;
|
FInsertBookmark^.Previous:=NewItem;
|
||||||
|
|
||||||
//update the cursor in case of a insert
|
//update the cursor
|
||||||
if FCurrentItem <> FEndItem then
|
FCurrentItem:=NewItem;
|
||||||
FCurrentItem:=NewItem;
|
|
||||||
|
|
||||||
Inc(FRecordCount);
|
Inc(FRecordCount);
|
||||||
if FAutoIncFieldNo <> - 1 then
|
if FAutoIncFieldNo <> - 1 then
|
||||||
@ -1052,7 +1130,7 @@ procedure TCustomSqliteDataset.SetDetailFilter;
|
|||||||
end;//case
|
end;//case
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
Result:='NULL';
|
Result:=NullString;
|
||||||
end;//function
|
end;//function
|
||||||
|
|
||||||
var
|
var
|
||||||
@ -1154,7 +1232,7 @@ procedure TCustomSqliteDataset.ExecSQLList;
|
|||||||
begin
|
begin
|
||||||
if FSqliteHandle = nil then
|
if FSqliteHandle = nil then
|
||||||
GetSqliteHandle;
|
GetSqliteHandle;
|
||||||
SqliteExec(FSqliteHandle,PChar(FSqlList.Text));
|
SqliteExec(PChar(FSqlList.Text),nil,nil);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCustomSqliteDataset.ExecSQL;
|
procedure TCustomSqliteDataset.ExecSQL;
|
||||||
@ -1197,7 +1275,7 @@ begin
|
|||||||
if StatementsCounter = 400 then
|
if StatementsCounter = 400 then
|
||||||
begin
|
begin
|
||||||
SqlTemp:=SqlTemp+'COMMIT;';
|
SqlTemp:=SqlTemp+'COMMIT;';
|
||||||
FSqliteReturnId:=SqliteExec(FSqliteHandle,PChar(SqlTemp));
|
FReturnCode:=SqliteExec(PChar(SqlTemp),nil,nil);
|
||||||
StatementsCounter:=0;
|
StatementsCounter:=0;
|
||||||
SqlTemp:='BEGIN;';
|
SqlTemp:='BEGIN;';
|
||||||
end;
|
end;
|
||||||
@ -1223,7 +1301,7 @@ begin
|
|||||||
if StatementsCounter = 400 then
|
if StatementsCounter = 400 then
|
||||||
begin
|
begin
|
||||||
SqlTemp:=SqlTemp+'COMMIT;';
|
SqlTemp:=SqlTemp+'COMMIT;';
|
||||||
FSqliteReturnId:=SqliteExec(FSqliteHandle,PChar(SqlTemp));
|
FReturnCode:=SqliteExec(PChar(SqlTemp),nil,nil);
|
||||||
StatementsCounter:=0;
|
StatementsCounter:=0;
|
||||||
SqlTemp:='BEGIN;';
|
SqlTemp:='BEGIN;';
|
||||||
end;
|
end;
|
||||||
@ -1255,7 +1333,7 @@ begin
|
|||||||
if StatementsCounter = 400 then
|
if StatementsCounter = 400 then
|
||||||
begin
|
begin
|
||||||
SqlTemp:=SqlTemp+'COMMIT;';
|
SqlTemp:=SqlTemp+'COMMIT;';
|
||||||
FSqliteReturnId:=SqliteExec(FSqliteHandle,PChar(SqlTemp));
|
FReturnCode:=SqliteExec(PChar(SqlTemp),nil,nil);
|
||||||
StatementsCounter:=0;
|
StatementsCounter:=0;
|
||||||
SqlTemp:='BEGIN;';
|
SqlTemp:='BEGIN;';
|
||||||
end;
|
end;
|
||||||
@ -1267,8 +1345,8 @@ begin
|
|||||||
FAddedItems.Clear;
|
FAddedItems.Clear;
|
||||||
FUpdatedItems.Clear;
|
FUpdatedItems.Clear;
|
||||||
FDeletedItems.Clear;
|
FDeletedItems.Clear;
|
||||||
FSqliteReturnId:=SqliteExec(FSqliteHandle,PChar(SqlTemp));
|
FReturnCode:=SqliteExec(PChar(SqlTemp),nil,nil);
|
||||||
Result:= FSqliteReturnId = SQLITE_OK;
|
Result:= FReturnCode = SQLITE_OK;
|
||||||
end;
|
end;
|
||||||
{$ifdef DEBUG}
|
{$ifdef DEBUG}
|
||||||
writeln(' Result: ',Result);
|
writeln(' Result: ',Result);
|
||||||
@ -1294,8 +1372,6 @@ begin
|
|||||||
{$endif}
|
{$endif}
|
||||||
if (ATableName <> '') and (FieldDefs.Count > 0) then
|
if (ATableName <> '') and (FieldDefs.Count > 0) then
|
||||||
begin
|
begin
|
||||||
if FSqliteHandle = nil then
|
|
||||||
GetSqliteHandle;
|
|
||||||
SqlTemp:='CREATE TABLE '+ATableName+' (';
|
SqlTemp:='CREATE TABLE '+ATableName+' (';
|
||||||
for i := 0 to FieldDefs.Count-1 do
|
for i := 0 to FieldDefs.Count-1 do
|
||||||
begin
|
begin
|
||||||
@ -1338,13 +1414,56 @@ begin
|
|||||||
{$ifdef DEBUG}
|
{$ifdef DEBUG}
|
||||||
writeln(' SQL: ',SqlTemp);
|
writeln(' SQL: ',SqlTemp);
|
||||||
{$endif}
|
{$endif}
|
||||||
FSqliteReturnId:=SqliteExec(FSqliteHandle,PChar(SqlTemp));
|
ExecSQL(SqlTemp);
|
||||||
Result:= FSqliteReturnId = SQLITE_OK;
|
Result:= FReturnCode = SQLITE_OK;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
Result:=False;
|
Result:=False;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCustomSqliteDataset.ExecCallback(const ASql: String; UserData: Pointer = nil);
|
||||||
|
var
|
||||||
|
CallbackInfo: TCallbackInfo;
|
||||||
|
begin
|
||||||
|
if not Assigned(FOnCallback) then
|
||||||
|
DatabaseError('OnCallback property not set',Self);
|
||||||
|
if FSqliteHandle = nil then
|
||||||
|
GetSqliteHandle;
|
||||||
|
CallbackInfo.Data:=UserData;
|
||||||
|
CallbackInfo.Proc:=FOnCallback;
|
||||||
|
SqliteExec(PChar(ASql),@CallbackDispatcher,@CallbackInfo);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TCustomSqliteDataset.QueryUpdates(RecordStates: TRecordStateSet; Callback: TQueryUpdatesCallback;
|
||||||
|
UserData: Pointer = nil);
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
TempItem: PDataRecord;
|
||||||
|
begin
|
||||||
|
if not Assigned(Callback) then
|
||||||
|
DatabaseError('Callback parameter not set',Self);
|
||||||
|
if rsDeleted in RecordStates then
|
||||||
|
with FDeletedItems do
|
||||||
|
for i:= 0 to Count - 1 do
|
||||||
|
Callback(UserData,PDataRecord(Items[i])^.Row,nil,rsDeleted);
|
||||||
|
if rsUpdated in RecordStates then
|
||||||
|
with FUpdatedItems do
|
||||||
|
for i:= 0 to Count - 1 do
|
||||||
|
begin
|
||||||
|
TempItem:=PDataRecord(Items[i]);
|
||||||
|
Callback(UserData,TempItem^.Row,TBookmark(@TempItem),rsUpdated);
|
||||||
|
end;
|
||||||
|
if rsAdded in RecordStates then
|
||||||
|
with FAddedItems do
|
||||||
|
for i:= 0 to Count - 1 do
|
||||||
|
begin
|
||||||
|
TempItem:=PDataRecord(Items[i]);
|
||||||
|
Callback(UserData,TempItem^.Row,TBookmark(@TempItem),rsAdded);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TCustomSqliteDataset.RefetchData;
|
procedure TCustomSqliteDataset.RefetchData;
|
||||||
var
|
var
|
||||||
i:Integer;
|
i:Integer;
|
||||||
@ -1378,14 +1497,12 @@ begin
|
|||||||
if not (ATableName = '') and FileExists(FFileName) then
|
if not (ATableName = '') and FileExists(FFileName) then
|
||||||
begin
|
begin
|
||||||
ExecSql('SELECT name FROM SQLITE_MASTER WHERE type = ''table'' AND name LIKE '''+ ATableName+ ''';');
|
ExecSql('SELECT name FROM SQLITE_MASTER WHERE type = ''table'' AND name LIKE '''+ ATableName+ ''';');
|
||||||
Result:=FSqliteReturnId = SQLITE_ROW;
|
Result:=FReturnCode = SQLITE_ROW;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCustomSqliteDataset.UpdatesPending: Boolean;
|
function TCustomSqliteDataset.UpdatesPending: Boolean;
|
||||||
begin
|
begin
|
||||||
//Sometimes FBeginItem is inserted in FUpdatedItems
|
|
||||||
FUpdatedItems.Remove(FBeginItem);
|
|
||||||
Result:= (FUpdatedItems.Count > 0) or
|
Result:= (FUpdatedItems.Count > 0) or
|
||||||
(FAddedItems.Count > 0) or (FDeletedItems.Count > 0);
|
(FAddedItems.Count > 0) or (FDeletedItems.Count > 0);
|
||||||
end;
|
end;
|
||||||
|
@ -35,7 +35,7 @@ type
|
|||||||
|
|
||||||
TSqlite3Dataset = class (TCustomSqliteDataset)
|
TSqlite3Dataset = class (TCustomSqliteDataset)
|
||||||
private
|
private
|
||||||
function SqliteExec(AHandle: Pointer; ASql:PChar):Integer;override;
|
function SqliteExec(ASql:PChar; ACallback: TSqliteCdeclCallback; Data: Pointer):Integer;override;
|
||||||
function InternalGetHandle: Pointer; override;
|
function InternalGetHandle: Pointer; override;
|
||||||
function GetSqliteVersion: String; override;
|
function GetSqliteVersion: String; override;
|
||||||
procedure InternalCloseHandle;override;
|
procedure InternalCloseHandle;override;
|
||||||
@ -45,7 +45,7 @@ type
|
|||||||
function GetRowsAffected:Integer; override;
|
function GetRowsAffected:Integer; override;
|
||||||
public
|
public
|
||||||
procedure ExecuteDirect(const ASql: String);override;
|
procedure ExecuteDirect(const ASql: String);override;
|
||||||
function SqliteReturnString: String; override;
|
function ReturnString: String; override;
|
||||||
function QuickQuery(const ASql:String;const AStrList: TStrings;FillObjects:Boolean):String;override;
|
function QuickQuery(const ASql:String;const AStrList: TStrings;FillObjects:Boolean):String;override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -71,9 +71,9 @@ end;
|
|||||||
|
|
||||||
{ TSqlite3Dataset }
|
{ TSqlite3Dataset }
|
||||||
|
|
||||||
function TSqlite3Dataset.SqliteExec(AHandle: Pointer; ASql: PChar): Integer;
|
function TSqlite3Dataset.SqliteExec(ASql: PChar; ACallback: TSqliteCdeclCallback; Data: Pointer): Integer;
|
||||||
begin
|
begin
|
||||||
Result:=sqlite3_exec(AHandle, ASql, nil, nil, nil);
|
Result:=sqlite3_exec(FSqliteHandle, ASql, ACallback, Data, nil);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSqlite3Dataset.InternalCloseHandle;
|
procedure TSqlite3Dataset.InternalCloseHandle;
|
||||||
@ -86,7 +86,7 @@ end;
|
|||||||
|
|
||||||
function TSqlite3Dataset.InternalGetHandle: Pointer;
|
function TSqlite3Dataset.InternalGetHandle: Pointer;
|
||||||
begin
|
begin
|
||||||
FSqliteReturnId:=sqlite3_open(PChar(FFileName),@Result);
|
FReturnCode:=sqlite3_open(PChar(FFileName),@Result);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSqlite3Dataset.InternalInitFieldDefs;
|
procedure TSqlite3Dataset.InternalInitFieldDefs;
|
||||||
@ -198,10 +198,10 @@ procedure TSqlite3Dataset.ExecuteDirect(const ASql: String);
|
|||||||
var
|
var
|
||||||
vm:Pointer;
|
vm:Pointer;
|
||||||
begin
|
begin
|
||||||
FSqliteReturnId:=sqlite3_prepare(FSqliteHandle,Pchar(ASql),-1,@vm,nil);
|
FReturnCode:=sqlite3_prepare(FSqliteHandle,Pchar(ASql),-1,@vm,nil);
|
||||||
if FSqliteReturnId <> SQLITE_OK then
|
if FReturnCode <> SQLITE_OK then
|
||||||
DatabaseError(SqliteReturnString,Self);
|
DatabaseError(ReturnString,Self);
|
||||||
FSqliteReturnId:=sqlite3_step(vm);
|
FReturnCode:=sqlite3_step(vm);
|
||||||
sqlite3_finalize(vm);
|
sqlite3_finalize(vm);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -216,17 +216,17 @@ begin
|
|||||||
sqlite3_exec(FSqliteHandle,PChar('Select Max('+Fields[FAutoIncFieldNo].FieldName+') from ' + FTableName),
|
sqlite3_exec(FSqliteHandle,PChar('Select Max('+Fields[FAutoIncFieldNo].FieldName+') from ' + FTableName),
|
||||||
@GetAutoIncValue,@FNextAutoInc,nil);
|
@GetAutoIncValue,@FNextAutoInc,nil);
|
||||||
|
|
||||||
FSqliteReturnId:=sqlite3_prepare(FSqliteHandle,Pchar(FSql),-1,@vm,nil);
|
FReturnCode:=sqlite3_prepare(FSqliteHandle,Pchar(FSql),-1,@vm,nil);
|
||||||
if FSqliteReturnId <> SQLITE_OK then
|
if FReturnCode <> SQLITE_OK then
|
||||||
DatabaseError(SqliteReturnString,Self);
|
DatabaseError(ReturnString,Self);
|
||||||
|
|
||||||
FDataAllocated:=True;
|
FDataAllocated:=True;
|
||||||
|
|
||||||
TempItem:=FBeginItem;
|
TempItem:=FBeginItem;
|
||||||
FRecordCount:=0;
|
FRecordCount:=0;
|
||||||
FRowCount:=sqlite3_column_count(vm);
|
FRowCount:=sqlite3_column_count(vm);
|
||||||
FSqliteReturnId:=sqlite3_step(vm);
|
FReturnCode:=sqlite3_step(vm);
|
||||||
while FSqliteReturnId = SQLITE_ROW do
|
while FReturnCode = SQLITE_ROW do
|
||||||
begin
|
begin
|
||||||
Inc(FRecordCount);
|
Inc(FRecordCount);
|
||||||
New(TempItem^.Next);
|
New(TempItem^.Next);
|
||||||
@ -235,7 +235,7 @@ begin
|
|||||||
GetMem(TempItem^.Row,FRowBufferSize);
|
GetMem(TempItem^.Row,FRowBufferSize);
|
||||||
for Counter := 0 to FRowCount - 1 do
|
for Counter := 0 to FRowCount - 1 do
|
||||||
TempItem^.Row[Counter]:=StrNew(sqlite3_column_text(vm,Counter));
|
TempItem^.Row[Counter]:=StrNew(sqlite3_column_text(vm,Counter));
|
||||||
FSqliteReturnId:=sqlite3_step(vm);
|
FReturnCode:=sqlite3_step(vm);
|
||||||
end;
|
end;
|
||||||
sqlite3_finalize(vm);
|
sqlite3_finalize(vm);
|
||||||
|
|
||||||
@ -254,9 +254,9 @@ begin
|
|||||||
FBeginItem^.Row[Counter]:=nil;
|
FBeginItem^.Row[Counter]:=nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSqlite3Dataset.SqliteReturnString: String;
|
function TSqlite3Dataset.ReturnString: String;
|
||||||
begin
|
begin
|
||||||
case FSqliteReturnId of
|
case FReturnCode of
|
||||||
SQLITE_OK : Result := 'SQLITE_OK';
|
SQLITE_OK : Result := 'SQLITE_OK';
|
||||||
SQLITE_ERROR : Result := 'SQLITE_ERROR';
|
SQLITE_ERROR : Result := 'SQLITE_ERROR';
|
||||||
SQLITE_INTERNAL : Result := 'SQLITE_INTERNAL';
|
SQLITE_INTERNAL : Result := 'SQLITE_INTERNAL';
|
||||||
@ -303,30 +303,30 @@ var
|
|||||||
|
|
||||||
procedure FillStrings;
|
procedure FillStrings;
|
||||||
begin
|
begin
|
||||||
while FSqliteReturnId = SQLITE_ROW do
|
while FReturnCode = SQLITE_ROW do
|
||||||
begin
|
begin
|
||||||
AStrList.Add(StrPas(sqlite3_column_text(vm,0)));
|
AStrList.Add(StrPas(sqlite3_column_text(vm,0)));
|
||||||
FSqliteReturnId:=sqlite3_step(vm);
|
FReturnCode:=sqlite3_step(vm);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
procedure FillStringsAndObjects;
|
procedure FillStringsAndObjects;
|
||||||
begin
|
begin
|
||||||
while FSqliteReturnId = SQLITE_ROW do
|
while FReturnCode = SQLITE_ROW do
|
||||||
begin
|
begin
|
||||||
AStrList.AddObject(StrPas(sqlite3_column_text(vm,0)),TObject(PtrInt(sqlite3_column_int(vm,1))));
|
AStrList.AddObject(StrPas(sqlite3_column_text(vm,0)),TObject(PtrInt(sqlite3_column_int(vm,1))));
|
||||||
FSqliteReturnId:=sqlite3_step(vm);
|
FReturnCode:=sqlite3_step(vm);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
begin
|
begin
|
||||||
if FSqliteHandle = nil then
|
if FSqliteHandle = nil then
|
||||||
GetSqliteHandle;
|
GetSqliteHandle;
|
||||||
Result:='';
|
Result:='';
|
||||||
FSqliteReturnId:=sqlite3_prepare(FSqliteHandle,Pchar(ASql),-1,@vm,nil);
|
FReturnCode:=sqlite3_prepare(FSqliteHandle,Pchar(ASql),-1,@vm,nil);
|
||||||
if FSqliteReturnId <> SQLITE_OK then
|
if FReturnCode <> SQLITE_OK then
|
||||||
DatabaseError(SqliteReturnString,Self);
|
DatabaseError(ReturnString,Self);
|
||||||
|
|
||||||
FSqliteReturnId:=sqlite3_step(vm);
|
FReturnCode:=sqlite3_step(vm);
|
||||||
if (FSqliteReturnId = SQLITE_ROW) and (sqlite3_column_count(vm) > 0) then
|
if (FReturnCode = SQLITE_ROW) and (sqlite3_column_count(vm) > 0) then
|
||||||
begin
|
begin
|
||||||
Result:=StrPas(sqlite3_column_text(vm,0));
|
Result:=StrPas(sqlite3_column_text(vm,0));
|
||||||
if AStrList <> nil then
|
if AStrList <> nil then
|
||||||
|
@ -35,7 +35,7 @@ type
|
|||||||
|
|
||||||
TSqliteDataset = class (TCustomSqliteDataset)
|
TSqliteDataset = class (TCustomSqliteDataset)
|
||||||
private
|
private
|
||||||
function SqliteExec(AHandle: Pointer; ASql:PChar):Integer;override;
|
function SqliteExec(ASql:PChar; ACallback: TSqliteCdeclCallback; Data: Pointer):Integer;override;
|
||||||
function InternalGetHandle: Pointer; override;
|
function InternalGetHandle: Pointer; override;
|
||||||
function GetSqliteEncoding: String;
|
function GetSqliteEncoding: String;
|
||||||
function GetSqliteVersion: String; override;
|
function GetSqliteVersion: String; override;
|
||||||
@ -46,7 +46,7 @@ type
|
|||||||
function GetRowsAffected:Integer; override;
|
function GetRowsAffected:Integer; override;
|
||||||
public
|
public
|
||||||
procedure ExecuteDirect(const ASql: String);override;
|
procedure ExecuteDirect(const ASql: String);override;
|
||||||
function SqliteReturnString: String; override;
|
function ReturnString: String; override;
|
||||||
function QuickQuery(const ASql:String;const AStrList: TStrings;FillObjects:Boolean):String;override;
|
function QuickQuery(const ASql:String;const AStrList: TStrings;FillObjects:Boolean):String;override;
|
||||||
property SqliteEncoding: String read GetSqliteEncoding;
|
property SqliteEncoding: String read GetSqliteEncoding;
|
||||||
end;
|
end;
|
||||||
@ -75,9 +75,9 @@ end;
|
|||||||
|
|
||||||
{ TSqliteDataset }
|
{ TSqliteDataset }
|
||||||
|
|
||||||
function TSqliteDataset.SqliteExec(AHandle: Pointer; ASql: PChar): Integer;
|
function TSqliteDataset.SqliteExec(ASql: PChar; ACallback: TSqliteCdeclCallback; Data: Pointer): Integer;
|
||||||
begin
|
begin
|
||||||
Result:=sqlite_exec(AHandle, ASql, nil, nil, nil);
|
Result:=sqlite_exec(FSqliteHandle, ASql, ACallback, Data, nil);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSqliteDataset.InternalCloseHandle;
|
procedure TSqliteDataset.InternalCloseHandle;
|
||||||
@ -187,8 +187,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
sqlite_finalize(vm, nil);
|
sqlite_finalize(vm, nil);
|
||||||
{
|
{
|
||||||
if FSqliteReturnId <> SQLITE_ABORT then
|
if FReturnCode <> SQLITE_ABORT then
|
||||||
DatabaseError(SqliteReturnString,Self);
|
DatabaseError(ReturnString,Self);
|
||||||
}
|
}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -204,11 +204,11 @@ var
|
|||||||
ColumnNames,ColumnValues:PPChar;
|
ColumnNames,ColumnValues:PPChar;
|
||||||
ColCount:Integer;
|
ColCount:Integer;
|
||||||
begin
|
begin
|
||||||
FSqliteReturnId:=sqlite_compile(FSqliteHandle,Pchar(ASql),nil,@vm,nil);
|
FReturnCode:=sqlite_compile(FSqliteHandle,Pchar(ASql),nil,@vm,nil);
|
||||||
if FSqliteReturnId <> SQLITE_OK then
|
if FReturnCode <> SQLITE_OK then
|
||||||
DatabaseError(SqliteReturnString,Self);
|
DatabaseError(ReturnString,Self);
|
||||||
|
|
||||||
FSqliteReturnId:=sqlite_step(vm,@ColCount,@ColumnValues,@ColumnNames);
|
FReturnCode:=sqlite_step(vm,@ColCount,@ColumnValues,@ColumnNames);
|
||||||
|
|
||||||
sqlite_finalize(vm, nil);
|
sqlite_finalize(vm, nil);
|
||||||
end;
|
end;
|
||||||
@ -225,16 +225,16 @@ begin
|
|||||||
sqlite_exec(FSqliteHandle,PChar('Select Max('+Fields[FAutoIncFieldNo].FieldName+') from ' + FTableName),
|
sqlite_exec(FSqliteHandle,PChar('Select Max('+Fields[FAutoIncFieldNo].FieldName+') from ' + FTableName),
|
||||||
@GetAutoIncValue,@FNextAutoInc,nil);
|
@GetAutoIncValue,@FNextAutoInc,nil);
|
||||||
|
|
||||||
FSqliteReturnId:=sqlite_compile(FSqliteHandle,Pchar(FSql),nil,@vm,nil);
|
FReturnCode:=sqlite_compile(FSqliteHandle,Pchar(FSql),nil,@vm,nil);
|
||||||
if FSqliteReturnId <> SQLITE_OK then
|
if FReturnCode <> SQLITE_OK then
|
||||||
DatabaseError(SqliteReturnString,Self);
|
DatabaseError(ReturnString,Self);
|
||||||
|
|
||||||
FDataAllocated:=True;
|
FDataAllocated:=True;
|
||||||
|
|
||||||
TempItem:=FBeginItem;
|
TempItem:=FBeginItem;
|
||||||
FRecordCount:=0;
|
FRecordCount:=0;
|
||||||
FSqliteReturnId:=sqlite_step(vm,@FRowCount,@ColumnValues,@ColumnNames);
|
FReturnCode:=sqlite_step(vm,@FRowCount,@ColumnValues,@ColumnNames);
|
||||||
while FSqliteReturnId = SQLITE_ROW do
|
while FReturnCode = SQLITE_ROW do
|
||||||
begin
|
begin
|
||||||
Inc(FRecordCount);
|
Inc(FRecordCount);
|
||||||
New(TempItem^.Next);
|
New(TempItem^.Next);
|
||||||
@ -243,7 +243,7 @@ begin
|
|||||||
GetMem(TempItem^.Row,FRowBufferSize);
|
GetMem(TempItem^.Row,FRowBufferSize);
|
||||||
for Counter := 0 to FRowCount - 1 do
|
for Counter := 0 to FRowCount - 1 do
|
||||||
TempItem^.Row[Counter]:=StrNew(ColumnValues[Counter]);
|
TempItem^.Row[Counter]:=StrNew(ColumnValues[Counter]);
|
||||||
FSqliteReturnId:=sqlite_step(vm,@FRowCount,@ColumnValues,@ColumnNames);
|
FReturnCode:=sqlite_step(vm,@FRowCount,@ColumnValues,@ColumnNames);
|
||||||
end;
|
end;
|
||||||
sqlite_finalize(vm, nil);
|
sqlite_finalize(vm, nil);
|
||||||
|
|
||||||
@ -261,9 +261,9 @@ begin
|
|||||||
FBeginItem^.Row[Counter]:=nil;
|
FBeginItem^.Row[Counter]:=nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSqliteDataset.SqliteReturnString: String;
|
function TSqliteDataset.ReturnString: String;
|
||||||
begin
|
begin
|
||||||
case FSqliteReturnId of
|
case FReturnCode of
|
||||||
SQLITE_OK : Result := 'SQLITE_OK';
|
SQLITE_OK : Result := 'SQLITE_OK';
|
||||||
SQLITE_ERROR : Result := 'SQLITE_ERROR';
|
SQLITE_ERROR : Result := 'SQLITE_ERROR';
|
||||||
SQLITE_INTERNAL : Result := 'SQLITE_INTERNAL';
|
SQLITE_INTERNAL : Result := 'SQLITE_INTERNAL';
|
||||||
@ -295,7 +295,7 @@ begin
|
|||||||
else
|
else
|
||||||
Result:='Unknow Return Value';
|
Result:='Unknow Return Value';
|
||||||
end;
|
end;
|
||||||
Result:=Result+' - '+sqlite_error_string(FSqliteReturnId);
|
Result:=Result+' - '+sqlite_error_string(FReturnCode);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSqliteDataset.GetSqliteEncoding: String;
|
function TSqliteDataset.GetSqliteEncoding: String;
|
||||||
@ -316,31 +316,31 @@ var
|
|||||||
|
|
||||||
procedure FillStrings;
|
procedure FillStrings;
|
||||||
begin
|
begin
|
||||||
while FSqliteReturnId = SQLITE_ROW do
|
while FReturnCode = SQLITE_ROW do
|
||||||
begin
|
begin
|
||||||
AStrList.Add(StrPas(ColumnValues[0]));
|
AStrList.Add(StrPas(ColumnValues[0]));
|
||||||
FSqliteReturnId:=sqlite_step(vm,@ColCount,@ColumnValues,@ColumnNames);
|
FReturnCode:=sqlite_step(vm,@ColCount,@ColumnValues,@ColumnNames);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
procedure FillStringsAndObjects;
|
procedure FillStringsAndObjects;
|
||||||
begin
|
begin
|
||||||
while FSqliteReturnId = SQLITE_ROW do
|
while FReturnCode = SQLITE_ROW do
|
||||||
begin
|
begin
|
||||||
// I know, this code is really dirty!!
|
// I know, this code is really dirty!!
|
||||||
AStrList.AddObject(StrPas(ColumnValues[0]),TObject(PtrInt(StrToInt(StrPas(ColumnValues[1])))));
|
AStrList.AddObject(StrPas(ColumnValues[0]),TObject(PtrInt(StrToInt(StrPas(ColumnValues[1])))));
|
||||||
FSqliteReturnId:=sqlite_step(vm,@ColCount,@ColumnValues,@ColumnNames);
|
FReturnCode:=sqlite_step(vm,@ColCount,@ColumnValues,@ColumnNames);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
begin
|
begin
|
||||||
if FSqliteHandle = nil then
|
if FSqliteHandle = nil then
|
||||||
GetSqliteHandle;
|
GetSqliteHandle;
|
||||||
Result:='';
|
Result:='';
|
||||||
FSqliteReturnId:=sqlite_compile(FSqliteHandle,Pchar(ASql),nil,@vm,nil);
|
FReturnCode:=sqlite_compile(FSqliteHandle,Pchar(ASql),nil,@vm,nil);
|
||||||
if FSqliteReturnId <> SQLITE_OK then
|
if FReturnCode <> SQLITE_OK then
|
||||||
DatabaseError(SqliteReturnString,Self);
|
DatabaseError(ReturnString,Self);
|
||||||
|
|
||||||
FSqliteReturnId:=sqlite_step(vm,@ColCount,@ColumnValues,@ColumnNames);
|
FReturnCode:=sqlite_step(vm,@ColCount,@ColumnValues,@ColumnNames);
|
||||||
if (FSqliteReturnId = SQLITE_ROW) and (ColCount > 0) then
|
if (FReturnCode = SQLITE_ROW) and (ColCount > 0) then
|
||||||
begin
|
begin
|
||||||
Result:=StrPas(ColumnValues[0]);
|
Result:=StrPas(ColumnValues[0]);
|
||||||
if AStrList <> nil then
|
if AStrList <> nil then
|
||||||
|
Loading…
Reference in New Issue
Block a user