* Generate detail sql used in masterdetail using the fielddefs instead of hardcoding to all fields

* Reset the detail sql also when masterlink is inactive
* Cleanup/refactor masterdetail routines

git-svn-id: trunk@12752 -
This commit is contained in:
blikblum 2009-02-19 17:20:05 +00:00
parent 28bb705abd
commit 09515e6b34

View File

@ -107,13 +107,14 @@ type
procedure SetOptions(const AValue: TSqliteOptions); procedure SetOptions(const AValue: TSqliteOptions);
procedure UpdateIndexFields; procedure UpdateIndexFields;
function FindRecordItem(StartItem: PDataRecord; const KeyFields: string; const KeyValues: Variant; LocateOptions: TLocateOptions; DoResync: Boolean): PDataRecord; function FindRecordItem(StartItem: PDataRecord; const KeyFields: string; const KeyValues: Variant; LocateOptions: TLocateOptions; DoResync: Boolean): PDataRecord;
procedure UpdateMasterDetailProperties;
protected protected
FPrimaryKey: String; FPrimaryKey: String;
FPrimaryKeyNo: Integer; FPrimaryKeyNo: Integer;
FFileName: String; FFileName: String;
FSQL: String; FSQL: String;
FTableName: String; FTableName: String;
FSelectSqlStr: String; FSqlFilterTemplate: String;
FAutoIncFieldNo: Integer; FAutoIncFieldNo: Integer;
FNextAutoInc: Integer; FNextAutoInc: Integer;
FUpdatedItems: TFPList; FUpdatedItems: TFPList;
@ -142,7 +143,6 @@ type
procedure DisposeLinkedList; procedure DisposeLinkedList;
procedure SetDetailFilter; procedure SetDetailFilter;
procedure MasterChanged(Sender: TObject); procedure MasterChanged(Sender: TObject);
procedure MasterDisabled(Sender: TObject);
procedure SetMasterFields(const Value: String); procedure SetMasterFields(const Value: String);
function GetMasterFields: String; function GetMasterFields: String;
procedure SetMasterSource(Value: TDataSource); procedure SetMasterSource(Value: TDataSource);
@ -412,7 +412,7 @@ begin
FMasterLink := TMasterDataLink.Create(Self); FMasterLink := TMasterDataLink.Create(Self);
FMasterLink.OnMasterChange := @MasterChanged; FMasterLink.OnMasterChange := @MasterChanged;
FMasterLink.OnMasterDisable := @MasterDisabled; FMasterLink.OnMasterDisable := @MasterChanged;
FIndexFieldList := TList.Create; FIndexFieldList := TList.Create;
BookmarkSize := SizeOf(Pointer); BookmarkSize := SizeOf(Pointer);
FUpdatedItems := TFPList.Create; FUpdatedItems := TFPList.Create;
@ -821,10 +821,6 @@ end;
procedure TCustomSqliteDataset.InternalInitFieldDefs; procedure TCustomSqliteDataset.InternalInitFieldDefs;
begin begin
//todo: retrieve only necessary fields
if FMasterLink.DataSource <> nil then
FSQL := 'Select * from ' + FTableName + ';'; //forced to obtain all fields
if FSQL = '' then if FSQL = '' then
begin begin
if FTablename = '' then if FTablename = '' then
@ -858,29 +854,17 @@ begin
end; end;
procedure TCustomSqliteDataset.InternalOpen; procedure TCustomSqliteDataset.InternalOpen;
var
i: Integer;
begin begin
InternalInitFieldDefs; InternalInitFieldDefs;
//todo: move this to InitFieldDefs
FSelectSqlStr := 'SELECT ';
for i := 0 to FieldDefs.Count - 2 do
FSelectSqlStr := FSelectSqlStr + FieldDefs[i].Name + ',';
FSelectSqlStr := FSelectSqlStr + FieldDefs[FieldDefs.Count - 1].Name +
' FROM ' + FTableName;
if DefaultFields then if DefaultFields then
CreateFields; CreateFields;
BindFields(True); BindFields(True);
UpdateIndexFields; UpdateIndexFields;
if FMasterLink.Active then
begin if FMasterLink.DataSource <> nil then
if FIndexFieldList.Count <> FMasterLink.Fields.Count then UpdateMasterDetailProperties;
DatabaseError('MasterFields count doesn''t match IndexFields count', Self);
//Set FSQL considering MasterSource active record
SetDetailFilter;
end;
// Get PrimaryKeyNo if available // Get PrimaryKeyNo if available
if Fields.FindField(FPrimaryKey) <> nil then if Fields.FindField(FPrimaryKey) <> nil then
@ -1097,6 +1081,25 @@ begin
end; end;
end; end;
procedure TCustomSqliteDataset.UpdateMasterDetailProperties;
var
i: Integer;
begin
if FMasterLink.Active and (FIndexFieldList.Count <> FMasterLink.Fields.Count) then
DatabaseError('MasterFields count doesn''t match IndexFields count', Self);
if FieldDefs.Count > 0 then
begin
//build the sql template used to filter the dataset
FSqlFilterTemplate := 'SELECT ';
for i := 0 to FieldDefs.Count - 2 do
FSqlFilterTemplate := FSqlFilterTemplate + FieldDefs[i].Name + ',';
FSqlFilterTemplate := FSqlFilterTemplate + FieldDefs[FieldDefs.Count - 1].Name +
' FROM ' + FTableName;
end;
//set FSQL considering MasterSource active record
SetDetailFilter;
end;
procedure TCustomSqliteDataset.GetSqliteHandle; procedure TCustomSqliteDataset.GetSqliteHandle;
begin begin
if FFileName = '' then if FFileName = '' then
@ -1278,8 +1281,8 @@ var
AFilter: String; AFilter: String;
i: Integer; i: Integer;
begin begin
if FMasterLink.Dataset.RecordCount = 0 then //Retrieve all data if (FMasterLink.Dataset.RecordCount = 0) or not FMasterLink.Active then //Retrieve all data
FSQL := 'Select * from ' + FTableName FSQL := FSqlFilterTemplate
else else
begin begin
AFilter := ' where '; AFilter := ' where ';
@ -1289,7 +1292,7 @@ begin
if i <> FMasterLink.Fields.Count - 1 then if i <> FMasterLink.Fields.Count - 1 then
AFilter := AFilter + ' and '; AFilter := AFilter + ' and ';
end; end;
FSQL := 'Select * from ' + FTableName + AFilter; FSQL := FSqlFilterTemplate + AFilter;
end; end;
end; end;
@ -1304,12 +1307,6 @@ begin
RefetchData; RefetchData;
end; end;
procedure TCustomSqliteDataset.MasterDisabled(Sender: TObject);
begin
FSQL := 'Select * from ' + FTableName + ';';
RefetchData;
end;
procedure TCustomSqliteDataset.SetMasterFields(const Value: String); procedure TCustomSqliteDataset.SetMasterFields(const Value: String);
begin begin
FMasterLink.FieldNames := Value; FMasterLink.FieldNames := Value;
@ -1334,8 +1331,11 @@ begin
try try
GetFieldList(FIndexFieldList, FIndexFieldNames); GetFieldList(FIndexFieldList, FIndexFieldNames);
except except
FIndexFieldList.Clear; on E: Exception do
raise; begin
FIndexFieldList.Clear;
DatabaseError('Error retrieving index fields: ' + E.Message);
end;
end; end;
end; end;
end; end;