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