Browse Source

+ Patch from Luiz Americo to implement Locate, Fix GetRecNo.

git-svn-id: trunk@944 -
michael 20 years ago
parent
commit
70dd22c6e1
3 changed files with 72 additions and 21 deletions
  1. 63 13
      fcl/db/sqlite/customsqliteds.pas
  2. 5 5
      fcl/db/sqlite/sqlite3ds.pas
  3. 4 3
      fcl/db/sqlite/sqliteds.pas

+ 63 - 13
fcl/db/sqlite/customsqliteds.pas

@@ -76,7 +76,7 @@ type
     FExpectedUpdates: Integer;
     FExpectedUpdates: Integer;
     FSaveOnClose: Boolean;
     FSaveOnClose: Boolean;
     FSaveOnRefetch: Boolean;
     FSaveOnRefetch: Boolean;
-    FComplexSql: Boolean;
+    FSqlMode: Boolean;
     FUpdatedItems: TFPList;
     FUpdatedItems: TFPList;
     FAddedItems: TFPList;
     FAddedItems: TFPList;
     FDeletedItems: TFPList;
     FDeletedItems: TFPList;
@@ -136,7 +136,8 @@ type
     procedure InternalOpen; override;
     procedure InternalOpen; override;
     procedure InternalPost; override;
     procedure InternalPost; override;
     procedure InternalSetToRecord(Buffer: PChar); override;
     procedure InternalSetToRecord(Buffer: PChar); override;
-    function IsCursorOpen: Boolean; override;    
+    function IsCursorOpen: Boolean; override;
+    function Locate(const keyfields: string; const keyvalues: Variant; options: TLocateOptions) : boolean; override;    
     procedure SetBookmarkData(Buffer: PChar; Data: Pointer); override;
     procedure SetBookmarkData(Buffer: PChar; Data: Pointer); override;
     procedure SetBookmarkFlag(Buffer: PChar; Value: TBookmarkFlag); override;
     procedure SetBookmarkFlag(Buffer: PChar; Value: TBookmarkFlag); override;
     procedure SetExpectedAppends(AValue:Integer);
     procedure SetExpectedAppends(AValue:Integer);
@@ -169,7 +170,6 @@ type
     property AddedItems: TFPList read FAddedItems;
     property AddedItems: TFPList read FAddedItems;
     property DeletedItems: TFPList read FDeletedItems;
     property DeletedItems: TFPList read FDeletedItems;
     {$endif}
     {$endif}
-    property ComplexSql: Boolean read FComplexSql write FComplexSql;
     property ExpectedAppends: Integer read FExpectedAppends write SetExpectedAppends;
     property ExpectedAppends: Integer read FExpectedAppends write SetExpectedAppends;
     property ExpectedUpdates: Integer read FExpectedUpdates write SetExpectedUpdates;
     property ExpectedUpdates: Integer read FExpectedUpdates write SetExpectedUpdates;
     property ExpectedDeletes: Integer read FExpectedDeletes write SetExpectedDeletes;
     property ExpectedDeletes: Integer read FExpectedDeletes write SetExpectedDeletes;
@@ -184,13 +184,13 @@ type
     property SaveOnClose: Boolean read FSaveOnClose write FSaveOnClose; 
     property SaveOnClose: Boolean read FSaveOnClose write FSaveOnClose; 
     property SaveOnRefetch: Boolean read FSaveOnRefetch write FSaveOnRefetch;
     property SaveOnRefetch: Boolean read FSaveOnRefetch write FSaveOnRefetch;
     property SQL: String read FSql write FSql;
     property SQL: String read FSql write FSql;
+    property SqlMode: Boolean read FSqlMode write FSqlMode;
     property TableName: String read FTableName write FTableName;   
     property TableName: String read FTableName write FTableName;   
     property MasterSource: TDataSource read GetMasterSource write SetMasterSource;
     property MasterSource: TDataSource read GetMasterSource write SetMasterSource;
     property MasterFields: string read GetMasterFields write SetMasterFields;
     property MasterFields: string read GetMasterFields write SetMasterFields;
     
     
     property Active;
     property Active;
-    property FieldDefs;
-     
+       
     //Events
     //Events
     property BeforeOpen;
     property BeforeOpen;
     property AfterOpen;
     property AfterOpen;
@@ -215,7 +215,7 @@ type
 implementation
 implementation
 
 
 uses
 uses
-  strutils;
+  strutils, variants;
 
 
 const
 const
   SQLITE_OK = 0;//sqlite2.x.x and sqlite3.x.x defines this equal
   SQLITE_OK = 0;//sqlite2.x.x and sqlite3.x.x defines this equal
@@ -635,9 +635,9 @@ procedure TCustomSqliteDataset.InternalOpen;
 begin
 begin
   FAutoIncFieldNo:=-1;
   FAutoIncFieldNo:=-1;
   if not FileExists(FFileName) then
   if not FileExists(FFileName) then
-    DatabaseError('TCustomSqliteDataset - File "'+FFileName+'" not found',Self);
-  if (FTablename = '') and not (FComplexSql) then
-    DatabaseError('TCustomSqliteDataset - Tablename not set',Self);
+    DatabaseError('File "'+ExpandFileName(FFileName)+'" not found',Self);
+  if (FTablename = '') and not (FSqlMode) then
+    DatabaseError('Tablename not set',Self);
 
 
   if MasterSource <> nil then
   if MasterSource <> nil then
   begin
   begin
@@ -689,9 +689,58 @@ begin
    Result := FDataAllocated;
    Result := FDataAllocated;
 end;
 end;
 
 
+function TCustomSqliteDataset.Locate(const keyfields: string; const keyvalues: Variant; options: TLocateOptions) : boolean;
+var
+  AValue:String;
+  AField:TField;
+  AFieldIndex:Integer;
+  TempItem:PDataRecord;
+begin
+  Result:=False;
+  // Now, it allows to search only one field and ignores options 
+  AField:=Fields.FindField(keyfields);
+  if AField <> nil then
+    AFieldIndex:=AField.FieldNo - 1  
+  else
+    DatabaseError('Field "'+keyfields+'" not found',Self);
+  //get float types in appropriate format
+  if not (AField.DataType in [ftFloat,ftDateTime,ftTime,ftDate]) then
+    AValue:=keyvalues
+  else
+  begin
+    Str(VarToDateTime(keyvalues),AValue);
+    AValue:=Trim(AValue);
+  end;  
+  {$ifdef DEBUG}
+  writeln('=Locate=');
+  writeln('keyfields: ',keyfields);
+  writeln('keyvalues: ',keyvalues);
+  writeln('AValue: ',AValue);
+  {$endif}        
+  //Search the list
+  TempItem:=FBeginItem^.Next;
+  while TempItem <> FEndItem do
+  begin
+    if TempItem^.Row[AFieldIndex] <> nil then
+    begin
+      writeln('TempItem^.Row[AFieldIndex]: ',TempItem^.Row[AFieldIndex]);
+      writeln('PChar(AValue):              ',PChar(AValue));
+      writeln('StrComp result: ',StrComp(TempItem^.Row[AFieldIndex],PChar(AValue)));
+      if StrComp(TempItem^.Row[AFieldIndex],PChar(AValue)) = 0 then
+      begin
+        Result:=True;
+        FCurrentItem:=TempItem;
+        Resync([]);
+        Break;
+      end;
+    end;    
+    TempItem:=TempItem^.Next;
+  end;      
+end;
+
 procedure TCustomSqliteDataset.SetBookmarkData(Buffer: PChar; Data: Pointer);
 procedure TCustomSqliteDataset.SetBookmarkData(Buffer: PChar; Data: Pointer);
 begin
 begin
-  //The BookMarkData is the Buffer itsef;
+  //The BookMarkData is the Buffer itself;
 end;
 end;
 
 
 procedure TCustomSqliteDataset.SetBookmarkFlag(Buffer: PChar; Value: TBookmarkFlag);
 procedure TCustomSqliteDataset.SetBookmarkFlag(Buffer: PChar; Value: TBookmarkFlag);
@@ -760,11 +809,12 @@ var
   TempItem:PDataRecord;
   TempItem:PDataRecord;
 begin
 begin
   if (Value >= FRecordCount) or (Value < 0) then
   if (Value >= FRecordCount) or (Value < 0) then
-    DatabaseError('SqliteDs - Record Number Out Of Range',Self);
+    DatabaseError('Record Number Out Of Range',Self);
   TempItem:=FBeginItem;
   TempItem:=FBeginItem;
   for Counter := 0 to Value do
   for Counter := 0 to Value do
     TempItem:=TempItem^.Next;
     TempItem:=TempItem^.Next;
-  PPDataRecord(ActiveBuffer)^:=TempItem;   
+  FCurrentItem:=TempItem;
+  Resync([]);
 end;
 end;
 
 
 // Specific functions 
 // Specific functions 
@@ -874,7 +924,7 @@ var
   SqlTemp,KeyName,ASqlLine,TemplateStr:String;
   SqlTemp,KeyName,ASqlLine,TemplateStr:String;
 begin
 begin
   Result:=False;
   Result:=False;
-  if (FPrimaryKeyNo <> -1) and not FComplexSql then
+  if (FPrimaryKeyNo <> -1) and not FSqlMode then
   begin
   begin
     StatementsCounter:=0;
     StatementsCounter:=0;
     KeyName:=Fields[FPrimaryKeyNo].FieldName;
     KeyName:=Fields[FPrimaryKeyNo].FieldName;

+ 5 - 5
fcl/db/sqlite/sqlite3ds.pas

@@ -307,7 +307,7 @@ var
   procedure FillStringsAndObjects;
   procedure FillStringsAndObjects;
   begin
   begin
     while FSqliteReturnId = SQLITE_ROW do
     while FSqliteReturnId = SQLITE_ROW do
-    begin      
+    begin
       AStrList.AddObject(StrPas(sqlite3_column_text(vm,0)),TObject(PtrInt(sqlite3_column_int(vm,1))));
       AStrList.AddObject(StrPas(sqlite3_column_text(vm,0)),TObject(PtrInt(sqlite3_column_int(vm,1))));
       FSqliteReturnId:=sqlite3_step(vm);  
       FSqliteReturnId:=sqlite3_step(vm);  
     end;
     end;
@@ -319,12 +319,12 @@ begin
     if FileExists(FFileName) then
     if FileExists(FFileName) then
       AHandle:=GetSqliteHandle
       AHandle:=GetSqliteHandle
     else
     else
-      DatabaseError('File '+FFileName+' not Exists',Self);    
+      DatabaseError('File "'+FFileName+'" not Exists',Self);    
   Result:='';
   Result:='';
-  if AStrList <> nil then
-    AStrList.Clear;
+  // It's up to the caller clear or not the list
+  //if AStrList <> nil then
+  //  AStrList.Clear;
   FSqliteReturnId:=sqlite3_prepare(AHandle,Pchar(ASql),-1,@vm,nil);
   FSqliteReturnId:=sqlite3_prepare(AHandle,Pchar(ASql),-1,@vm,nil);
-  //FSqliteReturnId:=sqlite_compile(AHandle,Pchar(ASql),nil,@vm,nil);
   if FSqliteReturnId <> SQLITE_OK then
   if FSqliteReturnId <> SQLITE_OK then
     DatabaseError('Error returned by sqlite in QuickQuery: '+SqliteReturnString,Self);
     DatabaseError('Error returned by sqlite in QuickQuery: '+SqliteReturnString,Self);
     
     

+ 4 - 3
fcl/db/sqlite/sqliteds.pas

@@ -330,7 +330,7 @@ var
   begin
   begin
     while FSqliteReturnId = SQLITE_ROW do
     while FSqliteReturnId = SQLITE_ROW do
     begin
     begin
-      // I know, this code is really dirty!!      
+      // I know, this code is really dirty!!
       AStrList.AddObject(StrPas(ColumnValues[0]),TObject(PtrInt(StrToInt(StrPas(ColumnValues[1])))));
       AStrList.AddObject(StrPas(ColumnValues[0]),TObject(PtrInt(StrToInt(StrPas(ColumnValues[1])))));
       FSqliteReturnId:=sqlite_step(vm,@ColCount,@ColumnValues,@ColumnNames);  
       FSqliteReturnId:=sqlite_step(vm,@ColCount,@ColumnValues,@ColumnNames);  
     end;
     end;
@@ -344,8 +344,9 @@ begin
     else
     else
       DatabaseError('File '+FFileName+' not Exists',Self);    
       DatabaseError('File '+FFileName+' not Exists',Self);    
   Result:='';
   Result:='';
-  if AStrList <> nil then
-    AStrList.Clear;
+  // It's up to the caller clear or not the list
+  //if AStrList <> nil then
+  //  AStrList.Clear;
   FSqliteReturnId:=sqlite_compile(AHandle,Pchar(ASql),nil,@vm,nil);
   FSqliteReturnId:=sqlite_compile(AHandle,Pchar(ASql),nil,@vm,nil);
   if FSqliteReturnId <> SQLITE_OK then
   if FSqliteReturnId <> SQLITE_OK then
     DatabaseError('Error returned by sqlite in QuickQuery: '+SqliteReturnString,Self);
     DatabaseError('Error returned by sqlite in QuickQuery: '+SqliteReturnString,Self);