mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-12 21:10:01 +02:00
--- Merging r31837 into '.':
U packages/fcl-db/src/sqlite/customsqliteds.pas U packages/fcl-db/src/sqlite/sqlite3ds.pas --- Recording mergeinfo for merge of r31837 into '.': U . --- Merging r31838 into '.': G packages/fcl-db/src/sqlite/customsqliteds.pas --- Recording mergeinfo for merge of r31838 into '.': G . --- Merging r31839 into '.': G packages/fcl-db/src/sqlite/customsqliteds.pas --- Recording mergeinfo for merge of r31839 into '.': G . --- Merging r31840 into '.': U packages/fcl-db/src/sqlite/sqliteds.pas --- Recording mergeinfo for merge of r31840 into '.': G . --- Merging r31841 into '.': U packages/fcl-db/src/sqlite/fillds.pas U packages/fcl-db/src/sqlite/concurrencyds.pas U packages/fcl-db/src/sqlite/testds.pas U packages/fcl-db/src/sqlite/browseds.pas U packages/fcl-db/src/sqlite/createds.pas --- Recording mergeinfo for merge of r31841 into '.': G . --- Merging r31844 into '.': G packages/fcl-db/src/sqlite/customsqliteds.pas --- Recording mergeinfo for merge of r31844 into '.': G . --- Merging r31845 into '.': G packages/fcl-db/src/sqlite/fillds.pas --- Recording mergeinfo for merge of r31845 into '.': G . --- Merging r31853 into '.': G packages/fcl-db/src/sqlite/customsqliteds.pas G packages/fcl-db/src/sqlite/sqlite3ds.pas --- Recording mergeinfo for merge of r31853 into '.': G . --- Merging r31876 into '.': G packages/fcl-db/src/sqlite/customsqliteds.pas --- Recording mergeinfo for merge of r31876 into '.': G . --- Merging r31877 into '.': G packages/fcl-db/src/sqlite/customsqliteds.pas --- Recording mergeinfo for merge of r31877 into '.': G . --- Merging r32034 into '.': U packages/fcl-db/src/sqldb/sqlite/sqlite3conn.pp --- Recording mergeinfo for merge of r32034 into '.': G . # revisions: 31837,31838,31839,31840,31841,31844,31845,31853,31876,31877,32034 git-svn-id: branches/fixes_3_0@33367 -
This commit is contained in:
parent
03be126de1
commit
2bd69ff480
@ -152,16 +152,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSQLite3Cursor.checkerror(const aerror: integer);
|
procedure TSQLite3Cursor.checkerror(const aerror: integer);
|
||||||
|
|
||||||
Var
|
|
||||||
S : String;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if (aerror<>sqlite_ok) then
|
fconnection.checkerror(aerror);
|
||||||
begin
|
|
||||||
S:=strpas(sqlite3_errmsg(fhandle));
|
|
||||||
DatabaseError(S);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Procedure TSQLite3Cursor.bindparams(AParams : TParams);
|
Procedure TSQLite3Cursor.bindparams(AParams : TParams);
|
||||||
@ -810,13 +802,15 @@ end;
|
|||||||
procedure TSQLite3Connection.checkerror(const aerror: integer);
|
procedure TSQLite3Connection.checkerror(const aerror: integer);
|
||||||
|
|
||||||
Var
|
Var
|
||||||
S : String;
|
ErrMsg : String;
|
||||||
|
ErrCode : integer;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if (aerror<>sqlite_ok) then
|
if (aerror<>sqlite_ok) then
|
||||||
begin
|
begin
|
||||||
S:=strpas(sqlite3_errmsg(fhandle));
|
ErrMsg := strpas(sqlite3_errmsg(fhandle));
|
||||||
DatabaseError(S,Self);
|
ErrCode := sqlite3_extended_errcode(fhandle);
|
||||||
|
raise ESQLDatabaseError.CreateFmt(ErrMsg, [], Self, ErrCode, '');
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -4,9 +4,6 @@ program browseds;
|
|||||||
{$H+}
|
{$H+}
|
||||||
{$define DEBUGHEAP}
|
{$define DEBUGHEAP}
|
||||||
|
|
||||||
//To test the sqlite3 version replace sqliteds by sqlite3ds
|
|
||||||
// and TSqliteDataset by TSqlite3Dataset
|
|
||||||
|
|
||||||
uses
|
uses
|
||||||
{$ifdef DEBUGHEAP}
|
{$ifdef DEBUGHEAP}
|
||||||
Heaptrc,
|
Heaptrc,
|
||||||
@ -15,17 +12,16 @@ uses
|
|||||||
cmem,
|
cmem,
|
||||||
{$endif}
|
{$endif}
|
||||||
crt,
|
crt,
|
||||||
sqliteds,
|
sqlite3ds,
|
||||||
sysutils,db,inifiles;
|
sysutils, db, inifiles;
|
||||||
|
|
||||||
const
|
const
|
||||||
SQLITEDS_TESTS_INI_FILE = 'sqlitedstests.ini';
|
SQLITEDS_TESTS_INI_FILE = 'sqlitedstests.ini';
|
||||||
DEFAULT_TABLENAME = 'tabletest';
|
DEFAULT_TABLENAME = 'tabletest';
|
||||||
DEFAULT_FILENAME = 'test.db';
|
DEFAULT_FILENAME = 'test.db';
|
||||||
|
|
||||||
|
|
||||||
var
|
var
|
||||||
dsTest:TSqliteDataset;
|
dsTest: TSqlite3Dataset;
|
||||||
ini: TIniFile;
|
ini: TIniFile;
|
||||||
i:Integer;
|
i:Integer;
|
||||||
|
|
||||||
@ -57,7 +53,7 @@ begin
|
|||||||
{$ifdef DEBUGHEAP}
|
{$ifdef DEBUGHEAP}
|
||||||
SetHeapTraceOutput(ExtractFileName(ParamStr(0))+'.heap.log');
|
SetHeapTraceOutput(ExtractFileName(ParamStr(0))+'.heap.log');
|
||||||
{$endif}
|
{$endif}
|
||||||
dsTest:=TSqliteDataset.Create(nil);
|
dsTest:=TSqlite3Dataset.Create(nil);
|
||||||
with dsTest do
|
with dsTest do
|
||||||
begin
|
begin
|
||||||
//Load Database properties from a inifile
|
//Load Database properties from a inifile
|
||||||
|
@ -4,9 +4,6 @@ program concurrencyds;
|
|||||||
{$H+}
|
{$H+}
|
||||||
{$define DEBUGHEAP}
|
{$define DEBUGHEAP}
|
||||||
|
|
||||||
//To test the sqlite3 version replace sqliteds by sqlite3ds
|
|
||||||
// and TSqliteDataset by TSqlite3Dataset
|
|
||||||
|
|
||||||
uses
|
uses
|
||||||
{$ifdef DEBUGHEAP}
|
{$ifdef DEBUGHEAP}
|
||||||
Heaptrc,
|
Heaptrc,
|
||||||
@ -14,7 +11,7 @@ uses
|
|||||||
{$ifdef Linux}
|
{$ifdef Linux}
|
||||||
cmem,
|
cmem,
|
||||||
{$endif}
|
{$endif}
|
||||||
sysutils,sqliteds, inifiles;
|
sysutils,sqlite3ds, inifiles;
|
||||||
|
|
||||||
const
|
const
|
||||||
SQLITEDS_TESTS_INI_FILE = 'sqlitedstests.ini';
|
SQLITEDS_TESTS_INI_FILE = 'sqlitedstests.ini';
|
||||||
@ -37,7 +34,7 @@ const
|
|||||||
);
|
);
|
||||||
|
|
||||||
var
|
var
|
||||||
dsArray: array [0..10] of TSqliteDataset;
|
dsArray: array [0..10] of TSqlite3Dataset;
|
||||||
ini:TIniFile;
|
ini:TIniFile;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
|
|
||||||
@ -48,7 +45,7 @@ begin
|
|||||||
ini:=TIniFile.Create(SQLITEDS_TESTS_INI_FILE);
|
ini:=TIniFile.Create(SQLITEDS_TESTS_INI_FILE);
|
||||||
for i:= 0 to 10 do
|
for i:= 0 to 10 do
|
||||||
begin
|
begin
|
||||||
dsArray[i] := TSqliteDataset.Create(nil);
|
dsArray[i] := TSqlite3Dataset.Create(nil);
|
||||||
with dsArray[i] do
|
with dsArray[i] do
|
||||||
begin
|
begin
|
||||||
FileName:=ini.ReadString('testinfo','filename',DEFAULT_FILENAME);
|
FileName:=ini.ReadString('testinfo','filename',DEFAULT_FILENAME);
|
||||||
|
@ -4,9 +4,6 @@ program createds;
|
|||||||
{$H+}
|
{$H+}
|
||||||
{$define DEBUGHEAP}
|
{$define DEBUGHEAP}
|
||||||
|
|
||||||
//To test the sqlite3 version replace sqliteds by sqlite3ds
|
|
||||||
// and TSqliteDataset by TSqlite3Dataset
|
|
||||||
|
|
||||||
uses
|
uses
|
||||||
{$ifdef DEBUGHEAP}
|
{$ifdef DEBUGHEAP}
|
||||||
Heaptrc,
|
Heaptrc,
|
||||||
@ -14,7 +11,7 @@ uses
|
|||||||
{$ifdef Linux}
|
{$ifdef Linux}
|
||||||
cmem,
|
cmem,
|
||||||
{$endif}
|
{$endif}
|
||||||
sqliteds,
|
sqlite3ds,
|
||||||
sysutils,db,inifiles;
|
sysutils,db,inifiles;
|
||||||
|
|
||||||
const
|
const
|
||||||
@ -23,14 +20,14 @@ const
|
|||||||
DEFAULT_FILENAME = 'test.db';
|
DEFAULT_FILENAME = 'test.db';
|
||||||
|
|
||||||
var
|
var
|
||||||
dsTest:TSqliteDataset;
|
dsTest: TSqlite3Dataset;
|
||||||
ini: TIniFile;
|
ini: TIniFile;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
{$ifdef DEBUGHEAP}
|
{$ifdef DEBUGHEAP}
|
||||||
SetHeapTraceOutput(ExtractFileName(ParamStr(0))+'.heap.log');
|
SetHeapTraceOutput(ExtractFileName(ParamStr(0))+'.heap.log');
|
||||||
{$endif}
|
{$endif}
|
||||||
dsTest:=TSqliteDataset.Create(nil);
|
dsTest:=TSqlite3Dataset.Create(nil);
|
||||||
with dsTest do
|
with dsTest do
|
||||||
begin
|
begin
|
||||||
//Load Database properties from a inifile
|
//Load Database properties from a inifile
|
||||||
@ -58,8 +55,15 @@ begin
|
|||||||
Add('LargeInt',ftLargeint);
|
Add('LargeInt',ftLargeint);
|
||||||
Add('Currency',ftCurrency);
|
Add('Currency',ftCurrency);
|
||||||
end;
|
end;
|
||||||
CreateTable;
|
if CreateTable then
|
||||||
writeln('ReturnString after CreateTable: ',ReturnString);
|
begin
|
||||||
|
WriteLn('Table created successfully');
|
||||||
|
if not TableExists then
|
||||||
|
WriteLn('TableExists check failed with error: ', ReturnString);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
WriteLn('Error creating table');
|
||||||
|
WriteLn('ReturnString after CreateTable: ',ReturnString);
|
||||||
Destroy;
|
Destroy;
|
||||||
end;
|
end;
|
||||||
end.
|
end.
|
||||||
|
@ -117,7 +117,6 @@ type
|
|||||||
FOptions: TSqliteOptions;
|
FOptions: TSqliteOptions;
|
||||||
FSQLList: TStrings;
|
FSQLList: TStrings;
|
||||||
FStoreDefs: Boolean;
|
FStoreDefs: Boolean;
|
||||||
procedure CopyCacheToItem(AItem: PDataRecord);
|
|
||||||
function GetIndexFields(Value: Integer): TField;
|
function GetIndexFields(Value: Integer): TField;
|
||||||
function GetSQLList: TStrings;
|
function GetSQLList: TStrings;
|
||||||
procedure SetMasterIndexValue;
|
procedure SetMasterIndexValue;
|
||||||
@ -147,7 +146,7 @@ type
|
|||||||
FRecordCount: Integer;
|
FRecordCount: Integer;
|
||||||
FBeginItem: PDataRecord;
|
FBeginItem: PDataRecord;
|
||||||
FEndItem: PDataRecord;
|
FEndItem: PDataRecord;
|
||||||
FCacheItem: PDataRecord;
|
FSavedEditItem: PDataRecord;
|
||||||
FGetSqlStr: array of TGetSqlStrFunction;
|
FGetSqlStr: array of TGetSqlStrFunction;
|
||||||
FSaveOnClose: Boolean;
|
FSaveOnClose: Boolean;
|
||||||
FSaveOnRefetch: Boolean;
|
FSaveOnRefetch: Boolean;
|
||||||
@ -298,7 +297,9 @@ type
|
|||||||
|
|
||||||
function Num2SQLStr(APChar: PAnsiChar): String;
|
function Num2SQLStr(APChar: PAnsiChar): String;
|
||||||
function Char2SQLStr(APChar: PAnsiChar): String;
|
function Char2SQLStr(APChar: PAnsiChar): String;
|
||||||
|
function Memo2SQLStr(APChar: PAnsiChar): String;
|
||||||
|
function StrBufNew(p : PAnsiChar): PAnsiChar;
|
||||||
|
function StrBufNew(p : PAnsiChar; BufLen: Cardinal): PAnsiChar;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
@ -312,6 +313,29 @@ const
|
|||||||
SQLITE_DONE = 101;
|
SQLITE_DONE = 101;
|
||||||
|
|
||||||
NullString = 'NULL';
|
NullString = 'NULL';
|
||||||
|
|
||||||
|
function StrBufNew(p : PAnsiChar): PAnsiChar;
|
||||||
|
var
|
||||||
|
BufLen : Cardinal;
|
||||||
|
begin
|
||||||
|
Result := nil;
|
||||||
|
if (p = nil) or (p^ = #0) then
|
||||||
|
Exit;
|
||||||
|
BufLen := StrBufSize(p);
|
||||||
|
Result := StrAlloc(BufLen);
|
||||||
|
if Result <> nil then
|
||||||
|
Move(p^, Result^, BufLen);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function StrBufNew(p: PChar; BufLen: Cardinal): PChar;
|
||||||
|
begin
|
||||||
|
Result := nil;
|
||||||
|
if (p = nil) or (p^ = #0) then
|
||||||
|
Exit;
|
||||||
|
Result := StrAlloc(BufLen);
|
||||||
|
if Result <> nil then
|
||||||
|
Move(p^, Result^, BufLen);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function CallbackDispatcher(UserData: Pointer; Count: LongInt; Values: PPAnsiChar; Names: PPAnsiChar): LongInt; cdecl;
|
function CallbackDispatcher(UserData: Pointer; Count: LongInt; Values: PPAnsiChar; Names: PPAnsiChar): LongInt; cdecl;
|
||||||
@ -344,6 +368,26 @@ begin
|
|||||||
Result := '''' + Result + '''';
|
Result := '''' + Result + '''';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function Memo2SQLStr(APChar: PAnsiChar): String;
|
||||||
|
var
|
||||||
|
Len: Cardinal;
|
||||||
|
begin
|
||||||
|
if APChar = nil then
|
||||||
|
begin
|
||||||
|
Result := NullString;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
//todo: create custom routine to directly transform PAnsiChar -> SQL str
|
||||||
|
Len := StrBufSize(APChar) - 1;
|
||||||
|
SetLength(Result, Len);
|
||||||
|
Move(APChar^, Result[1], Len);
|
||||||
|
if Pos('''', Result) > 0 then
|
||||||
|
Result := AnsiReplaceStr(Result, '''', '''''');
|
||||||
|
Result := '''' + Result + '''';
|
||||||
|
if Pos(#0, Result) > 0 then
|
||||||
|
Result := AnsiReplaceStr(Result, #0, '''||x''00''||''');
|
||||||
|
end;
|
||||||
|
|
||||||
// TDSStream
|
// TDSStream
|
||||||
|
|
||||||
function TDSStream.GetPosition: Int64;
|
function TDSStream.GetPosition: Int64;
|
||||||
@ -368,7 +412,7 @@ begin
|
|||||||
FEditItem := EditItem;
|
FEditItem := EditItem;
|
||||||
FFieldRow := FEditItem^.Row[FFieldOffset];
|
FFieldRow := FEditItem^.Row[FFieldOffset];
|
||||||
if FFieldRow <> nil then
|
if FFieldRow <> nil then
|
||||||
FRowSize := StrLen(FFieldRow);
|
FRowSize := StrBufSize(FFieldRow) - 1;
|
||||||
//else
|
//else
|
||||||
// FRowSize := 0;
|
// FRowSize := 0;
|
||||||
end;
|
end;
|
||||||
@ -411,11 +455,11 @@ begin
|
|||||||
WriteLn(' FPosition(Before): ', FPosition);
|
WriteLn(' FPosition(Before): ', FPosition);
|
||||||
WriteLn(' FRowSize(Before): ', FRowSize);
|
WriteLn(' FRowSize(Before): ', FRowSize);
|
||||||
WriteLn(' FPosition(After): ', FPosition+Count);
|
WriteLn(' FPosition(After): ', FPosition+Count);
|
||||||
WriteLn(' FRowSize(After): ', StrLen(NewRow));
|
WriteLn(' FRowSize(After): ', StrBufSize(NewRow) -1);
|
||||||
//WriteLn(' Stream Value: ',NewRow);
|
//WriteLn(' Stream Value: ',NewRow);
|
||||||
{$endif}
|
{$endif}
|
||||||
FFieldRow := NewRow;
|
FFieldRow := NewRow;
|
||||||
FRowSize := StrLen(NewRow);
|
FRowSize := StrBufSize(NewRow) - 1;
|
||||||
Inc(FPosition, Count);
|
Inc(FPosition, Count);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -467,7 +511,7 @@ constructor TCustomSqliteDataset.Create(AOwner: TComponent);
|
|||||||
begin
|
begin
|
||||||
// setup special items
|
// setup special items
|
||||||
New(FBeginItem);
|
New(FBeginItem);
|
||||||
New(FCacheItem);
|
New(FSavedEditItem);
|
||||||
New(FEndItem);
|
New(FEndItem);
|
||||||
|
|
||||||
FBeginItem^.Previous := nil;
|
FBeginItem^.Previous := nil;
|
||||||
@ -493,10 +537,7 @@ var
|
|||||||
begin
|
begin
|
||||||
if Field.FieldNo >= 0 then
|
if Field.FieldNo >= 0 then
|
||||||
begin
|
begin
|
||||||
if Mode = bmWrite then
|
EditItem := PPDataRecord(ActiveBuffer)^;
|
||||||
EditItem := FCacheItem
|
|
||||||
else
|
|
||||||
EditItem := PPDataRecord(ActiveBuffer)^;
|
|
||||||
FieldOffset := Field.FieldNo - 1;
|
FieldOffset := Field.FieldNo - 1;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -552,7 +593,7 @@ begin
|
|||||||
FCalcFieldList.Free;
|
FCalcFieldList.Free;
|
||||||
// dispose special items
|
// dispose special items
|
||||||
Dispose(FBeginItem);
|
Dispose(FBeginItem);
|
||||||
Dispose(FCacheItem);
|
Dispose(FSavedEditItem);
|
||||||
Dispose(FEndItem);
|
Dispose(FEndItem);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -575,16 +616,21 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCustomSqliteDataset.CompareBookmarks(Bookmark1, Bookmark2: TBookmark
|
function TCustomSqliteDataset.CompareBookmarks(Bookmark1, Bookmark2: TBookmark): Longint;
|
||||||
): LongInt;
|
|
||||||
var
|
var
|
||||||
TempItem: PDataRecord;
|
TempItem: PDataRecord;
|
||||||
begin
|
begin
|
||||||
if PPDataRecord(Bookmark1)^ = PPDataRecord(Bookmark2)^ then
|
Result := 0;
|
||||||
|
if (Bookmark1 = nil) or (Bookmark2 = nil) then
|
||||||
begin
|
begin
|
||||||
Result := 0;
|
if Bookmark1 <> nil then
|
||||||
|
Result := -1
|
||||||
|
else if Bookmark2 <> nil then
|
||||||
|
Result := 1;
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
|
if PPDataRecord(Bookmark1)^ = PPDataRecord(Bookmark2)^ then
|
||||||
|
Exit;
|
||||||
//assume Bookmark1 < Bookmark2
|
//assume Bookmark1 < Bookmark2
|
||||||
Result := -1;
|
Result := -1;
|
||||||
TempItem := PPDataRecord(Bookmark1)^^.Previous;
|
TempItem := PPDataRecord(Bookmark1)^^.Previous;
|
||||||
@ -600,19 +646,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCustomSqliteDataset.CopyCacheToItem(AItem: PDataRecord);
|
|
||||||
var
|
|
||||||
i: Integer;
|
|
||||||
begin
|
|
||||||
for i := 0 to FRowCount - 1 do
|
|
||||||
begin
|
|
||||||
StrDispose(AItem^.Row[i]);
|
|
||||||
AItem^.Row[i] := FCacheItem^.Row[i];
|
|
||||||
FCacheItem^.Row[i] := nil;
|
|
||||||
end;
|
|
||||||
AItem^.BookmarkFlag := FCacheItem^.BookmarkFlag;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TCustomSqliteDataset.GetIndexFields(Value: Integer): TField;
|
function TCustomSqliteDataset.GetIndexFields(Value: Integer): TField;
|
||||||
begin
|
begin
|
||||||
Result := TField(FIndexFieldList[Value]);
|
Result := TField(FIndexFieldList[Value]);
|
||||||
@ -676,12 +709,14 @@ begin
|
|||||||
FreeItem(PDataRecord(FDeletedItems.List^[i]));
|
FreeItem(PDataRecord(FDeletedItems.List^[i]));
|
||||||
|
|
||||||
//Dispose FBeginItem.Row
|
//Dispose FBeginItem.Row
|
||||||
|
for i := 0 to FRowCount - 1 do
|
||||||
|
StrDispose(FBeginItem^.Row[i]);
|
||||||
FreeMem(FBeginItem^.Row, FRowBufferSize);
|
FreeMem(FBeginItem^.Row, FRowBufferSize);
|
||||||
|
|
||||||
//Dispose cache item row
|
//Dispose edit item row
|
||||||
for i:= 0 to FRowCount - 1 do
|
for i := 0 to FRowCount - 1 do
|
||||||
StrDispose(FCacheItem^.Row[i]);
|
StrDispose(FSavedEditItem^.Row[i]);
|
||||||
FreeMem(FCacheItem^.Row, FRowBufferSize);
|
FreeMem(FSavedEditItem^.Row, FRowBufferSize);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCustomSqliteDataset.FreeRecordBuffer(var Buffer: TRecordBuffer);
|
procedure TCustomSqliteDataset.FreeRecordBuffer(var Buffer: TRecordBuffer);
|
||||||
@ -722,7 +757,7 @@ begin
|
|||||||
case Field.Datatype of
|
case Field.Datatype of
|
||||||
ftString:
|
ftString:
|
||||||
begin
|
begin
|
||||||
Move(FieldRow^, PAnsiChar(Buffer)^, StrLen(FieldRow) + 1);
|
Move(FieldRow^, PAnsiChar(Buffer)^, StrBufSize(FieldRow));
|
||||||
end;
|
end;
|
||||||
ftInteger, ftAutoInc:
|
ftInteger, ftAutoInc:
|
||||||
begin
|
begin
|
||||||
@ -788,21 +823,19 @@ end;
|
|||||||
|
|
||||||
function TCustomSqliteDataset.GetRecNo: Integer;
|
function TCustomSqliteDataset.GetRecNo: Integer;
|
||||||
var
|
var
|
||||||
TempItem, TempActive: PDataRecord;
|
RunItem, ActiveItem: PDataRecord;
|
||||||
begin
|
begin
|
||||||
Result := 0;
|
Result := 0;
|
||||||
if (FRecordCount = 0) or (State = dsInsert) then
|
if (FRecordCount = 0) or (State = dsInsert) then
|
||||||
Exit;
|
Exit;
|
||||||
TempItem := FBeginItem;
|
RunItem := FBeginItem;
|
||||||
TempActive := PPDataRecord(ActiveBuffer)^;
|
ActiveItem := PPDataRecord(ActiveBuffer)^;
|
||||||
if TempActive = FCacheItem then // Record is being edited
|
while ActiveItem <> RunItem do
|
||||||
TempActive := FInternalActiveBuffer;
|
|
||||||
while TempActive <> TempItem do
|
|
||||||
begin
|
begin
|
||||||
if TempItem^.Next <> nil then
|
if RunItem^.Next <> nil then
|
||||||
begin
|
begin
|
||||||
Inc(Result);
|
Inc(Result);
|
||||||
TempItem := TempItem^.Next;
|
RunItem := RunItem^.Next;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@ -819,20 +852,23 @@ end;
|
|||||||
|
|
||||||
procedure TCustomSqliteDataset.InternalAddRecord(Buffer: Pointer; DoAppend: Boolean);
|
procedure TCustomSqliteDataset.InternalAddRecord(Buffer: Pointer; DoAppend: Boolean);
|
||||||
var
|
var
|
||||||
NewItem: PDataRecord;
|
NewItem, ActiveItem: PDataRecord;
|
||||||
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
{$ifdef DEBUG_SQLITEDS}
|
{$ifdef DEBUG_SQLITEDS}
|
||||||
if PPDataRecord(ActiveBuffer)^ <> FCacheItem then
|
if PPDataRecord(ActiveBuffer)^ <> FCacheItem then
|
||||||
DatabaseError('PPDataRecord(ActiveBuffer) <> FCacheItem - Problem', Self);
|
DatabaseError('PPDataRecord(ActiveBuffer) <> FCacheItem - Problem', Self);
|
||||||
{$endif}
|
{$endif}
|
||||||
|
ActiveItem := PPDataRecord(Buffer)^;
|
||||||
New(NewItem);
|
New(NewItem);
|
||||||
GetMem(NewItem^.Row, FRowBufferSize);
|
GetMem(NewItem^.Row, FRowBufferSize);
|
||||||
//if is a detail dataset then set the index value
|
//if is a detail dataset then set the index value
|
||||||
if FMasterLink.Active then
|
if FMasterLink.Active then
|
||||||
SetMasterIndexValue;
|
SetMasterIndexValue;
|
||||||
//necessary to nullify the Row before copy the cache
|
//necessary to nullify the Row before copy the cache
|
||||||
FillChar(NewItem^.Row^, FRowBufferSize, #0);
|
for i := 0 to FRowCount - 1 do
|
||||||
CopyCacheToItem(NewItem);
|
NewItem^.Row[i] := StrBufNew(ActiveItem^.Row[i]);
|
||||||
|
NewItem^.BookmarkFlag := bfCurrent;
|
||||||
|
|
||||||
//insert in the linked list
|
//insert in the linked list
|
||||||
FInsertBookmark^.Previous^.Next := NewItem;
|
FInsertBookmark^.Previous^.Next := NewItem;
|
||||||
@ -865,13 +901,15 @@ end;
|
|||||||
procedure TCustomSqliteDataset.InternalCancel;
|
procedure TCustomSqliteDataset.InternalCancel;
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
|
ActiveItem: PDataRecord;
|
||||||
begin
|
begin
|
||||||
PPDataRecord(ActiveBuffer)^ := FInternalActiveBuffer;
|
ActiveItem := PPDataRecord(ActiveBuffer)^;
|
||||||
//free the cache
|
//copy pristine data to active record
|
||||||
for i:= 0 to FRowCount - 1 do
|
for i:= 0 to FRowCount - 1 do
|
||||||
begin
|
begin
|
||||||
StrDispose(FCacheItem^.Row[i]);
|
StrDispose(ActiveItem^.Row[i]);
|
||||||
FCacheItem^.Row[i] := nil;
|
ActiveItem^.Row[i] := FSavedEditItem^.Row[i];
|
||||||
|
FSavedEditItem^.Row[i] := nil;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -882,8 +920,6 @@ var
|
|||||||
begin
|
begin
|
||||||
Dec(FRecordCount);
|
Dec(FRecordCount);
|
||||||
TempItem := PPDataRecord(ActiveBuffer)^;
|
TempItem := PPDataRecord(ActiveBuffer)^;
|
||||||
if TempItem = FCacheItem then // Record is being edited
|
|
||||||
TempItem := FInternalActiveBuffer;
|
|
||||||
TempItem^.Next^.Previous := TempItem^.Previous;
|
TempItem^.Next^.Previous := TempItem^.Previous;
|
||||||
TempItem^.Previous^.Next := TempItem^.Next;
|
TempItem^.Previous^.Next := TempItem^.Next;
|
||||||
if FCurrentItem = TempItem then
|
if FCurrentItem = TempItem then
|
||||||
@ -911,14 +947,15 @@ end;
|
|||||||
procedure TCustomSqliteDataset.InternalEdit;
|
procedure TCustomSqliteDataset.InternalEdit;
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
|
ActiveItem: PDataRecord;
|
||||||
begin
|
begin
|
||||||
FInternalActiveBuffer := PPDataRecord(ActiveBuffer)^;
|
ActiveItem := PPDataRecord(ActiveBuffer)^;
|
||||||
//copy active item to cache
|
//copy active item to pristine
|
||||||
for i:= 0 to FRowCount - 1 do
|
for i:= 0 to FRowCount - 1 do
|
||||||
FCacheItem^.Row[i] := StrNew(FInternalActiveBuffer^.Row[i]);
|
begin
|
||||||
FCacheItem^.BookmarkFlag := FInternalActiveBuffer^.BookmarkFlag;
|
StrDispose(FSavedEditItem^.Row[i]);
|
||||||
//now active buffer is the cache item
|
FSavedEditItem^.Row[i] := StrBufNew(ActiveItem^.Row[i]);
|
||||||
PPDataRecord(ActiveBuffer)^ := FCacheItem;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCustomSqliteDataset.InternalFirst;
|
procedure TCustomSqliteDataset.InternalFirst;
|
||||||
@ -955,11 +992,13 @@ begin
|
|||||||
if FAutoIncFieldNo <> - 1 then
|
if FAutoIncFieldNo <> - 1 then
|
||||||
begin
|
begin
|
||||||
Str(FNextAutoInc, TempStr);
|
Str(FNextAutoInc, TempStr);
|
||||||
FCacheItem^.Row[FAutoIncFieldNo] := StrAlloc(Length(TempStr) + 1);
|
StrDispose(FBeginItem^.Row[FAutoIncFieldNo]);
|
||||||
StrPCopy(FCacheItem^.Row[FAutoIncFieldNo], TempStr);
|
FBeginItem^.Row[FAutoIncFieldNo] := StrAlloc(Length(TempStr) + 1);
|
||||||
|
StrPCopy(FBeginItem^.Row[FAutoIncFieldNo], TempStr);
|
||||||
end;
|
end;
|
||||||
PPDataRecord(Buffer)^ := FCacheItem;
|
//todo: see if use bfInserted or bfCurrent
|
||||||
FCacheItem^.BookmarkFlag := bfInserted;
|
PPDataRecord(Buffer)^ := FBeginItem;
|
||||||
|
FBeginItem^.BookmarkFlag := bfInserted;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCustomSqliteDataset.InternalLast;
|
procedure TCustomSqliteDataset.InternalLast;
|
||||||
@ -995,16 +1034,19 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCustomSqliteDataset.InternalPost;
|
procedure TCustomSqliteDataset.InternalPost;
|
||||||
|
var
|
||||||
|
ActiveItem: PDataRecord;
|
||||||
begin
|
begin
|
||||||
|
inherited InternalPost;
|
||||||
|
|
||||||
if State <> dsEdit then
|
if State <> dsEdit then
|
||||||
InternalAddRecord(nil, True)
|
InternalAddRecord(ActiveBuffer, True)
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
CopyCacheToItem(FInternalActiveBuffer);
|
ActiveItem := PPDataRecord(ActiveBuffer)^;
|
||||||
PPDataRecord(ActiveBuffer)^ := FInternalActiveBuffer;
|
if (FUpdatedItems.IndexOf(ActiveItem) = -1) and
|
||||||
if (FUpdatedItems.IndexOf(FInternalActiveBuffer) = -1) and
|
(FAddedItems.IndexOf(ActiveItem) = -1) then
|
||||||
(FAddedItems.IndexOf(FInternalActiveBuffer) = -1) then
|
FUpdatedItems.Add(ActiveItem);
|
||||||
FUpdatedItems.Add(FInternalActiveBuffer);
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1296,7 +1338,7 @@ begin
|
|||||||
SaveState := SetTempState(dsInternalCalc);
|
SaveState := SetTempState(dsInternalCalc);
|
||||||
try
|
try
|
||||||
CalculateFields(TRecordBuffer(@TempItem));
|
CalculateFields(TRecordBuffer(@TempItem));
|
||||||
Result := FieldByName(ResultFields).Value;
|
Result := FieldValues[ResultFields];
|
||||||
finally
|
finally
|
||||||
RestoreState(SaveState);
|
RestoreState(SaveState);
|
||||||
end;
|
end;
|
||||||
@ -1345,7 +1387,7 @@ begin
|
|||||||
if State in [dsEdit, dsInsert] then
|
if State in [dsEdit, dsInsert] then
|
||||||
Field.Validate(Buffer);
|
Field.Validate(Buffer);
|
||||||
FieldOffset := Field.FieldNo - 1;
|
FieldOffset := Field.FieldNo - 1;
|
||||||
EditItem := FCacheItem;
|
EditItem := PPDataRecord(ActiveBuffer)^;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
|
@ -4,9 +4,6 @@ program fillds;
|
|||||||
{$H+}
|
{$H+}
|
||||||
{$define DEBUGHEAP}
|
{$define DEBUGHEAP}
|
||||||
|
|
||||||
//To test the sqlite3 version replace sqliteds by sqlite3ds
|
|
||||||
// and TSqliteDataset by TSqlite3Dataset
|
|
||||||
|
|
||||||
uses
|
uses
|
||||||
{$ifdef DEBUGHEAP}
|
{$ifdef DEBUGHEAP}
|
||||||
Heaptrc,
|
Heaptrc,
|
||||||
@ -14,7 +11,7 @@ uses
|
|||||||
{$ifdef Linux}
|
{$ifdef Linux}
|
||||||
cmem,
|
cmem,
|
||||||
{$endif}
|
{$endif}
|
||||||
sqliteds,
|
sqlite3ds,
|
||||||
sysutils,db,IniFiles;
|
sysutils,db,IniFiles;
|
||||||
|
|
||||||
const
|
const
|
||||||
@ -24,14 +21,14 @@ const
|
|||||||
MEMOTEST_FILENAME = 'createds.pas';
|
MEMOTEST_FILENAME = 'createds.pas';
|
||||||
|
|
||||||
var
|
var
|
||||||
dsTest:TSqliteDataset;
|
dsTest: TSqlite3Dataset;
|
||||||
ini: TIniFile;
|
ini: TIniFile;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
{$ifdef DEBUGHEAP}
|
{$ifdef DEBUGHEAP}
|
||||||
SetHeapTraceOutput(ExtractFileName(ParamStr(0))+'.heap.log');
|
SetHeapTraceOutput(ExtractFileName(ParamStr(0))+'.heap.log');
|
||||||
{$endif}
|
{$endif}
|
||||||
dsTest:=TSqliteDataset.Create(nil);
|
dsTest:=TSqlite3Dataset.Create(nil);
|
||||||
with dsTest do
|
with dsTest do
|
||||||
begin
|
begin
|
||||||
//Load Database properties from a inifile
|
//Load Database properties from a inifile
|
||||||
@ -55,6 +52,7 @@ begin
|
|||||||
FieldByName('Currency').AsFloat:=1.23;
|
FieldByName('Currency').AsFloat:=1.23;
|
||||||
FieldByName('LargeInt').AsLargeInt:=2163871263187263;
|
FieldByName('LargeInt').AsLargeInt:=2163871263187263;
|
||||||
Post;
|
Post;
|
||||||
|
|
||||||
Append;
|
Append;
|
||||||
FieldByName('Integer').AsInteger:=101;
|
FieldByName('Integer').AsInteger:=101;
|
||||||
FieldByName('String').AsString:='Américo';
|
FieldByName('String').AsString:='Américo';
|
||||||
@ -68,6 +66,7 @@ begin
|
|||||||
if FileExists(MEMOTEST_FILENAME) then
|
if FileExists(MEMOTEST_FILENAME) then
|
||||||
TMemoField(FieldByName('Memo')).LoadFromFile(MEMOTEST_FILENAME);
|
TMemoField(FieldByName('Memo')).LoadFromFile(MEMOTEST_FILENAME);
|
||||||
Post;
|
Post;
|
||||||
|
|
||||||
Append;
|
Append;
|
||||||
FieldByName('Integer').AsInteger:=102;
|
FieldByName('Integer').AsInteger:=102;
|
||||||
FieldByName('String').AsString:='Ana';
|
FieldByName('String').AsString:='Ana';
|
||||||
@ -78,6 +77,7 @@ begin
|
|||||||
FieldByName('Date').AsDateTime:=Date;
|
FieldByName('Date').AsDateTime:=Date;
|
||||||
FieldByName('LargeInt').AsLargeInt:=9223372036854775807;
|
FieldByName('LargeInt').AsLargeInt:=9223372036854775807;
|
||||||
Post;
|
Post;
|
||||||
|
|
||||||
Append;
|
Append;
|
||||||
FieldByName('Integer').AsInteger:=103;
|
FieldByName('Integer').AsInteger:=103;
|
||||||
FieldByName('String').AsString:='Luiza';
|
FieldByName('String').AsString:='Luiza';
|
||||||
@ -88,6 +88,7 @@ begin
|
|||||||
FieldByName('Date').AsDateTime:=Date;
|
FieldByName('Date').AsDateTime:=Date;
|
||||||
FieldByName('Currency').AsFloat:=20.08;
|
FieldByName('Currency').AsFloat:=20.08;
|
||||||
Post;
|
Post;
|
||||||
|
|
||||||
//Save the added data to database
|
//Save the added data to database
|
||||||
ApplyUpdates;
|
ApplyUpdates;
|
||||||
writeln('ReturnString after ApplyUpdates: ',ReturnString);
|
writeln('ReturnString after ApplyUpdates: ',ReturnString);
|
||||||
|
@ -239,10 +239,14 @@ begin
|
|||||||
end;
|
end;
|
||||||
FieldDefs.Add(String(sqlite3_column_name(vm, i)), AType, DataSize);
|
FieldDefs.Add(String(sqlite3_column_name(vm, i)), AType, DataSize);
|
||||||
//Set the pchar2sql function
|
//Set the pchar2sql function
|
||||||
if AType in [ftString, ftMemo] then
|
case AType of
|
||||||
FGetSqlStr[i] := @Char2SQLStr
|
ftString:
|
||||||
|
FGetSqlStr[i] := @Char2SQLStr;
|
||||||
|
ftMemo:
|
||||||
|
FGetSqlStr[i] := @Memo2SQLStr;
|
||||||
else
|
else
|
||||||
FGetSqlStr[i] := @Num2SQLStr;
|
FGetSqlStr[i] := @Num2SQLStr;
|
||||||
|
end;
|
||||||
{$ifdef DEBUG_SQLITEDS}
|
{$ifdef DEBUG_SQLITEDS}
|
||||||
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));
|
||||||
@ -304,7 +308,7 @@ begin
|
|||||||
TempItem := TempItem^.Next;
|
TempItem := TempItem^.Next;
|
||||||
GetMem(TempItem^.Row, FRowBufferSize);
|
GetMem(TempItem^.Row, FRowBufferSize);
|
||||||
for Counter := 0 to ColumnCount - 1 do
|
for Counter := 0 to ColumnCount - 1 do
|
||||||
TempItem^.Row[Counter] := StrNew(sqlite3_column_text(vm, Counter));
|
TempItem^.Row[Counter] := StrBufNew(sqlite3_column_text(vm, Counter), sqlite3_column_bytes(vm, Counter) + 1);
|
||||||
//initialize calculated fields with nil
|
//initialize calculated fields with nil
|
||||||
for Counter := ColumnCount to FRowCount - 1 do
|
for Counter := ColumnCount to FRowCount - 1 do
|
||||||
TempItem^.Row[Counter] := nil;
|
TempItem^.Row[Counter] := nil;
|
||||||
@ -316,10 +320,10 @@ begin
|
|||||||
TempItem^.Next := FEndItem;
|
TempItem^.Next := FEndItem;
|
||||||
FEndItem^.Previous := TempItem;
|
FEndItem^.Previous := TempItem;
|
||||||
|
|
||||||
// Alloc temporary item used in append/insert
|
// Alloc temporary item used in edit
|
||||||
GetMem(FCacheItem^.Row, FRowBufferSize);
|
GetMem(FSavedEditItem^.Row, FRowBufferSize);
|
||||||
for Counter := 0 to FRowCount - 1 do
|
for Counter := 0 to FRowCount - 1 do
|
||||||
FCacheItem^.Row[Counter] := nil;
|
FSavedEditItem^.Row[Counter] := nil;
|
||||||
// Fill FBeginItem.Row with nil -> necessary for avoid exceptions in empty datasets
|
// Fill FBeginItem.Row with nil -> necessary for avoid exceptions in empty datasets
|
||||||
GetMem(FBeginItem^.Row, FRowBufferSize);
|
GetMem(FBeginItem^.Row, FRowBufferSize);
|
||||||
//Todo: see if is better to nullif using FillDWord
|
//Todo: see if is better to nullif using FillDWord
|
||||||
|
@ -267,9 +267,9 @@ begin
|
|||||||
FEndItem^.Previous := TempItem;
|
FEndItem^.Previous := TempItem;
|
||||||
|
|
||||||
// Alloc item used in append/insert
|
// Alloc item used in append/insert
|
||||||
GetMem(FCacheItem^.Row, FRowBufferSize);
|
GetMem(FSavedEditItem^.Row, FRowBufferSize);
|
||||||
for Counter := 0 to FRowCount - 1 do
|
for Counter := 0 to FRowCount - 1 do
|
||||||
FCacheItem^.Row[Counter] := nil;
|
FSavedEditItem^.Row[Counter] := nil;
|
||||||
// Fill FBeginItem.Row with nil -> necessary for avoid exceptions in empty datasets
|
// Fill FBeginItem.Row with nil -> necessary for avoid exceptions in empty datasets
|
||||||
GetMem(FBeginItem^.Row, FRowBufferSize);
|
GetMem(FBeginItem^.Row, FRowBufferSize);
|
||||||
for Counter := 0 to FRowCount - 1 do
|
for Counter := 0 to FRowCount - 1 do
|
||||||
|
@ -4,9 +4,6 @@ program testds;
|
|||||||
{$H+}
|
{$H+}
|
||||||
{$define DEBUGHEAP}
|
{$define DEBUGHEAP}
|
||||||
|
|
||||||
//To test the sqlite3 version replace sqliteds by sqlite3ds
|
|
||||||
// and TSqliteDataset by TSqlite3Dataset
|
|
||||||
|
|
||||||
uses
|
uses
|
||||||
{$ifdef DEBUGHEAP}
|
{$ifdef DEBUGHEAP}
|
||||||
Heaptrc,
|
Heaptrc,
|
||||||
@ -14,7 +11,7 @@ uses
|
|||||||
{$ifdef Linux}
|
{$ifdef Linux}
|
||||||
cmem,
|
cmem,
|
||||||
{$endif}
|
{$endif}
|
||||||
crt,sysutils,db,sqliteds,IniFiles;
|
crt,sysutils,db,sqlite3ds,IniFiles;
|
||||||
|
|
||||||
const
|
const
|
||||||
SQLITEDS_TESTS_INI_FILE = 'sqlitedstests.ini';
|
SQLITEDS_TESTS_INI_FILE = 'sqlitedstests.ini';
|
||||||
@ -22,14 +19,14 @@ const
|
|||||||
DEFAULT_FILENAME = 'test.db';
|
DEFAULT_FILENAME = 'test.db';
|
||||||
|
|
||||||
var
|
var
|
||||||
dsTest:TSqliteDataset;
|
dsTest: TSqlite3Dataset;
|
||||||
ini: TIniFile;
|
ini: TIniFile;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
{$ifdef DEBUGHEAP}
|
{$ifdef DEBUGHEAP}
|
||||||
SetHeapTraceOutput(ExtractFileName(ParamStr(0))+'.heap.log');
|
SetHeapTraceOutput(ExtractFileName(ParamStr(0))+'.heap.log');
|
||||||
{$endif}
|
{$endif}
|
||||||
dsTest:=TSqliteDataset.Create(nil);
|
dsTest:=TSqlite3Dataset.Create(nil);
|
||||||
with dsTest do
|
with dsTest do
|
||||||
begin
|
begin
|
||||||
//Load Database properties from a inifile
|
//Load Database properties from a inifile
|
||||||
|
Loading…
Reference in New Issue
Block a user