diff --git a/querywindow.pas b/querywindow.pas index cde1c96..89e45b6 100644 --- a/querywindow.pas +++ b/querywindow.pas @@ -164,8 +164,6 @@ TfmQueryWindow = class(TForm) { private declarations } FDBIndex: Integer; // Index of selected registered database FRegRec: TRegisteredDatabase; - FResultControls: array of TObject; - FParentResultControls: array of TObject; FOptions: set of TSynSearchOption; FIBConnection: TIBConnection; FSQLTrans: TSQLTransaction; @@ -190,7 +188,8 @@ TfmQueryWindow = class(TForm) procedure ExecuteQuery; function GetNewTabNum: string; procedure FinishCellEditing(DataSet: TDataSet); - function GetRecordSet(TabIndex: Integer): TSQLQuery; + // Gets sql query on current result tabsheet + function GetRecordSet: TSQLQuery; // Gets both querytype and whether SQL is DML or DDL // Investigates QueryList[LookAtIndex] to find out function GetQuerySQLType(QueryList: TStringList; var LookAtIndex: Integer; @@ -405,20 +404,31 @@ procedure TfmQueryWindow.ApplyClick(Sender: TObject); var i, x: Integer; aTableName: string; - aQuery: TSQLQuery; + UpdateQuery: TSQLQuery; PKIndexName: string; ConstraintName: string; KeyList, FieldsList: TStringList; WhereClause: string; RecordSet: TSQLQuery; TabIndex: Integer; - //todo: review this and use regular FPC databound controls? autogenerated updatesql etc + //todo: review this and perhaps use regular FPC databound controls? autogenerated updatesql etc FieldsSQL: string; begin try TabIndex:= pgOutputPageCtl.TabIndex; - aTableName:= GetTableName(GetCurrentSQLText); - RecordSet:= GetRecordSet(TabIndex); + RecordSet:= nil; + RecordSet:= GetRecordSet; + aTableName:= GetTableName(RecordSet.SQL.Text); + + // Better safe than sorry + if not(Assigned(RecordSet)) then + begin + ShowMessage('Error getting query from tabsheet.'); + {$IFDEF DEBUG} + SendDebug('ApplyClick: GetRecordSet call returned nil recordset'); + {$ENDIF} + exit; + end; // Get primary key name PKIndexName:= fmMain.GetPrimaryKeyIndexName(FDBIndex, ATableName, ConstraintName); @@ -426,13 +436,13 @@ procedure TfmQueryWindow.ApplyClick(Sender: TObject); begin KeyList:= TStringList.Create; Fieldslist:= TStringList.Create; - aQuery:= TSQLQuery.Create(nil); + UpdateQuery:= TSQLQuery.Create(nil); try - aQuery.DataBase:= FIBConnection; - aQuery.Transaction:= FSQLTrans; + UpdateQuery.DataBase:= FIBConnection; + UpdateQuery.Transaction:= FSQLTrans; // Get primary key fields - fmMain.GetIndexFields(ATableName, PKIndexName, aQuery, KeyList); + fmMain.GetIndexFields(ATableName, PKIndexName, UpdateQuery, KeyList); fmMain.GetFields(FDBIndex, ATableName, FieldsList); WhereClause:= 'where '; @@ -442,7 +452,7 @@ procedure TfmQueryWindow.ApplyClick(Sender: TObject); begin FieldsSQL:= ''; RecordSet.RecNo:= FModifiedRecords[TabIndex][i]; - for x:= 0 to RecordSet.Fields.Count - 1 do + for x:= 0 to RecordSet.FieldCount - 1 do begin if (FieldsList.IndexOf(RecordSet.Fields[x].FieldName) <> -1) and // Field exist in origional table (RecordSet.Fields[x].NewValue <> RecordSet.Fields[x].OldValue) then // field data has been modified @@ -467,8 +477,8 @@ procedure TfmQueryWindow.ApplyClick(Sender: TObject); // Update current record if FieldsSQL <> '' then begin - aQuery.Close; - aQuery.SQL.Text:= 'update ' + aTableName + ' set ' + FieldsSQL; + UpdateQuery.Close; + UpdateQuery.SQL.Text:= 'update ' + aTableName + ' set ' + FieldsSQL; WhereClause:= 'where '; // where clause @@ -489,8 +499,8 @@ procedure TfmQueryWindow.ApplyClick(Sender: TObject); WhereClause += ' and '; end; end; - aQuery.SQL.Add(WhereClause); - aQuery.ExecSQL; + UpdateQuery.SQL.Add(WhereClause); + UpdateQuery.ExecSQL; (Sender as TBitBtn).Visible:= False; // Auto commit @@ -507,7 +517,7 @@ procedure TfmQueryWindow.ApplyClick(Sender: TObject); finally FieldsList.Free; KeyList.Free; - aQuery.Free; + UpdateQuery.Free; end; end else @@ -540,7 +550,7 @@ procedure TfmQueryWindow.EnableApplyButton; end; end; // Found the hosting panel; this should have the Apply button - // as well as the navigator etc + // as well as the commit button and the tdbnavigator if assigned(ParentPanel) then begin for i:= 0 to ParentPanel.ControlCount-1 do @@ -562,13 +572,35 @@ procedure TfmQueryWindow.EnableApplyButton; procedure TfmQueryWindow.EnableCommitButton; var i: Integer; + Ctl: TControl; + ParentPanel: TPanel; begin - for i:= 0 to High(FResultControls) do - if (FResultControls[i] is TBitBtn) and ((FResultControls[i] as TBitBtn).Tag = PageControl1.TabIndex) - and ((FResultControls[i] as TBitBtn).Caption = 'Commit') then + //todo: priority high test whether this works + // The page has a panel that contains the button + ParentPanel:=nil; + for i:= 0 to pgOutputPageCtl.ActivePage.ControlCount-1 do begin - (FResultControls[i] as TBitBtn).Visible:= True; - Break; + Ctl:=pgOutputPageCtl.ActivePage.Controls[i]; + if Ctl is TPanel then + begin + ParentPanel:= TPanel(Ctl); //found + break; + end; + end; + // Found the hosting panel; this should have the Apply, Commit button + // as well as the navigator + if assigned(ParentPanel) then + begin + for i:= 0 to ParentPanel.ControlCount-1 do + begin + Ctl:=ParentPanel.Controls[i]; + if (Ctl is TBitBtn) and + ((Ctl as TBitBtn).Caption = 'Commit') then + begin + (Ctl as TBitBtn).Visible:= true; + Break; + end; + end; end; end; @@ -592,7 +624,6 @@ function TfmQueryWindow.GetTableName(SQLText: string): string; end; if Pos(';', Result) > 0 then Delete(Result, Pos(';', Result), 1); - end; @@ -601,12 +632,15 @@ function TfmQueryWindow.GetTableName(SQLText: string): string; function TfmQueryWindow.GetCurrentSQLText: string; var i: Integer; + Ctl: TControl; begin - for i:= 0 to High(FResultControls) do + // Tabsheet has grid as well as panel + for i:= 0 to pgOutputPageCtl.ActivePage.ControlCount-1 do begin - if (FResultControls[i] is TDBGrid) and ((FResultControls[i] as TDBGrid).Tag = PageControl1.TabIndex) then + Ctl:=pgOutputPageCtl.ActivePage.Controls[i]; + if (Ctl is TDBGrid) then begin - Result:= ((FResultControls[i] as TDBGrid).DataSource.DataSet as TSQLQuery).SQL.Text; + Result:= (TDBGrid(Ctl).DataSource.DataSet as TSQLQuery).SQL.Text; Break; end; end; @@ -642,16 +676,19 @@ procedure TfmQueryWindow.GetLogEvent(Sender: TSQLConnection; { GetRecordSet: return result recordset of a page tab } -function TfmQueryWindow.GetRecordSet(TabIndex: Integer): TSQLQuery; +function TfmQueryWindow.GetRecordSet: TSQLQuery; var i: Integer; + Ctl: TControl; begin - for i:= 0 to High(FResultControls) do + // Tabsheet has grid as well as panel - let's use that to get the dataset + //todo: high priority perhaps better go directly to Tsqlquery object? + for i:= 0 to pgOutputPageCtl.ActivePage.ControlCount-1 do begin - if (FResultControls[i] is TSQLQuery) and - ((FResultControls[i] as TSQLQuery).Tag = TabIndex) then + Ctl:=pgOutputPageCtl.ActivePage.Controls[i]; + if (Ctl is TDBGrid) then begin - Result:= FResultControls[i] as TSQLQuery; + Result:= (TDBGrid(Ctl).DataSource.DataSet as TSQLQuery); Break; end; end; @@ -2096,29 +2133,43 @@ procedure TfmQueryWindow.QueryAfterScroll(DataSet: TDataSet); i: Integer; begin TabSheet:= nil; + // Get DataSet's TTabsheet + //todo: high + //showmessage('todo: priority high same approach as apply button'); + { for i:= 0 to High(FResultControls) do - if (FResultControls[i] <> nil) and - (DataSet = FResultControls[i]) then begin - TabSheet:= FParentResultControls[i] as TTabSheet; - Break; + if (FResultControls[i] <> nil) and + (DataSet = FResultControls[i]) then + begin + TabSheet:= FParentResultControls[i] as TTabSheet; + Break; + end; end; - - - // Search for status bar inside current query result TabSheet + } + // Search for status bar inside current query result TTabSheet if TabSheet <> nil then - for i:= 0 to High(FResultControls) do - if FResultControls[i] <> nil then - if (FParentResultControls[i] <> nil) and ((FParentResultControls[i] as TTabSheet) = TabSheet) - and (FResultControls[i] is TStatusBar) then + begin + //todo: high + //showmessage('todo: priority high same approach as apply button'); + { + for i:= 0 to High(FResultControls) do begin - // Display current record and number of total records in status bar - (FResultControls[i] as TStatusBar).SimpleText:= IntToStr(DataSet.RecordCount) + - ' records fetched. At record # ' + IntToStr(DataSet.RecNo); - break; + if FResultControls[i] <> nil then + begin + if (FParentResultControls[i] <> nil) and ((FParentResultControls[i] as TTabSheet) = TabSheet) + and (FResultControls[i] is TStatusBar) then + begin + // Display current record and number of total records in status bar + (FResultControls[i] as TStatusBar).SimpleText:= IntToStr(DataSet.RecordCount) + + ' records fetched. At record # ' + IntToStr(DataSet.RecNo); + break; + end; + end; + end; + } end; - end;