* 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:
michael 2007-01-15 08:36:55 +00:00
parent 7e62e2cfc1
commit 156719af03
3 changed files with 209 additions and 92 deletions

View File

@ -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;

View File

@ -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

View File

@ -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