Browse Source

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

marco 9 years ago
parent
commit
2bd69ff480

+ 6 - 12
packages/fcl-db/src/sqldb/sqlite/sqlite3conn.pp

@@ -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 - 8
packages/fcl-db/src/sqlite/browseds.pas

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

+ 3 - 6
packages/fcl-db/src/sqlite/concurrencyds.pas

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

+ 12 - 8
packages/fcl-db/src/sqlite/createds.pas

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

+ 111 - 69
packages/fcl-db/src/sqlite/customsqliteds.pas

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

+ 7 - 6
packages/fcl-db/src/sqlite/fillds.pas

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

+ 10 - 6
packages/fcl-db/src/sqlite/sqlite3ds.pas

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

+ 2 - 2
packages/fcl-db/src/sqlite/sqliteds.pas

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

+ 3 - 6
packages/fcl-db/src/sqlite/testds.pas

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