mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-19 18:51:31 +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}
|
||||
{$H+}
|
||||
{ $Define USE_SQLITEDS_INTERNALS}
|
||||
{ $Define DEBUG}
|
||||
{ $Define DEBUGACTIVEBUFFER}
|
||||
|
||||
@ -55,10 +54,21 @@ type
|
||||
function Read(var Buffer; Count: Longint): Longint; override;
|
||||
function Seek(Offset: Longint; Origin: Word): Longint; override;
|
||||
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 }
|
||||
|
||||
@ -70,10 +80,12 @@ type
|
||||
FCurrentItem: PDataRecord;
|
||||
{$endif}
|
||||
FInternalActiveBuffer: PDataRecord;
|
||||
FInsertBookmark: PDataRecord;
|
||||
FBufferSize: Integer;
|
||||
FExpectedAppends: Integer;
|
||||
FExpectedDeletes: Integer;
|
||||
FExpectedUpdates: Integer;
|
||||
FOnCallback: TSqliteCallback;
|
||||
FSaveOnClose: Boolean;
|
||||
FSaveOnRefetch: Boolean;
|
||||
FAutoIncrementKey: Boolean;
|
||||
@ -98,7 +110,7 @@ type
|
||||
FAddedItems: TFPList;
|
||||
FDeletedItems: TFPList;
|
||||
FOrphanItems: TFPList;
|
||||
FSqliteReturnId: Integer;
|
||||
FReturnCode: Integer;
|
||||
FSqliteHandle: Pointer;
|
||||
FDataAllocated: Boolean;
|
||||
FRowBufferSize: Integer;
|
||||
@ -108,7 +120,7 @@ type
|
||||
FEndItem: PDataRecord;
|
||||
FCacheItem: PDataRecord;
|
||||
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;
|
||||
function InternalGetHandle: Pointer; virtual; abstract;
|
||||
procedure GetSqliteHandle;
|
||||
@ -127,6 +139,8 @@ type
|
||||
//TDataSet overrides
|
||||
function AllocRecordBuffer: PChar; override;
|
||||
function CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream; override;
|
||||
procedure DoAfterInsert; override;
|
||||
procedure DoBeforeInsert; override;
|
||||
procedure FreeRecordBuffer(var Buffer: PChar); override;
|
||||
procedure GetBookmarkData(Buffer: PChar; Data: Pointer); override;
|
||||
function GetBookmarkFlag(Buffer: PChar): TBookmarkFlag; override;
|
||||
@ -158,6 +172,8 @@ type
|
||||
public
|
||||
constructor Create(AOwner: TComponent); 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; NativeFormat: Boolean): Boolean; override;
|
||||
function Locate(const KeyFields: string; const KeyValues: Variant; Options: TLocateOptions) : boolean; override;
|
||||
@ -167,15 +183,17 @@ type
|
||||
function ApplyUpdates: Boolean;
|
||||
function CreateTable: Boolean;
|
||||
function CreateTable(const ATableName: String): Boolean;
|
||||
procedure ExecCallback(const ASql: String; UserData: Pointer = nil);
|
||||
procedure ExecSQL;
|
||||
procedure ExecSQL(const ASql:String);
|
||||
procedure ExecSQLList;
|
||||
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;const AStrList: TStrings):String;overload;
|
||||
function QuickQuery(const ASql:String;const AStrList: TStrings;FillObjects:Boolean):String;virtual;abstract;overload;
|
||||
procedure RefetchData;
|
||||
function SqliteReturnString: String; virtual;abstract;
|
||||
function ReturnString: String; virtual;abstract;
|
||||
function TableExists: Boolean;
|
||||
function TableExists(const ATableName:String):Boolean;
|
||||
function UpdatesPending: Boolean;
|
||||
@ -183,19 +201,12 @@ type
|
||||
procedure SetCurrentItem(Value:PDataRecord);
|
||||
property FCurrentItem: PDataRecord read FFCurrentItem write SetCurrentItem;
|
||||
{$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 ExpectedUpdates: Integer read FExpectedUpdates write SetExpectedUpdates;
|
||||
property ExpectedDeletes: Integer read FExpectedDeletes write SetExpectedDeletes;
|
||||
property IndexFields[Value: Integer]: TField read GetIndexFields;
|
||||
property RowsAffected: Integer read GetRowsAffected;
|
||||
property SqliteReturnId: Integer read FSqliteReturnId;
|
||||
property ReturnCode: Integer read FReturnCode;
|
||||
property SqliteHandle: Pointer read FSqliteHandle;
|
||||
property SqliteVersion: String read GetSqliteVersion;
|
||||
property SQLList:TStrings read FSqlList;
|
||||
@ -203,6 +214,7 @@ type
|
||||
property AutoIncrementKey: Boolean read FAutoIncrementKey write FAutoIncrementKey;
|
||||
property IndexFieldNames: string read FIndexFieldNames write FIndexFieldNames;
|
||||
property FileName: String read FFileName write SetFileName;
|
||||
property OnCallback: TSqliteCallback read FOnCallback write FOnCallback;
|
||||
property PrimaryKey: String read FPrimaryKey write FPrimaryKey;
|
||||
property SaveOnClose: Boolean read FSaveOnClose write FSaveOnClose;
|
||||
property SaveOnRefetch: Boolean read FSaveOnRefetch write FSaveOnRefetch;
|
||||
@ -248,11 +260,20 @@ const
|
||||
SQLITE_OK = 0;
|
||||
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;
|
||||
begin
|
||||
if APChar = nil then
|
||||
begin
|
||||
Result:='NULL';
|
||||
Result:=NullString;
|
||||
Exit;
|
||||
end;
|
||||
Result:=StrPas(APChar);
|
||||
@ -262,7 +283,7 @@ function Char2SqlStr(APChar: PChar): String;
|
||||
begin
|
||||
if APChar = nil then
|
||||
begin
|
||||
Result:='NULL';
|
||||
Result:=NullString;
|
||||
Exit;
|
||||
end;
|
||||
//todo: create custom routine to directly transform PChar -> SQL str
|
||||
@ -399,6 +420,22 @@ begin
|
||||
Result:= TDSStream.Create(PPDataRecord(ActiveBuffer)^,Field.FieldNo - 1);
|
||||
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;
|
||||
begin
|
||||
inherited Destroy;
|
||||
@ -417,6 +454,48 @@ begin
|
||||
Dispose(FEndItem);
|
||||
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);
|
||||
var
|
||||
i:Integer;
|
||||
@ -622,14 +701,13 @@ begin
|
||||
CopyCacheToItem(NewItem);
|
||||
|
||||
//insert in the linked list
|
||||
FCurrentItem^.Previous^.Next:=NewItem;
|
||||
NewItem^.Next:=FCurrentItem;
|
||||
NewItem^.Previous:=FCurrentItem^.Previous;
|
||||
FCurrentItem^.Previous:=NewItem;
|
||||
FInsertBookmark^.Previous^.Next:=NewItem;
|
||||
NewItem^.Next:=FInsertBookmark;
|
||||
NewItem^.Previous:=FInsertBookmark^.Previous;
|
||||
FInsertBookmark^.Previous:=NewItem;
|
||||
|
||||
//update the cursor in case of a insert
|
||||
if FCurrentItem <> FEndItem then
|
||||
FCurrentItem:=NewItem;
|
||||
//update the cursor
|
||||
FCurrentItem:=NewItem;
|
||||
|
||||
Inc(FRecordCount);
|
||||
if FAutoIncFieldNo <> - 1 then
|
||||
@ -1052,7 +1130,7 @@ procedure TCustomSqliteDataset.SetDetailFilter;
|
||||
end;//case
|
||||
end
|
||||
else
|
||||
Result:='NULL';
|
||||
Result:=NullString;
|
||||
end;//function
|
||||
|
||||
var
|
||||
@ -1154,7 +1232,7 @@ procedure TCustomSqliteDataset.ExecSQLList;
|
||||
begin
|
||||
if FSqliteHandle = nil then
|
||||
GetSqliteHandle;
|
||||
SqliteExec(FSqliteHandle,PChar(FSqlList.Text));
|
||||
SqliteExec(PChar(FSqlList.Text),nil,nil);
|
||||
end;
|
||||
|
||||
procedure TCustomSqliteDataset.ExecSQL;
|
||||
@ -1197,7 +1275,7 @@ begin
|
||||
if StatementsCounter = 400 then
|
||||
begin
|
||||
SqlTemp:=SqlTemp+'COMMIT;';
|
||||
FSqliteReturnId:=SqliteExec(FSqliteHandle,PChar(SqlTemp));
|
||||
FReturnCode:=SqliteExec(PChar(SqlTemp),nil,nil);
|
||||
StatementsCounter:=0;
|
||||
SqlTemp:='BEGIN;';
|
||||
end;
|
||||
@ -1223,7 +1301,7 @@ begin
|
||||
if StatementsCounter = 400 then
|
||||
begin
|
||||
SqlTemp:=SqlTemp+'COMMIT;';
|
||||
FSqliteReturnId:=SqliteExec(FSqliteHandle,PChar(SqlTemp));
|
||||
FReturnCode:=SqliteExec(PChar(SqlTemp),nil,nil);
|
||||
StatementsCounter:=0;
|
||||
SqlTemp:='BEGIN;';
|
||||
end;
|
||||
@ -1255,7 +1333,7 @@ begin
|
||||
if StatementsCounter = 400 then
|
||||
begin
|
||||
SqlTemp:=SqlTemp+'COMMIT;';
|
||||
FSqliteReturnId:=SqliteExec(FSqliteHandle,PChar(SqlTemp));
|
||||
FReturnCode:=SqliteExec(PChar(SqlTemp),nil,nil);
|
||||
StatementsCounter:=0;
|
||||
SqlTemp:='BEGIN;';
|
||||
end;
|
||||
@ -1267,8 +1345,8 @@ begin
|
||||
FAddedItems.Clear;
|
||||
FUpdatedItems.Clear;
|
||||
FDeletedItems.Clear;
|
||||
FSqliteReturnId:=SqliteExec(FSqliteHandle,PChar(SqlTemp));
|
||||
Result:= FSqliteReturnId = SQLITE_OK;
|
||||
FReturnCode:=SqliteExec(PChar(SqlTemp),nil,nil);
|
||||
Result:= FReturnCode = SQLITE_OK;
|
||||
end;
|
||||
{$ifdef DEBUG}
|
||||
writeln(' Result: ',Result);
|
||||
@ -1294,8 +1372,6 @@ begin
|
||||
{$endif}
|
||||
if (ATableName <> '') and (FieldDefs.Count > 0) then
|
||||
begin
|
||||
if FSqliteHandle = nil then
|
||||
GetSqliteHandle;
|
||||
SqlTemp:='CREATE TABLE '+ATableName+' (';
|
||||
for i := 0 to FieldDefs.Count-1 do
|
||||
begin
|
||||
@ -1338,13 +1414,56 @@ begin
|
||||
{$ifdef DEBUG}
|
||||
writeln(' SQL: ',SqlTemp);
|
||||
{$endif}
|
||||
FSqliteReturnId:=SqliteExec(FSqliteHandle,PChar(SqlTemp));
|
||||
Result:= FSqliteReturnId = SQLITE_OK;
|
||||
ExecSQL(SqlTemp);
|
||||
Result:= FReturnCode = SQLITE_OK;
|
||||
end
|
||||
else
|
||||
Result:=False;
|
||||
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;
|
||||
var
|
||||
i:Integer;
|
||||
@ -1378,14 +1497,12 @@ begin
|
||||
if not (ATableName = '') and FileExists(FFileName) then
|
||||
begin
|
||||
ExecSql('SELECT name FROM SQLITE_MASTER WHERE type = ''table'' AND name LIKE '''+ ATableName+ ''';');
|
||||
Result:=FSqliteReturnId = SQLITE_ROW;
|
||||
Result:=FReturnCode = SQLITE_ROW;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TCustomSqliteDataset.UpdatesPending: Boolean;
|
||||
begin
|
||||
//Sometimes FBeginItem is inserted in FUpdatedItems
|
||||
FUpdatedItems.Remove(FBeginItem);
|
||||
Result:= (FUpdatedItems.Count > 0) or
|
||||
(FAddedItems.Count > 0) or (FDeletedItems.Count > 0);
|
||||
end;
|
||||
|
@ -35,7 +35,7 @@ type
|
||||
|
||||
TSqlite3Dataset = class (TCustomSqliteDataset)
|
||||
private
|
||||
function SqliteExec(AHandle: Pointer; ASql:PChar):Integer;override;
|
||||
function SqliteExec(ASql:PChar; ACallback: TSqliteCdeclCallback; Data: Pointer):Integer;override;
|
||||
function InternalGetHandle: Pointer; override;
|
||||
function GetSqliteVersion: String; override;
|
||||
procedure InternalCloseHandle;override;
|
||||
@ -45,7 +45,7 @@ type
|
||||
function GetRowsAffected:Integer; override;
|
||||
public
|
||||
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;
|
||||
end;
|
||||
|
||||
@ -71,9 +71,9 @@ end;
|
||||
|
||||
{ TSqlite3Dataset }
|
||||
|
||||
function TSqlite3Dataset.SqliteExec(AHandle: Pointer; ASql: PChar): Integer;
|
||||
function TSqlite3Dataset.SqliteExec(ASql: PChar; ACallback: TSqliteCdeclCallback; Data: Pointer): Integer;
|
||||
begin
|
||||
Result:=sqlite3_exec(AHandle, ASql, nil, nil, nil);
|
||||
Result:=sqlite3_exec(FSqliteHandle, ASql, ACallback, Data, nil);
|
||||
end;
|
||||
|
||||
procedure TSqlite3Dataset.InternalCloseHandle;
|
||||
@ -86,7 +86,7 @@ end;
|
||||
|
||||
function TSqlite3Dataset.InternalGetHandle: Pointer;
|
||||
begin
|
||||
FSqliteReturnId:=sqlite3_open(PChar(FFileName),@Result);
|
||||
FReturnCode:=sqlite3_open(PChar(FFileName),@Result);
|
||||
end;
|
||||
|
||||
procedure TSqlite3Dataset.InternalInitFieldDefs;
|
||||
@ -198,10 +198,10 @@ procedure TSqlite3Dataset.ExecuteDirect(const ASql: String);
|
||||
var
|
||||
vm:Pointer;
|
||||
begin
|
||||
FSqliteReturnId:=sqlite3_prepare(FSqliteHandle,Pchar(ASql),-1,@vm,nil);
|
||||
if FSqliteReturnId <> SQLITE_OK then
|
||||
DatabaseError(SqliteReturnString,Self);
|
||||
FSqliteReturnId:=sqlite3_step(vm);
|
||||
FReturnCode:=sqlite3_prepare(FSqliteHandle,Pchar(ASql),-1,@vm,nil);
|
||||
if FReturnCode <> SQLITE_OK then
|
||||
DatabaseError(ReturnString,Self);
|
||||
FReturnCode:=sqlite3_step(vm);
|
||||
sqlite3_finalize(vm);
|
||||
end;
|
||||
|
||||
@ -216,17 +216,17 @@ begin
|
||||
sqlite3_exec(FSqliteHandle,PChar('Select Max('+Fields[FAutoIncFieldNo].FieldName+') from ' + FTableName),
|
||||
@GetAutoIncValue,@FNextAutoInc,nil);
|
||||
|
||||
FSqliteReturnId:=sqlite3_prepare(FSqliteHandle,Pchar(FSql),-1,@vm,nil);
|
||||
if FSqliteReturnId <> SQLITE_OK then
|
||||
DatabaseError(SqliteReturnString,Self);
|
||||
FReturnCode:=sqlite3_prepare(FSqliteHandle,Pchar(FSql),-1,@vm,nil);
|
||||
if FReturnCode <> SQLITE_OK then
|
||||
DatabaseError(ReturnString,Self);
|
||||
|
||||
FDataAllocated:=True;
|
||||
|
||||
TempItem:=FBeginItem;
|
||||
FRecordCount:=0;
|
||||
FRowCount:=sqlite3_column_count(vm);
|
||||
FSqliteReturnId:=sqlite3_step(vm);
|
||||
while FSqliteReturnId = SQLITE_ROW do
|
||||
FReturnCode:=sqlite3_step(vm);
|
||||
while FReturnCode = SQLITE_ROW do
|
||||
begin
|
||||
Inc(FRecordCount);
|
||||
New(TempItem^.Next);
|
||||
@ -235,7 +235,7 @@ begin
|
||||
GetMem(TempItem^.Row,FRowBufferSize);
|
||||
for Counter := 0 to FRowCount - 1 do
|
||||
TempItem^.Row[Counter]:=StrNew(sqlite3_column_text(vm,Counter));
|
||||
FSqliteReturnId:=sqlite3_step(vm);
|
||||
FReturnCode:=sqlite3_step(vm);
|
||||
end;
|
||||
sqlite3_finalize(vm);
|
||||
|
||||
@ -254,9 +254,9 @@ begin
|
||||
FBeginItem^.Row[Counter]:=nil;
|
||||
end;
|
||||
|
||||
function TSqlite3Dataset.SqliteReturnString: String;
|
||||
function TSqlite3Dataset.ReturnString: String;
|
||||
begin
|
||||
case FSqliteReturnId of
|
||||
case FReturnCode of
|
||||
SQLITE_OK : Result := 'SQLITE_OK';
|
||||
SQLITE_ERROR : Result := 'SQLITE_ERROR';
|
||||
SQLITE_INTERNAL : Result := 'SQLITE_INTERNAL';
|
||||
@ -303,30 +303,30 @@ var
|
||||
|
||||
procedure FillStrings;
|
||||
begin
|
||||
while FSqliteReturnId = SQLITE_ROW do
|
||||
while FReturnCode = SQLITE_ROW do
|
||||
begin
|
||||
AStrList.Add(StrPas(sqlite3_column_text(vm,0)));
|
||||
FSqliteReturnId:=sqlite3_step(vm);
|
||||
FReturnCode:=sqlite3_step(vm);
|
||||
end;
|
||||
end;
|
||||
procedure FillStringsAndObjects;
|
||||
begin
|
||||
while FSqliteReturnId = SQLITE_ROW do
|
||||
while FReturnCode = SQLITE_ROW do
|
||||
begin
|
||||
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;
|
||||
begin
|
||||
if FSqliteHandle = nil then
|
||||
GetSqliteHandle;
|
||||
Result:='';
|
||||
FSqliteReturnId:=sqlite3_prepare(FSqliteHandle,Pchar(ASql),-1,@vm,nil);
|
||||
if FSqliteReturnId <> SQLITE_OK then
|
||||
DatabaseError(SqliteReturnString,Self);
|
||||
FReturnCode:=sqlite3_prepare(FSqliteHandle,Pchar(ASql),-1,@vm,nil);
|
||||
if FReturnCode <> SQLITE_OK then
|
||||
DatabaseError(ReturnString,Self);
|
||||
|
||||
FSqliteReturnId:=sqlite3_step(vm);
|
||||
if (FSqliteReturnId = SQLITE_ROW) and (sqlite3_column_count(vm) > 0) then
|
||||
FReturnCode:=sqlite3_step(vm);
|
||||
if (FReturnCode = SQLITE_ROW) and (sqlite3_column_count(vm) > 0) then
|
||||
begin
|
||||
Result:=StrPas(sqlite3_column_text(vm,0));
|
||||
if AStrList <> nil then
|
||||
|
@ -35,7 +35,7 @@ type
|
||||
|
||||
TSqliteDataset = class (TCustomSqliteDataset)
|
||||
private
|
||||
function SqliteExec(AHandle: Pointer; ASql:PChar):Integer;override;
|
||||
function SqliteExec(ASql:PChar; ACallback: TSqliteCdeclCallback; Data: Pointer):Integer;override;
|
||||
function InternalGetHandle: Pointer; override;
|
||||
function GetSqliteEncoding: String;
|
||||
function GetSqliteVersion: String; override;
|
||||
@ -46,7 +46,7 @@ type
|
||||
function GetRowsAffected:Integer; override;
|
||||
public
|
||||
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;
|
||||
property SqliteEncoding: String read GetSqliteEncoding;
|
||||
end;
|
||||
@ -75,9 +75,9 @@ end;
|
||||
|
||||
{ TSqliteDataset }
|
||||
|
||||
function TSqliteDataset.SqliteExec(AHandle: Pointer; ASql: PChar): Integer;
|
||||
function TSqliteDataset.SqliteExec(ASql: PChar; ACallback: TSqliteCdeclCallback; Data: Pointer): Integer;
|
||||
begin
|
||||
Result:=sqlite_exec(AHandle, ASql, nil, nil, nil);
|
||||
Result:=sqlite_exec(FSqliteHandle, ASql, ACallback, Data, nil);
|
||||
end;
|
||||
|
||||
procedure TSqliteDataset.InternalCloseHandle;
|
||||
@ -187,8 +187,8 @@ begin
|
||||
end;
|
||||
sqlite_finalize(vm, nil);
|
||||
{
|
||||
if FSqliteReturnId <> SQLITE_ABORT then
|
||||
DatabaseError(SqliteReturnString,Self);
|
||||
if FReturnCode <> SQLITE_ABORT then
|
||||
DatabaseError(ReturnString,Self);
|
||||
}
|
||||
end;
|
||||
|
||||
@ -204,11 +204,11 @@ var
|
||||
ColumnNames,ColumnValues:PPChar;
|
||||
ColCount:Integer;
|
||||
begin
|
||||
FSqliteReturnId:=sqlite_compile(FSqliteHandle,Pchar(ASql),nil,@vm,nil);
|
||||
if FSqliteReturnId <> SQLITE_OK then
|
||||
DatabaseError(SqliteReturnString,Self);
|
||||
FReturnCode:=sqlite_compile(FSqliteHandle,Pchar(ASql),nil,@vm,nil);
|
||||
if FReturnCode <> SQLITE_OK then
|
||||
DatabaseError(ReturnString,Self);
|
||||
|
||||
FSqliteReturnId:=sqlite_step(vm,@ColCount,@ColumnValues,@ColumnNames);
|
||||
FReturnCode:=sqlite_step(vm,@ColCount,@ColumnValues,@ColumnNames);
|
||||
|
||||
sqlite_finalize(vm, nil);
|
||||
end;
|
||||
@ -225,16 +225,16 @@ begin
|
||||
sqlite_exec(FSqliteHandle,PChar('Select Max('+Fields[FAutoIncFieldNo].FieldName+') from ' + FTableName),
|
||||
@GetAutoIncValue,@FNextAutoInc,nil);
|
||||
|
||||
FSqliteReturnId:=sqlite_compile(FSqliteHandle,Pchar(FSql),nil,@vm,nil);
|
||||
if FSqliteReturnId <> SQLITE_OK then
|
||||
DatabaseError(SqliteReturnString,Self);
|
||||
FReturnCode:=sqlite_compile(FSqliteHandle,Pchar(FSql),nil,@vm,nil);
|
||||
if FReturnCode <> SQLITE_OK then
|
||||
DatabaseError(ReturnString,Self);
|
||||
|
||||
FDataAllocated:=True;
|
||||
|
||||
TempItem:=FBeginItem;
|
||||
FRecordCount:=0;
|
||||
FSqliteReturnId:=sqlite_step(vm,@FRowCount,@ColumnValues,@ColumnNames);
|
||||
while FSqliteReturnId = SQLITE_ROW do
|
||||
FReturnCode:=sqlite_step(vm,@FRowCount,@ColumnValues,@ColumnNames);
|
||||
while FReturnCode = SQLITE_ROW do
|
||||
begin
|
||||
Inc(FRecordCount);
|
||||
New(TempItem^.Next);
|
||||
@ -243,7 +243,7 @@ begin
|
||||
GetMem(TempItem^.Row,FRowBufferSize);
|
||||
for Counter := 0 to FRowCount - 1 do
|
||||
TempItem^.Row[Counter]:=StrNew(ColumnValues[Counter]);
|
||||
FSqliteReturnId:=sqlite_step(vm,@FRowCount,@ColumnValues,@ColumnNames);
|
||||
FReturnCode:=sqlite_step(vm,@FRowCount,@ColumnValues,@ColumnNames);
|
||||
end;
|
||||
sqlite_finalize(vm, nil);
|
||||
|
||||
@ -261,9 +261,9 @@ begin
|
||||
FBeginItem^.Row[Counter]:=nil;
|
||||
end;
|
||||
|
||||
function TSqliteDataset.SqliteReturnString: String;
|
||||
function TSqliteDataset.ReturnString: String;
|
||||
begin
|
||||
case FSqliteReturnId of
|
||||
case FReturnCode of
|
||||
SQLITE_OK : Result := 'SQLITE_OK';
|
||||
SQLITE_ERROR : Result := 'SQLITE_ERROR';
|
||||
SQLITE_INTERNAL : Result := 'SQLITE_INTERNAL';
|
||||
@ -295,7 +295,7 @@ begin
|
||||
else
|
||||
Result:='Unknow Return Value';
|
||||
end;
|
||||
Result:=Result+' - '+sqlite_error_string(FSqliteReturnId);
|
||||
Result:=Result+' - '+sqlite_error_string(FReturnCode);
|
||||
end;
|
||||
|
||||
function TSqliteDataset.GetSqliteEncoding: String;
|
||||
@ -316,31 +316,31 @@ var
|
||||
|
||||
procedure FillStrings;
|
||||
begin
|
||||
while FSqliteReturnId = SQLITE_ROW do
|
||||
while FReturnCode = SQLITE_ROW do
|
||||
begin
|
||||
AStrList.Add(StrPas(ColumnValues[0]));
|
||||
FSqliteReturnId:=sqlite_step(vm,@ColCount,@ColumnValues,@ColumnNames);
|
||||
FReturnCode:=sqlite_step(vm,@ColCount,@ColumnValues,@ColumnNames);
|
||||
end;
|
||||
end;
|
||||
procedure FillStringsAndObjects;
|
||||
begin
|
||||
while FSqliteReturnId = SQLITE_ROW do
|
||||
while FReturnCode = SQLITE_ROW do
|
||||
begin
|
||||
// I know, this code is really dirty!!
|
||||
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;
|
||||
begin
|
||||
if FSqliteHandle = nil then
|
||||
GetSqliteHandle;
|
||||
Result:='';
|
||||
FSqliteReturnId:=sqlite_compile(FSqliteHandle,Pchar(ASql),nil,@vm,nil);
|
||||
if FSqliteReturnId <> SQLITE_OK then
|
||||
DatabaseError(SqliteReturnString,Self);
|
||||
FReturnCode:=sqlite_compile(FSqliteHandle,Pchar(ASql),nil,@vm,nil);
|
||||
if FReturnCode <> SQLITE_OK then
|
||||
DatabaseError(ReturnString,Self);
|
||||
|
||||
FSqliteReturnId:=sqlite_step(vm,@ColCount,@ColumnValues,@ColumnNames);
|
||||
if (FSqliteReturnId = SQLITE_ROW) and (ColCount > 0) then
|
||||
FReturnCode:=sqlite_step(vm,@ColCount,@ColumnValues,@ColumnNames);
|
||||
if (FReturnCode = SQLITE_ROW) and (ColCount > 0) then
|
||||
begin
|
||||
Result:=StrPas(ColumnValues[0]);
|
||||
if AStrList <> nil then
|
||||
|
Loading…
Reference in New Issue
Block a user