1 {*********************************************************}
3 { Zeos Database Objects }
4 { UpdateSql property editor }
6 { Originally written by Janos Fegyverneki }
8 {*********************************************************}
10 {@********************************************************}
11 { Copyright (c) 1999-2012 Zeos Development Group }
13 { License Agreement: }
15 { This library is distributed in the hope that it will be }
16 { useful, but WITHOUT ANY WARRANTY; without even the }
17 { implied warranty of MERCHANTABILITY or FITNESS FOR }
18 { A PARTICULAR PURPOSE. See the GNU Lesser General }
19 { Public License for more details. }
21 { The source code of the ZEOS Libraries and packages are }
22 { distributed under the Library GNU General Public }
23 { License (see the file COPYING / COPYING.ZEOS) }
24 { with the following modification: }
25 { As a special exception, the copyright holders of this }
26 { library give you permission to link this library with }
27 { independent modules to produce an executable, }
28 { regardless of the license terms of these independent }
29 { modules, and to copy and distribute the resulting }
30 { executable under terms of your choice, provided that }
31 { you also meet, for each linked independent module, }
32 { the terms and conditions of the license of that module. }
33 { An independent module is a module which is not derived }
34 { from or based on this library. If you modify this }
35 { library, you may extend this exception to your version }
36 { of the library, but you are not obligated to do so. }
37 { If you do not wish to do so, delete this exception }
38 { statement from your version. }
41 { The project web site is located on: }
42 { http://zeos.firmos.at (FORUM) }
43 { http://sourceforge.net/p/zeoslib/tickets/ (BUGTRACKER)}
44 { svn://svn.code.sf.net/p/zeoslib/code-0/trunk (SVN) }
46 { http://www.sourceforge.net/projects/zeoslib. }
49 { Zeos Development Group. }
50 {********************************************************@}
52 unit ZUpdateSqlEditor;
62 PropEdits, Buttons, ComponentEditors,
64 Forms, DB, ExtCtrls, StdCtrls, Controls, ComCtrls,
65 Classes, SysUtils, {$IFNDEF FPC}Windows, {$ELSE}LCLIntf, LResources, {$ENDIF}
66 Menus, ZAbstractDataset,
69 QMenus, QTypes, QExtCtrls, QStdCtrls, QControls, QComCtrls,
76 TWaitMethod = procedure of object;
78 { TZUpdateSQLEditForm }
80 TZUpdateSQLEditForm = class(TForm)
84 GenerateButton: TButton;
86 PrimaryKeyButton: TButton;
87 DefaultButton: TButton;
88 UpdateTableName: TComboBox;
89 FieldsPage: TTabSheet;
91 PageControl: TPageControl;
92 KeyFieldList: TListBox;
93 UpdateFieldList: TListBox;
97 StatementType: TRadioGroup;
98 QuoteFields: TCheckBox;
99 GetTableFieldsButton: TButton;
100 FieldListPopup: TPopupMenu;
101 miSelectAll: TMenuItem;
102 miClearAll: TMenuItem;
104 CancelButton: TButton;
106 procedure FormCreate(Sender: TObject);
107 procedure FormResize(Sender: TObject);
108 procedure HelpButtonClick(Sender: TObject);
109 procedure StatementTypeClick(Sender: TObject);
110 procedure OkButtonClick(Sender: TObject);
111 procedure DefaultButtonClick(Sender: TObject);
112 procedure GenerateButtonClick(Sender: TObject);
113 procedure PrimaryKeyButtonClick(Sender: TObject);
114 procedure PageControlChanging(Sender: TObject;
115 var AllowChange: Boolean);
116 procedure FormDestroy(Sender: TObject);
117 procedure GetTableFieldsButtonClick(Sender: TObject);
118 procedure SettingsChanged(Sender: TObject);
119 procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
120 procedure UpdateTableNameChange(Sender: TObject);
121 procedure UpdateTableNameClick(Sender: TObject);
122 procedure SelectAllClick(Sender: TObject);
123 procedure ClearAllClick(Sender: TObject);
124 procedure SQLMemoKeyPress(Sender: TObject; var Key: Char);
127 DataSet: TZAbstractDataset;
129 ConnectionOpened: Boolean;
130 UpdateSQL: TZUpdateSQL;
131 FSettingsChanged: Boolean;
132 FDatasetDefaults: Boolean;
133 SQLText: array[TUpdateKind] of TStrings;
134 function GetTableRef(const TabName: string): string;
135 function Edit: Boolean;
136 procedure GenWhereClause(const TabAlias: string; KeyFields, SQL: TStrings);
137 procedure GenDeleteSQL(const TableName: string; KeyFields, SQL: TStrings);
138 procedure GenInsertSQL(const TableName: string; UpdateFields, SQL: TStrings);
139 procedure GenModifySQL(const TableName: string; KeyFields, UpdateFields,
141 procedure GenerateSQL;
142 procedure GetDataSetFieldNames;
143 procedure GetTableFieldNames;
144 procedure InitGenerateOptions;
145 procedure InitUpdateTableNames;
146 procedure SetButtonStates;
147 procedure SelectPrimaryKeyFields;
148 procedure SetDefaultSelections;
149 procedure ShowWait(WaitMethod: TWaitMethod);
154 TSQLToken = (stSymbol, stAlias, stNumber, stComma, stEQ, stOther, stLParen,
155 stRParen, stEnd, stSemiColon);
162 FTokenString: string;
164 FSymbolQuoted: Boolean;
165 FQuoteString: string;
166 function NextToken: TSQLToken;
167 function TokenSymbolIs(const S: string): Boolean;
170 constructor Create(const Text, QuoteString: string);
171 procedure GetSelectTableNames(List: TStrings);
172 procedure GetUpdateTableName(var TableName: string);
173 procedure GetUpdateFields(List: TStrings);
174 procedure GetWhereFields(List: TStrings);
177 TZUpdateSqlEditor = class(TComponentEditor)
179 procedure ExecuteVerb(Index: Integer); override;
180 function GetVerb(Index: Integer): string; override;
181 function GetVerbCount: Integer; override;
182 procedure Edit; override;
185 function EditUpdateSQL(AZUpdateSQL: TZUpdateSQL): Boolean;
188 SSQLDataSetOpen = 'Unable to determine field names for %s';
189 SNoDataSet = 'No dataset association';
190 SSQLGenSelect = 'Must select at least one key field and one update field';
191 SSQLNotGenerated = 'Update SQL statements not generated, exit anyway?';
199 uses Dialogs, {$IFNDEF FPC}LibHelp, {$ENDIF}TypInfo, ZCompatibility, ZSqlMetadata,
200 ZDbcIntfs, ZTokenizer, ZGenericSqlAnalyser, ZSelectSchema, ZDbcMetadata;
202 function InternalQuoteIdentifier(const S, QuoteString: string): string;
205 if Length(QuoteString) > 1 then
206 Result := QuoteString[1] + Result + QuoteString[2]
207 else if Length(QuoteString) = 1 then
208 Result := QuoteString[1] + Result + QuoteString[1];
211 { TZUpdateSqlEditor }
213 procedure TZUpdateSqlEditor.ExecuteVerb(Index: Integer);
216 EditUpdateSQL(TZUpdateSQL(Component));
222 function TZUpdateSqlEditor.GetVerb(Index: Integer): string;
224 Result := 'UpdateSql editor...';
231 function TZUpdateSqlEditor.GetVerbCount: Integer;
236 procedure TZUpdateSqlEditor.Edit;
238 EditUpdateSQL(TZUpdateSQL(Component));
241 { Global Interface functions }
243 function EditUpdateSQL(AZUpdateSQL: TZUpdateSQL): Boolean;
245 with TZUpdateSQLEditForm.Create(Application) do
247 UpdateSQL := AZUpdateSQL;
256 procedure GetSelectedItems(ListBox: TListBox; List: TStrings);
261 for I := 0 to ListBox.Items.Count - 1 do
262 if ListBox.Selected[I] then
263 List.AddObject(ListBox.Items[I], ListBox.Items.Objects[I]);
266 function SetSelectedItems(ListBox: TListBox; List: TStrings): Integer;
271 ListBox.Items.BeginUpdate;
273 for I := 0 to ListBox.Items.Count - 1 do
274 if List.IndexOf(ListBox.Items[I]) > -1 then
276 ListBox.Selected[I] := True;
280 ListBox.Selected[I] := False;
281 if ListBox.Items.Count > 0 then
283 ListBox.ItemIndex := 0;
284 ListBox.TopIndex := 0;
287 ListBox.Items.EndUpdate;
291 procedure SelectAll(ListBox: TListBox);
295 ListBox.Items.BeginUpdate;
298 for I := 0 to Items.Count - 1 do
300 if ListBox.Items.Count > 0 then
302 ListBox.ItemIndex := 0;
303 ListBox.TopIndex := 0;
306 ListBox.Items.EndUpdate;
310 procedure GetDataKeyNames(Dataset: TDataset; ErrorName: string; List: TStrings);
320 for I := 0 to FieldDefs.Count - 1 do
322 if not (FieldDefs[I].DataType in [Low(TBlobType)..High(TBlobType)]) then
324 if not (FieldDefs[I].DataType in [ftBlob..ftTypedBinary]) then
326 List.AddObject(FieldDefs[I].Name, Pointer(not FieldDefs[I].Required));
331 if ErrorName <> '' then
332 MessageDlg(Format(SSQLDataSetOpen, [ErrorName]), mtError, [mbOK], 0);
336 procedure GetDataFieldNames(Dataset: TDataset; ErrorName: string; List: TStrings);
346 for I := 0 to FieldDefs.Count - 1 do
347 List.AddObject(FieldDefs[I].Name, Pointer(not FieldDefs[I].Required));
352 if ErrorName <> '' then
353 MessageDlg(Format(SSQLDataSetOpen, [ErrorName]), mtError, [mbOK], 0);
357 procedure ParseUpdateSQL(const SQL, QuoteString: string; var TableName: string;
358 UpdateFields: TStrings; WhereFields: TStrings);
360 with TSQLParser.Create(SQL, QuoteString) do
362 GetUpdateTableName(TableName);
363 if Assigned(UpdateFields) then
366 GetUpdateFields(UpdateFields);
368 if Assigned(WhereFields) then
371 GetWhereFields(WhereFields);
380 constructor TSQLParser.Create(const Text, QuoteString: string);
383 FSourcePtr := PChar(Text);
384 FQuoteString := QuoteString;
385 if FQuoteString = '' then
386 FQuoteString := '""';
387 if Length(FQuoteString) = 1 then
388 FQuoteString := FQuoteString + FQuoteString;
392 function TSQLParser.NextToken: TSQLToken;
394 P, TokenStart: PChar;
398 function IsKatakana(const Chr: Byte): Boolean;
400 Result := (SysLocale.PriLangID = LANG_JAPANESE) and (Chr in [$A1..$DF]);
405 if FToken = stEnd then SysUtils.Abort;
407 FSymbolQuoted := False;
409 while (P^ <> #0) and (P^ <= ' ') do Inc(P);
412 'A'..'Z', 'a'..'z', '_', '$', #127..#255:
415 if not SysLocale.FarEast then
418 while CharInSet(P^, ['A'..'Z', 'a'..'z', '0'..'9', '_', '"', '$', #127..#255] ) do Inc(P);
419 if P^ = '.' then Inc(P);//!!! This must be added for syslocale fareast also
425 if CharInSet(P^, ['A'..'Z', 'a'..'z', '0'..'9', '_', '.', '"', '$']) or
426 {$IFNDEF FPC}IsKatakana(Byte(P^)){$ELSE}False{$ENDIF} then
429 if CharInSet(P^, LeadBytes) then
435 SetString(FTokenString, TokenStart, P - TokenStart);
442 while CharInSet(P^, ['0'..'9', '.', 'e', 'E', '+', '-'] )do Inc(P);
443 SetString(FTokenString, TokenStart, P - TokenStart);
454 FToken := stSemiColon;
474 if P^ = FQuoteString[1] then
478 if IsParam then Inc(P);
480 while not CharInSet(P^, [FQuoteString[2], #0]) do Inc(P);
481 SetString(FTokenString, TokenStart, P - TokenStart);
485 FTokenString := FTokenString + '.';
490 FSymbolQuoted := True;
499 if (FToken = stSymbol) and
500 (FTokenString[Length(FTokenString)] = '.') then FToken := stAlias;
504 procedure TSQLParser.Reset;
506 FSourcePtr := PChar(FText);
511 function TSQLParser.TokenSymbolIs(const S: string): Boolean;
513 Result := (FToken = stSymbol) and (CompareText(FTokenString, S) = 0);
516 procedure TSQLParser.GetSelectTableNames(List: TStrings);
521 if TokenSymbolIs('SELECT') then { Do not localize }
523 while not TokenSymbolIs('FROM') do NextToken; { Do not localize }
525 while FToken = stSymbol do
527 List.AddObject(FTokenString, Pointer(Integer(FSymbolQuoted)));
528 if NextToken = stSymbol then NextToken;
529 if FToken = stComma then NextToken
539 procedure TSQLParser.GetUpdateTableName(var TableName: string);
541 if TokenSymbolIs('UPDATE') and (NextToken = stSymbol) then { Do not localize }
542 TableName := FTokenString else
546 procedure TSQLParser.GetUpdateFields(List: TStrings);
551 if TokenSymbolIs('UPDATE') then { Do not localize }
553 while not TokenSymbolIs('SET') do NextToken; { Do not localize }
557 if FToken = stAlias then NextToken;
558 if FToken <> stSymbol then Break;
559 List.Add(FTokenString);
560 if NextToken <> stEQ then Break;
561 while NextToken <> stComma do
562 if TokenSymbolIs('WHERE') or TokenSymbolIs('UPDATE') then Exit;{ Do not localize }
572 procedure TSQLParser.GetWhereFields(List: TStrings);
577 if TokenSymbolIs('UPDATE') then { Do not localize }
579 while not TokenSymbolIs('WHERE') do NextToken; { Do not localize }
583 while FToken in [stLParen, stRParen, stAlias, stOther] do NextToken;
584 if FToken <> stSymbol then Break;
585 List.Add(FTokenString);
587 if (FToken <> stEQ) and not TokenSymbolIs('IS') then Break;
591 if FToken in [stEnd, stSemiColon] then Exit; //!!!!stSemiColon should be the statement separator
592 if TokenSymbolIs('AND') then Break; { Do not localize }
607 function TZUpdateSQLEditForm.Edit: Boolean;
613 ConnectionOpened := False;
614 if Assigned(UpdateSQL.DataSet) and (UpdateSQL.DataSet is TZAbstractDataset) then
616 DataSet := TZAbstractDataset(UpdateSQL.DataSet);
617 DataSetName := Format('%s%s%s', [DataSet.Owner.Name, DotSep, DataSet.Name]);
618 if Assigned(DataSet.Connection) and not DataSet.Connection.Connected then
620 DataSet.Connection.Connect;
621 ConnectionOpened := True;
624 DataSetName := SNoDataSet;
625 Caption := Format('%s%s%s (%s)', [UpdateSQL.Owner.Name, DotSep, UpdateSQL.Name, DataSetName]);
627 for Index := Low(TUpdateKind) to High(TUpdateKind) do
629 SQLText[Index] := TStringList.Create;
630 SQLText[Index].Assign(UpdateSQL.SQL[Index]);
632 StatementType.ItemIndex := 0;
633 StatementTypeClick(Self);
634 InitUpdateTableNames;
635 ShowWait(InitGenerateOptions);
636 PageControl.ActivePage := PageControl.Pages[0];
637 if ShowModal = mrOk then
639 for Index := low(TUpdateKind) to high(TUpdateKind) do
640 UpdateSQL.SQL[Index] := SQLText[Index];
644 for Index := Low(TUpdateKind) to High(TUpdateKind) do
649 procedure TZUpdateSQLEditForm.GenWhereClause(const TabAlias: string;
650 KeyFields, SQL: TStrings);
655 OldFieldName: string;
657 SQL.Add('WHERE'); { Do not localize }
658 for I := 0 to KeyFields.Count - 1 do
660 FieldName := KeyFields[I];
661 OldFieldName := 'OLD_' + FieldName;
662 if QuoteFields.Checked then
663 FieldName := InternalQuoteIdentifier(FieldName, QuoteChar);
664 if not Assigned(KeyFields.Objects[I]) then
665 BindText := Format(' %s%s = :%s', { Do not localize }
666 [TabAlias, FieldName, OldFieldName])
668 BindText := Format(' ((%0:s%1:s IS NULL AND :%2:s IS NULL) OR (%0:s%1:s = :%2:s))', { Do not localize }
669 [TabAlias, FieldName, OldFieldName]);
670 if I < KeyFields.Count - 1 then
671 BindText := Format('%s AND',[BindText]); { Do not localize }
676 procedure TZUpdateSQLEditForm.GenDeleteSQL(const TableName: string;
677 KeyFields, SQL: TStrings);
679 SQL.Add(Format('DELETE FROM %s', [TableName])); { Do not localize }
680 GenWhereClause(GetTableRef(TableName), KeyFields, SQL);
683 procedure TZUpdateSQLEditForm.GenInsertSQL(const TableName: string;
684 UpdateFields, SQL: TStrings);
686 procedure GenFieldList(const TabName, ParamChar: String);
695 for I := 0 to UpdateFields.Count - 1 do
697 if I = UpdateFields.Count - 1 then Comma := '';
698 FieldName := UpdateFields[I];
699 if QuoteFields.Checked and (ParamChar = '') then
700 FieldName := InternalQuoteIdentifier(FieldName, QuoteChar);
701 L := Format('%s%s%s%s',[L, ParamChar, FieldName, Comma]);
702 if (Length(L) > 70) and (I <> UpdateFields.Count - 1) then
712 SQL.Add(Format('INSERT INTO %s', [TableName])); { Do not localize }
713 GenFieldList(GetTableRef(TableName), '');
714 SQL.Add('VALUES'); { Do not localize }
715 GenFieldList('', ':');
718 procedure TZUpdateSQLEditForm.GenModifySQL(const TableName: string;
719 KeyFields, UpdateFields, SQL: TStrings);
726 SQL.Add(Format('UPDATE %s SET', [TableName])); { Do not localize }
728 TableRef := GetTableRef(TableName);
729 for I := 0 to UpdateFields.Count - 1 do
731 if I = UpdateFields.Count -1 then Comma := '';
732 FieldName := UpdateFields[I];
733 if QuoteFields.Checked then
734 FieldName := InternalQuoteIdentifier(FieldName, QuoteChar);
735 SQL.Add(Format(' %s = :%s%s',
736 [FieldName, UpdateFields[I], Comma]));
738 GenWhereClause(TableRef, KeyFields, SQL);
741 procedure TZUpdateSQLEditForm.GenerateSQL;
743 function QuotedTableName(const BaseName: string): string;
745 if QuoteFields.Checked then
746 Result := InternalQuoteIdentifier(BaseName, QuoteChar)
752 KeyFields: TStringList;
753 UpdateFields: TStringList;
756 if (KeyFieldList.SelCount = 0) or (UpdateFieldList.SelCount = 0) then
757 raise Exception.Create(SSQLGenSelect);
758 KeyFields := TStringList.Create;
760 GetSelectedItems(KeyFieldList, KeyFields);
761 UpdateFields := TStringList.Create;
763 GetSelectedItems(UpdateFieldList, UpdateFields);
764 TableName := QuotedTableName(UpdateTableName.Text);
765 if (SQLText[ukDelete].Text <> '') or (SQLText[ukInsert].Text <> '') or (SQLText[ukModify].Text <> '') then
766 if MessageDlg('The SQL property is not empty. Do you want to clear it before the generation?', mtWarning, [mbYes, mbNo], 0) = mrYes then
768 SQLText[ukDelete].Clear;
769 SQLText[ukInsert].Clear;
770 SQLText[ukModify].Clear;
774 SQLText[ukDelete].Text := SQLText[ukDelete].Text + '';//!!!Statement separator should be added
775 SQLText[ukDelete].Add('');
776 SQLText[ukInsert].Text := SQLText[ukInsert].Text + '';//!!!Statement separator should be added
777 SQLText[ukInsert].Add('');
778 SQLText[ukModify].Text := SQLText[ukModify].Text + '';//!!!Statement separator should be added
779 SQLText[ukModify].Add('');
781 GenDeleteSQL(TableName, KeyFields, SQLText[ukDelete]);
782 GenInsertSQL(TableName, UpdateFields, SQLText[ukInsert]);
783 GenModifySQL(TableName, KeyFields, UpdateFields,
785 SQLMemo.Modified := False;
786 StatementTypeClick(Self);
787 PageControl.SelectNextPage(True);
796 procedure TZUpdateSQLEditForm.GetDataSetFieldNames;
798 if Assigned(DataSet) and Assigned(Dataset.Connection) then
800 GetDataKeyNames(DataSet, DataSet.Name, KeyFieldList.Items);
801 GetDataFieldNames(DataSet, DataSet.Name, UpdateFieldList.Items);
805 procedure TZUpdateSQLEditForm.GetTableFieldNames;
807 ResultSet: IZResultSet;
809 if Assigned(DataSet) and Assigned(DataSet.Connection) and Assigned(DataSet.Connection.dbcConnection)then
812 UpdateFieldList.Clear;
813 ResultSet := DataSet.Connection.DbcConnection.GetMetadata.GetColumns('', '', UpdateTableName.Text, '');
814 if Assigned(ResultSet) then
816 while ResultSet.Next do
818 if ResultSet.GetBooleanByName('SEARCHABLE') then
819 KeyFieldList.Items.AddObject(ResultSet.GetStringByName('COLUMN_NAME'), Pointer(ResultSet.GetIntByName('NULLABLE') <> 0));
820 if ResultSet.GetBooleanByName('WRITABLE') then
821 UpdateFieldList.Items.Add(ResultSet.GetStringByName('COLUMN_NAME')) ;
824 FDatasetDefaults := False;
828 function TZUpdateSQLEditForm.GetTableRef(const TabName: string): string;
830 if QuoteChar <> '' then
831 Result := TabName + '.' else
835 procedure TZUpdateSQLEditForm.InitGenerateOptions;
839 procedure InitFromDataSet;
841 // If this is a Query with more than 1 table in the "from" clause then
842 // initialize the list of fields from the table rather than the dataset.
843 if (UpdateTableName.Items.Count > 1) then
847 GetDataSetFieldNames;
848 FDatasetDefaults := True;
850 SetDefaultSelections;
853 procedure InitFromUpdateSQL;
858 UpdFields := TStringList.Create;
860 WhFields := TStringList.Create;
862 ParseUpdateSQL(SQLText[ukModify].Text, QuoteChar, UpdTabName, UpdFields, WhFields);
863 GetDataSetFieldNames;
864 if SetSelectedItems(UpdateFieldList, UpdFields) < 1 then
865 SelectAll(UpdateFieldList);
866 if SetSelectedItems(KeyFieldList, WhFields) < 1 then
867 SelectAll(KeyFieldList);
877 // If there are existing update SQL statements, try to initialize the
878 // dialog with the fields that correspond to them.
879 if SQLText[ukModify].Count > 0 then
881 ParseUpdateSQL(SQLText[ukModify].Text, QuoteChar, UpdTabName, nil, nil);
882 // If the table name from the update statement is not part of the
883 // dataset, then initialize from the dataset instead.
884 if (UpdateTableName.Items.Count > 0) and
885 (UpdateTableName.Items.IndexOf(UpdTabName) > -1) then
887 UpdateTableName.Text := UpdTabName;
892 UpdateTableName.Items.Add(UpdTabName);
900 THackDataSet = class(TZAbstractDataset);
902 procedure TZUpdateSQLEditForm.InitUpdateTableNames;
906 Tokenizer: IZTokenizer;
907 StatementAnalyser: IZStatementAnalyser;
908 SelectSchema: IZSelectSchema;
911 if Assigned(DataSet) and Assigned(DataSet.Connection)
912 and Assigned(DataSet.Connection.DbcConnection)then
914 QuoteChar := DataSet.Connection.DbcConnection.GetMetadata.GetDatabaseInfo.
915 GetIdentifierQuoteString;
916 if Length(QuoteChar) = 1 then
917 QuoteChar := QuoteChar + QuoteChar;
918 { Parses the Select statement and retrieves a schema object. }
919 Tokenizer := DataSet.Connection.DbcDriver.GetTokenizer;
920 StatementAnalyser := DataSet.Connection.DbcDriver.GetStatementAnalyser;
921 SelectSchema := StatementAnalyser.DefineSelectSchemaFromQuery(Tokenizer,
922 THackDataSet(DataSet).SQL.Text);
923 if Assigned(SelectSchema) then
925 UpdateTableName.Clear;
926 for I := 0 to SelectSchema.TableCount - 1 do
927 UpdateTableName.Items.Add(SelectSchema.Tables[I].Table);//!!!Schema support
931 if Assigned(Dataset) then
934 if SQLText[ukModify].Count > 0 then
935 ParseUpdateSql(SQLText[ukModify].Text, QuoteChar, TableName, nil, nil);
936 if TableName <> '' then
937 UpdateTableName.Items.Add(TableName);
939 if UpdateTableName.Items.Count > 0 then
940 UpdateTableName.ItemIndex := 0;
943 procedure TZUpdateSQLEditForm.SetButtonStates;
945 GetTableFieldsButton.Enabled := UpdateTableName.Text <> '';
946 PrimaryKeyButton.Enabled := GetTableFieldsButton.Enabled and
947 (KeyFieldList.Items.Count > 0);
948 GenerateButton.Enabled := GetTableFieldsButton.Enabled and
949 (UpdateFieldList.Items.Count > 0) and (KeyFieldList.Items.Count > 0);
950 DefaultButton.Enabled := Assigned(DataSet) and not FDatasetDefaults;
953 procedure TZUpdateSQLEditForm.SelectPrimaryKeyFields;
957 PKeys: TZSQLMetadata;
959 if KeyFieldList.Items.Count < 1 then Exit;
962 for I := 0 to KeyFieldList.Items.Count - 1 do
963 KeyFieldList.Selected[I] := False;
964 PKeys := TZSQLMetadata.Create(nil);
966 PKeys.Connection := Connection;
967 PKeys.TableName := UpdateTableName.Text;
968 PKeys.MetadataType := mdPrimaryKeys;
971 while not PKeys.Eof do
973 Index := KeyFieldList.Items.IndexOf(PKeys.FieldByName('COLUMN_NAME').AsString);
974 if Index > -1 then KeyFieldList.Selected[Index] := True;
983 procedure TZUpdateSQLEditForm.SetDefaultSelections;
985 DSFields: TStringList;
987 if FDatasetDefaults or not Assigned(DataSet) then
989 SelectAll(UpdateFieldList);
990 SelectAll(KeyFieldList);
992 else if (DataSet.FieldDefs.Count > 0) then
994 DSFields := TStringList.Create;
996 GetDataFieldNames(DataSet, '', DSFields);
997 SetSelectedItems(KeyFieldList, DSFields);
998 SetSelectedItems(UpdateFieldList, DSFields);
1005 procedure TZUpdateSQLEditForm.ShowWait(WaitMethod: TWaitMethod);
1007 Screen.Cursor := crHourGlass;
1011 Screen.Cursor := crDefault;
1017 procedure TZUpdateSQLEditForm.FormCreate(Sender: TObject);
1019 // HelpContext := hcDUpdateSQL;
1022 procedure TZUpdateSQLEditForm.FormResize(Sender: TObject);
1025 i := PageControl.Height - 92;
1026 If i < 0 Then i := 0;
1027 SQLMemo.Height := i;
1030 procedure TZUpdateSQLEditForm.HelpButtonClick(Sender: TObject);
1032 Application.HelpContext(HelpContext);
1035 procedure TZUpdateSQLEditForm.StatementTypeClick(Sender: TObject);
1037 if SQLMemo.Modified then
1038 SQLText[TUpdateKind(StmtIndex)].Assign(SQLMemo.Lines);
1039 StmtIndex := StatementType.ItemIndex;
1040 SQLMemo.Lines.Assign(SQLText[TUpdateKind(StmtIndex)]);
1043 procedure TZUpdateSQLEditForm.OkButtonClick(Sender: TObject);
1045 if SQLMemo.Modified then
1046 SQLText[TUpdateKind(StmtIndex)].Assign(SQLMemo.Lines);
1049 procedure TZUpdateSQLEditForm.DefaultButtonClick(Sender: TObject);
1051 with UpdateTableName do
1052 if Items.Count > 0 then ItemIndex := 0;
1053 ShowWait(GetDataSetFieldNames);
1054 FDatasetDefaults := True;
1055 SetDefaultSelections;
1056 KeyfieldList.SetFocus;
1060 procedure TZUpdateSQLEditForm.GenerateButtonClick(Sender: TObject);
1063 FSettingsChanged := False;
1066 procedure TZUpdateSQLEditForm.PrimaryKeyButtonClick(Sender: TObject);
1068 ShowWait(SelectPrimaryKeyFields);
1069 SettingsChanged(Sender);
1072 procedure TZUpdateSQLEditForm.PageControlChanging(Sender: TObject;
1073 var AllowChange: Boolean);
1075 if (PageControl.ActivePage = PageControl.Pages[0]) and
1076 not SQLPage.Enabled then
1077 AllowChange := False;
1080 procedure TZUpdateSQLEditForm.FormDestroy(Sender: TObject);
1082 if ConnectionOpened then
1083 DataSet.Connection.Disconnect;
1086 procedure TZUpdateSQLEditForm.GetTableFieldsButtonClick(Sender: TObject);
1088 ShowWait(GetTableFieldNames);
1089 SetDefaultSelections;
1090 SettingsChanged(Sender);
1093 procedure TZUpdateSQLEditForm.SettingsChanged(Sender: TObject);
1095 FSettingsChanged := True;
1096 FDatasetDefaults := False;
1100 procedure TZUpdateSQLEditForm.FormCloseQuery(Sender: TObject;
1101 var CanClose: Boolean);
1103 if (ModalResult = mrOK) and FSettingsChanged then
1104 CanClose := MessageDlg(SSQLNotGenerated, mtConfirmation,
1105 mbYesNoCancel, 0) = mrYes;
1108 procedure TZUpdateSQLEditForm.UpdateTableNameChange(Sender: TObject);
1110 SettingsChanged(Sender);
1113 procedure TZUpdateSQLEditForm.UpdateTableNameClick(Sender: TObject);
1115 if not Visible then Exit;
1116 GetTableFieldsButtonClick(Sender);
1119 procedure TZUpdateSQLEditForm.SelectAllClick(Sender: TObject);
1121 SelectAll(FieldListPopup.PopupComponent as TListBox);
1124 procedure TZUpdateSQLEditForm.ClearAllClick(Sender: TObject);
1128 with FieldListPopup.PopupComponent as TListBox do
1132 for I := 0 to Items.Count - 1 do
1133 Selected[I] := False;
1140 procedure TZUpdateSQLEditForm.SQLMemoKeyPress(Sender: TObject;
1143 if Key = #27 then Close;
1148 {$i ZUpdateSqlEditor.lrs}