Browse Source

Use actual item instead of cache item for edit

git-svn-id: trunk@31837 -
blikblum 10 years ago
parent
commit
da100b43f7

+ 46 - 59
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;
@@ -467,7 +466,7 @@ constructor TCustomSqliteDataset.Create(AOwner: TComponent);
 begin
   // setup special items
   New(FBeginItem);
-  New(FCacheItem);
+  New(FSavedEditItem);
   New(FEndItem);
   
   FBeginItem^.Previous := nil;
@@ -493,10 +492,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 +548,7 @@ begin
   FCalcFieldList.Free;
   // dispose special items
   Dispose(FBeginItem);
-  Dispose(FCacheItem);
+  Dispose(FSavedEditItem);
   Dispose(FEndItem);
 end;
 
@@ -600,19 +596,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]);
@@ -678,10 +661,10 @@ begin
   //Dispose FBeginItem.Row
   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);
@@ -788,21 +771,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 +800,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] := StrNew(ActiveItem^.Row[i]);
+  NewItem^.BookmarkFlag := bfCurrent;
 
   //insert in the linked list
   FInsertBookmark^.Previous^.Next := NewItem;
@@ -865,13 +849,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 +868,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 +895,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] := StrNew(ActiveItem^.Row[i]);
+  end;
 end;
 
 procedure TCustomSqliteDataset.InternalFirst;
@@ -955,11 +940,12 @@ begin
   if FAutoIncFieldNo <> - 1 then
   begin
     Str(FNextAutoInc, TempStr);
-    FCacheItem^.Row[FAutoIncFieldNo] := StrAlloc(Length(TempStr) + 1);
-    StrPCopy(FCacheItem^.Row[FAutoIncFieldNo], TempStr);
+    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 +981,17 @@ begin
 end;
 
 procedure TCustomSqliteDataset.InternalPost;
+var
+  ActiveItem: PDataRecord;
 begin
   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;
 
@@ -1345,7 +1332,7 @@ begin
     if State in [dsEdit, dsInsert] then
       Field.Validate(Buffer);
     FieldOffset := Field.FieldNo - 1;
-    EditItem := FCacheItem;
+    EditItem := PPDataRecord(ActiveBuffer)^;
   end
   else
   begin

+ 3 - 3
packages/fcl-db/src/sqlite/sqlite3ds.pas

@@ -316,10 +316,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