home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 October / Chip_2001-10_cd1.bin / zkuste / delphi / kompon / d45 / ARDOCI.ZIP / AOraUpdateSQLEd.pas < prev    next >
Pascal/Delphi Source File  |  2001-04-06  |  27KB  |  997 lines

  1.  
  2. {*******************************************************}
  3. {                                                       }
  4. {       AXIOMA Delphi Visual Component Library          }
  5. {       AOraUpdateSQL Component Editor                  }
  6. {                                                       }
  7. {       Copyright (c) 1997,2001 AXIOMA Corp             }
  8. {                                                       }
  9. {*******************************************************}
  10.  
  11. unit AOraUpdateSQLEd;
  12.  
  13. interface
  14.  
  15. uses Forms, DB,{ DBTables,} ExtCtrls, StdCtrls, Controls, ComCtrls, Dsgnintf,
  16.   Classes, SysUtils, Windows, Menus, OraDB, AOraUpdateSQL, OraSQL,
  17.   AOraSQL, VirtualDataSet, DataSetQuery;
  18.  
  19. type
  20.  
  21.   TWaitMethod = procedure of object;
  22.  
  23.   TAOraUpdateSQLEditForm = class(TForm)
  24.     OkButton: TButton;
  25.     CancelButton: TButton;
  26.     HelpButton: TButton;
  27.     GenerateButton: TButton;
  28.     PrimaryKeyButton: TButton;
  29.     DefaultButton: TButton;
  30.     UpdateTableName: TComboBox;
  31.     FieldsPage: TTabSheet;
  32.     SQLPage: TTabSheet;
  33.     PageControl: TPageControl;
  34.     KeyFieldList: TListBox;
  35.     UpdateFieldList: TListBox;
  36.     GroupBox1: TGroupBox;
  37.     Label1: TLabel;
  38.     SQLMemo: TMemo;
  39.     StatementType: TRadioGroup;
  40.     QuoteFields: TCheckBox;
  41.     GetTableFieldsButton: TButton;
  42.     FieldListPopup: TPopupMenu;
  43.     miSelectAll: TMenuItem;
  44.     miClearAll: TMenuItem;
  45.     FTempSQL: TOraSQL;
  46.     procedure FormCreate(Sender: TObject);
  47.     procedure HelpButtonClick(Sender: TObject);
  48.     procedure StatementTypeClick(Sender: TObject);
  49.     procedure OkButtonClick(Sender: TObject);
  50.     procedure DefaultButtonClick(Sender: TObject);
  51.     procedure GenerateButtonClick(Sender: TObject);
  52.     procedure PrimaryKeyButtonClick(Sender: TObject);
  53.     procedure PageControlChanging(Sender: TObject;
  54.       var AllowChange: Boolean);
  55.     procedure FormDestroy(Sender: TObject);
  56.     procedure GetTableFieldsButtonClick(Sender: TObject);
  57.     procedure SettingsChanged(Sender: TObject);
  58.     procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  59.     procedure UpdateTableNameChange(Sender: TObject);
  60.     procedure UpdateTableNameClick(Sender: TObject);
  61.     procedure SelectAllClick(Sender: TObject);
  62.     procedure ClearAllClick(Sender: TObject);
  63.     procedure SQLMemoKeyPress(Sender: TObject; var Key: Char);
  64.   private
  65.     StmtIndex: Integer;
  66.     DataSet: TOraSQL;//TDBDataSet;
  67.     Database: TOraDB;//TDatabase
  68.     DatabaseOpened: Boolean;
  69.     UpdateSQL: TAOraUpdateSQL;//TUpdateSQL
  70.     FSettingsChanged: Boolean;
  71.     FDatasetDefaults: Boolean;
  72.     SQLText: array[TUpdateKind] of TStrings;
  73.     function GetTableRef(const TabName, QuoteChar: string): string;
  74.     function DatabaseOpen: Boolean;
  75.     function Edit: Boolean;
  76.     procedure GenWhereClause(const TabAlias, QuoteChar: string;
  77.       KeyFields, SQL: TStrings);
  78.     procedure GenDeleteSQL(const TableName, QuoteChar: string;
  79.       KeyFields, SQL: TStrings);
  80.     procedure GenInsertSQL(const TableName, QuoteChar: string;
  81.       UpdateFields, SQL: TStrings);
  82.     procedure GenModifySQL(const TableName, QuoteChar: string;
  83.       KeyFields, UpdateFields, SQL: TStrings);
  84.     procedure GenerateSQL;
  85.     procedure GetDataSetFieldNames;
  86.     procedure GetTableFieldNames;
  87.     procedure InitGenerateOptions;
  88.     procedure InitUpdateTableNames;
  89.     procedure SetButtonStates;
  90.     procedure SelectPrimaryKeyFields;
  91.     procedure SetDefaultSelections;
  92.     procedure ShowWait(WaitMethod: TWaitMethod);
  93.     function TempTable: TOraSQL;
  94.   end;
  95.  
  96. { TSQLParser }
  97.  
  98.   TSQLToken = (stSymbol, stAlias, stNumber, stComma, stEQ, stOther, stLParen,
  99.     stRParen, stEnd);
  100.  
  101.   TSQLParser = class
  102.   private
  103.     FText: string;
  104.     FSourcePtr: PChar;
  105.     FTokenPtr: PChar;
  106.     FTokenString: string;
  107.     FToken: TSQLToken;
  108.     FSymbolQuoted: Boolean;
  109.     function NextToken: TSQLToken;
  110.     function TokenSymbolIs(const S: string): Boolean;
  111.     procedure Reset;
  112.   public
  113.     constructor Create(const Text: string);
  114.     procedure GetSelectTableNames(List: TStrings);
  115.     procedure GetUpdateTableName(var TableName: string);
  116.     procedure GetUpdateFields(List: TStrings);
  117.     procedure GetWhereFields(List: TStrings);
  118.   end;
  119.  
  120.   TAOraUpdateSQLEditor = class(TComponentEditor)
  121.   public
  122.     procedure ExecuteVerb(Index: Integer); override;
  123.     function GetVerb(Index: Integer): string; override;
  124.     function GetVerbCount: Integer; override;
  125.   end;
  126.  
  127. //function EditUpdateSQL(AUpdateSQL: TUpdateSQL): Boolean;
  128. function EditUpdateSQL(AOraUpdateSQL: TAOraUpdateSQL): Boolean;
  129. procedure Register;
  130.  
  131. resourcestring
  132.  sSQLDataSetOpen = 'Unable to determine field names for %s';
  133.  sUpdateSQLEditor = '&AOraUpdateSQL Editor...';
  134.  sNoDataSet = 'No dataset association';
  135.  sSQLGenSelect = 'Must select at least one key field and one update field';
  136.  sSQLNotGenerated = 'Update SQL statements not generated, exit anyway?';
  137.  
  138. implementation
  139.  
  140. {$R *.DFM}
  141.  
  142. uses Dialogs, {BdeConst,} LibHelp, TypInfo{, BDE};
  143.  
  144. procedure Register;
  145. begin
  146.   RegisterComponentEditor(TAOraUpdateSQL,TAOraUpdateSQLEditor);
  147. end;
  148.  
  149.  
  150. { Global Interface functions }
  151.  
  152. function EditUpdateSQL(AOraUpdateSQL: TAOraUpdateSQL): Boolean;
  153. begin
  154.   with TAOraUpdateSQLEditForm.Create(Application) do
  155.   try
  156.     UpdateSQL := AOraUpdateSQL;
  157.     Result := Edit;
  158.   finally
  159.     Free;
  160.   end;
  161. end;
  162.  
  163. { Utility Routines }
  164.  
  165. procedure GetSelectedItems(ListBox: TListBox; List: TStrings);
  166. var
  167.   I: Integer;
  168. begin
  169.   List.Clear;
  170.   for I := 0 to ListBox.Items.Count - 1 do
  171.     if ListBox.Selected[I] then
  172.       List.Add(ListBox.Items[I]);
  173. end;
  174.  
  175. function SetSelectedItems(ListBox: TListBox; List: TStrings): Integer;
  176. var
  177.   I: Integer;
  178. begin
  179.   Result := 0;
  180.   ListBox.Items.BeginUpdate;
  181.   try
  182.     for I := 0 to ListBox.Items.Count - 1 do
  183.       if List.IndexOf(ListBox.Items[I]) > -1 then
  184.       begin
  185.         ListBox.Selected[I] := True;
  186.         Inc(Result);
  187.       end
  188.       else
  189.         ListBox.Selected[I] := False;
  190.     if ListBox.Items.Count > 0 then
  191.     begin
  192.       ListBox.ItemIndex := 0;
  193.       ListBox.TopIndex := 0;
  194.     end;
  195.   finally
  196.     ListBox.Items.EndUpdate;
  197.   end;
  198. end;
  199.  
  200. procedure SelectAll(ListBox: TListBox);
  201. var
  202.   I: Integer;
  203. begin
  204.   ListBox.Items.BeginUpdate;
  205.   try
  206.     with ListBox do
  207.       for I := 0 to Items.Count - 1 do
  208.         Selected[I] := True;
  209.     if ListBox.Items.Count > 0 then
  210.     begin
  211.       ListBox.ItemIndex := 0;
  212.       ListBox.TopIndex := 0;
  213.     end;
  214.   finally
  215.     ListBox.Items.EndUpdate;
  216.   end;
  217. end;
  218.  
  219. procedure GetDataFieldNames(Dataset: TDataset; ErrorName: string; List: TStrings);
  220. var
  221.   I: Integer;
  222. begin
  223.   with Dataset do
  224.   try
  225.     FieldDefs.Update;
  226.     List.BeginUpdate;
  227.     try
  228.       List.Clear;
  229.       for I := 0 to FieldDefs.Count - 1 do
  230.         List.Add(FieldDefs[I].Name);
  231.     finally
  232.       List.EndUpdate;
  233.     end;
  234.   except
  235.     if ErrorName <> '' then
  236.       MessageDlg(Format(SSQLDataSetOpen, [ErrorName]), mtError, [mbOK], 0);
  237.   end;
  238. end;
  239.  
  240. procedure GetSQLTableNames(const SQL: string; List: TStrings);
  241. begin
  242.   with TSQLParser.Create(SQL) do
  243.   try
  244.     GetSelectTableNames(List);
  245.   finally
  246.     Free;
  247.   end;
  248. end;
  249.  
  250. procedure ParseUpdateSQL(const SQL: string; var TableName: string;
  251.   UpdateFields: TStrings; WhereFields: TStrings);
  252. begin
  253.   with TSQLParser.Create(SQL) do
  254.   try
  255.     GetUpdateTableName(TableName);
  256.     if Assigned(UpdateFields) then
  257.     begin
  258.       Reset;
  259.       GetUpdateFields(UpdateFields);
  260.     end;
  261.     if Assigned(WhereFields) then
  262.     begin
  263.       Reset;
  264.       GetWhereFields(WhereFields);
  265.     end;
  266.   finally
  267.     Free;
  268.   end;
  269. end;
  270.  
  271.   { TUpdateSQLEditor }
  272.  
  273. procedure TAOraUpdateSQLEditor.ExecuteVerb(Index: Integer);
  274. begin
  275.   if EditUpdateSQL(TAOraUpdateSQL(Component)) then Designer.Modified;
  276. end;
  277.  
  278. function TAOraUpdateSQLEditor.GetVerb(Index: Integer): string;
  279. begin
  280.   Result := SUpdateSQLEditor;
  281. end;
  282.  
  283. function TAOraUpdateSQLEditor.GetVerbCount: Integer;
  284. begin
  285.   Result := 1;
  286. end;
  287.  
  288. { TSQLParser }
  289.  
  290. constructor TSQLParser.Create(const Text: string);
  291. begin
  292.   FText := Text;
  293.   FSourcePtr := PChar(Text);
  294.   NextToken;
  295. end;
  296.  
  297. function TSQLParser.NextToken: TSQLToken;
  298. var
  299.   P, TokenStart: PChar;
  300.   QuoteChar: Char;
  301.   IsParam: Boolean;
  302.  
  303.   function IsKatakana(const Chr: Byte): Boolean;
  304.   begin
  305.     Result := (SysLocale.PriLangID = LANG_JAPANESE) and (Chr in [$A1..$DF]);
  306.   end;
  307.  
  308. begin
  309.   if FToken = stEnd then SysUtils.Abort;
  310.   FTokenString := '';
  311.   FSymbolQuoted := False;
  312.   P := FSourcePtr;
  313.   while (P^ <> #0) and (P^ <= ' ') do Inc(P);
  314.   FTokenPtr := P;
  315.   case P^ of
  316.     'A'..'Z', 'a'..'z', '_', '$', #127..#255:
  317.       begin
  318.         TokenStart := P;
  319.         if not SysLocale.FarEast then
  320.         begin
  321.           Inc(P);
  322.           while P^ in ['A'..'Z', 'a'..'z', '0'..'9', '_', '.', '"', '$', #127..#255] do Inc(P);
  323.         end
  324.         else
  325.           begin
  326.             while TRUE do
  327.             begin
  328.               if (P^ in ['A'..'Z', 'a'..'z', '0'..'9', '_', '.', '"', '$']) or
  329.                  IsKatakana(Byte(P^)) then
  330.                 Inc(P)
  331.               else
  332.                 if P^ in LeadBytes then
  333.                   Inc(P, 2)
  334.                 else
  335.                   Break;
  336.             end;
  337.           end;
  338.         SetString(FTokenString, TokenStart, P - TokenStart);
  339.         FToken := stSymbol;
  340.       end;
  341.     '''', '"':
  342.       begin
  343.         QuoteChar := P^;
  344.         Inc(P);
  345.         IsParam := P^ = ':';
  346.         if IsParam then Inc(P);
  347.         TokenStart := P;
  348.         while not (P^ in [QuoteChar, #0]) do Inc(P);
  349.         SetString(FTokenString, TokenStart, P - TokenStart);
  350.         Inc(P);
  351.         Trim(FTokenString);
  352.         FToken := stSymbol;
  353.         FSymbolQuoted := True;
  354.       end;
  355.     '-', '0'..'9':
  356.       begin
  357.         TokenStart := P;
  358.         Inc(P);
  359.         while P^ in ['0'..'9', '.', 'e', 'E', '+', '-'] do Inc(P);
  360.         SetString(FTokenString, TokenStart, P - TokenStart);
  361.         FToken := stNumber;
  362.       end;
  363.     ',':
  364.       begin
  365.         Inc(P);
  366.         FToken := stComma;
  367.       end;
  368.     '=':
  369.       begin
  370.         Inc(P);
  371.         FToken := stEQ;
  372.       end;
  373.     '(':
  374.       begin
  375.         Inc(P);
  376.         FToken := stLParen;
  377.       end;
  378.     ')':
  379.       begin
  380.         Inc(P);
  381.         FToken := stRParen;
  382.       end;
  383.     #0:
  384.       FToken := stEnd;
  385.   else
  386.     begin
  387.       FToken := stOther;
  388.       Inc(P);
  389.     end;
  390.   end;
  391.   FSourcePtr := P;
  392.   if (FToken = stSymbol) and
  393.     (FTokenString[Length(FTokenString)] = '.') then FToken := stAlias;
  394.   Result := FToken;
  395. end;
  396.  
  397. procedure TSQLParser.Reset;
  398. begin
  399.   FSourcePtr := PChar(FText);
  400.   FToken := stSymbol;
  401.   NextToken;
  402. end;
  403.  
  404. function TSQLParser.TokenSymbolIs(const S: string): Boolean;
  405. begin
  406.   Result := (FToken = stSymbol) and (CompareText(FTokenString, S) = 0);
  407. end;
  408.  
  409. procedure TSQLParser.GetSelectTableNames(List: TStrings);
  410. begin
  411.   List.BeginUpdate;
  412.   try
  413.     List.Clear;
  414.     if TokenSymbolIs('SELECT') then { Do not localize }
  415.     try
  416.       while not TokenSymbolIs('FROM') do NextToken; { Do not localize }
  417.       NextToken;
  418.       while FToken = stSymbol do
  419.       begin
  420.         List.AddObject(FTokenString, Pointer(Integer(FSymbolQuoted)));
  421.         if NextToken = stSymbol then NextToken;
  422.         if FToken = stComma then NextToken
  423.         else break;
  424.       end;
  425.     except
  426.     end;
  427.   finally
  428.     List.EndUpdate;
  429.   end;
  430. end;
  431.  
  432. procedure TSQLParser.GetUpdateTableName(var TableName: string);
  433. begin
  434.   if TokenSymbolIs('UPDATE') and (NextToken = stSymbol) then { Do not localize }
  435.     TableName := FTokenString else
  436.     TableName := '';
  437. end;
  438.  
  439. procedure TSQLParser.GetUpdateFields(List: TStrings);
  440. begin
  441.   List.BeginUpdate;
  442.   try
  443.     List.Clear;
  444.     if TokenSymbolIs('UPDATE') then { Do not localize }
  445.     try
  446.       while not TokenSymbolIs('SET') do NextToken; { Do not localize }
  447.       NextToken;
  448.       while True do
  449.       begin
  450.         if FToken = stAlias then NextToken;
  451.         if FToken <> stSymbol then Break;
  452.         List.Add(FTokenString);
  453.         if NextToken <> stEQ then Break;
  454.         while NextToken <> stComma do
  455.           if TokenSymbolIs('WHERE') then Exit;{ Do not localize }
  456.         NextToken;
  457.       end;
  458.     except
  459.     end;
  460.   finally
  461.     List.EndUpdate;
  462.   end;
  463. end;
  464.  
  465. procedure TSQLParser.GetWhereFields(List: TStrings);
  466. begin
  467.   List.BeginUpdate;
  468.   try
  469.     List.Clear;
  470.     if TokenSymbolIs('UPDATE') then { Do not localize }
  471.     try
  472.       while not TokenSymbolIs('WHERE') do NextToken; { Do not localize }
  473.       NextToken;
  474.       while True do
  475.       begin
  476.         while FToken in [stLParen, stAlias] do NextToken;
  477.         if FToken <> stSymbol then Break;
  478.         List.Add(FTokenString);
  479.         if NextToken <> stEQ then Break;
  480.         while true do
  481.         begin
  482.           NextToken;
  483.           if FToken = stEnd then Exit;
  484.           if TokenSymbolIs('AND') then Break; { Do not localize }
  485.         end;
  486.         NextToken;
  487.       end;
  488.     except
  489.     end;
  490.   finally
  491.     List.EndUpdate;
  492.   end;
  493. end;
  494.  
  495. { TUpdateSQLEditor }
  496.  
  497. { Private Methods }
  498.  
  499. function TAOraUpdateSQLEditForm.DatabaseOpen: Boolean;
  500. begin
  501.   if Assigned(Database) then
  502.     Result := True
  503.   else
  504.   begin
  505.     Result := False;
  506.     if not Assigned(DataSet) then Exit;
  507.     if Assigned(DataSet.Database) then
  508.     begin
  509.       Database := TOraDB(DataSet.Database);
  510.       Result := True;
  511.     end
  512. {    else
  513.     begin
  514.       Database := DataSet.OpenDatabase;
  515.       DatabaseOpened := True;
  516.       Result := True;
  517.     end;}
  518.   end;
  519. end;
  520.  
  521. function TAOraUpdateSQLEditForm.Edit: Boolean;
  522. var
  523.   Index: TUpdateKind;
  524.   DataSetName: string;
  525. begin
  526.   Result := False;
  527.   if Assigned(UpdateSQL.DataSet){ and (UpdateSQL.DataSet is TOraSQL)} then
  528.   begin
  529.     DataSet := TOraSQL(UpdateSQL.DataSet);
  530. //    FTempTable.SessionName := DataSet.SessionName;
  531.     FTempSQL.Database := DataSet.Database;
  532.     DataSetName := Format('%s%s%s', [DataSet.Owner.Name, DotSep, DataSet.Name]);
  533.   end else
  534.     DataSetName := SNoDataSet;
  535.   Caption := Format('%s%s%s (%s)', [UpdateSQL.Owner.Name, DotSep, UpdateSQL.Name, DataSetName]);
  536.   try
  537.     for Index := Low(TUpdateKind) to High(TUpdateKind) do
  538.     begin
  539.       SQLText[Index] := TStringList.Create;
  540.       SQLText[Index].Assign(UpdateSQL.SQL[Index]);
  541.     end;
  542.  
  543.     StatementTypeClick(Self);
  544.     InitUpdateTableNames;
  545.     ShowWait(InitGenerateOptions);
  546.     PageControl.ActivePage := PageControl.Pages[0];
  547.     if ShowModal = mrOk then
  548.     begin
  549.       for Index := low(TUpdateKind) to high(TUpdateKind) do
  550.         UpdateSQL.SQL[Index] := SQLText[Index];
  551.       Result := True;
  552.     end;
  553.   finally
  554.     for Index := Low(TUpdateKind) to High(TUpdateKind) do
  555.       SQLText[Index].Free;
  556.   end;
  557. end;
  558.  
  559. procedure TAOraUpdateSQLEditForm.GenWhereClause(const TabAlias, QuoteChar: string;
  560.   KeyFields, SQL: TStrings);
  561. var
  562.   I: Integer;
  563.   BindText: string;
  564.   FieldName: string;
  565. begin
  566.   SQL.Add('where'); { Do not localize }
  567.   for I := 0 to KeyFields.Count - 1 do
  568.   begin
  569.     FieldName := KeyFields[I];
  570.     BindText := Format('  %s%s%s%1:s = :%1:sOLD_%2:s%1:s', { Do not localize }
  571.       [TabAlias, QuoteChar, FieldName]);
  572.     if I < KeyFields.Count - 1 then
  573.       BindText := Format('%s and',[BindText]); { Do not localize }
  574.     SQL.Add(BindText);
  575.   end;
  576. end;
  577.  
  578. procedure TAOraUpdateSQLEditForm.GenDeleteSQL(const TableName, QuoteChar: string;
  579.   KeyFields, SQL: TStrings);
  580. begin
  581.   SQL.Clear;
  582.   SQL.Add(Format('delete from %s', [TableName])); { Do not localize }
  583.   GenWhereClause(GetTableRef(TableName, QuoteChar), QuoteChar, KeyFields, SQL);
  584. end;
  585.  
  586. procedure TAOraUpdateSQLEditForm.GenInsertSQL(const TableName, QuoteChar: string;
  587.   UpdateFields, SQL: TStrings);
  588.  
  589.   procedure GenFieldList(const TabName, ParamChar, QuoteChar: String);
  590.   var
  591.     L: string;
  592.     I: integer;
  593.     Comma: string;
  594.   begin
  595.     L := '  (';
  596.     Comma := ', ';
  597.     for I := 0 to UpdateFields.Count - 1 do
  598.     begin
  599.       if I = UpdateFields.Count - 1 then Comma := '';
  600.       L := Format('%s%s%s%s%s%3:s%5:s',
  601.         [L, TabName, ParamChar, QuoteChar, UpdateFields[I], Comma]);
  602.       if (Length(L) > 70) and (I <> UpdateFields.Count - 1) then
  603.       begin
  604.         SQL.Add(L);
  605.         L := '   ';
  606.       end;
  607.     end;
  608.     SQL.Add(L+')');
  609.   end;
  610.  
  611. begin
  612.   SQL.Clear;
  613.   SQL.Add(Format('insert into %s', [TableName])); { Do not localize }
  614.   GenFieldList(GetTableRef(TableName, QuoteChar), '', QuoteChar);
  615.   SQL.Add('values'); { Do not localize }
  616.   GenFieldList('', ':', QuoteChar);
  617. end;
  618.  
  619. procedure TAOraUpdateSQLEditForm.GenModifySQL(const TableName, QuoteChar: string;
  620.   KeyFields, UpdateFields, SQL: TStrings);
  621. var
  622.   I: integer;
  623.   Comma: string;
  624.   TableRef: string;
  625. begin
  626.   SQL.Clear;
  627.   SQL.Add(Format('update %s', [TableName]));  { Do not localize }
  628.   SQL.Add('set');                             { Do not localize }
  629.   Comma := ',';
  630.   TableRef := GetTableRef(TableName, QuoteChar);
  631.   for I := 0 to UpdateFields.Count - 1 do
  632.   begin
  633.     if I = UpdateFields.Count -1 then Comma := '';
  634.     SQL.Add(Format('  %s%s%s%1:s = :%1:s%2:s%1:s%3:s',
  635.       [TableRef, QuoteChar, UpdateFields[I], Comma]));
  636.   end;
  637.   GenWhereClause(TableRef, QuoteChar, KeyFields, SQL);
  638. end;
  639.  
  640. procedure TAOraUpdateSQLEditForm.GenerateSQL;
  641.  
  642.   function QuotedTableName(const BaseName: string): string;
  643.   begin
  644.     with UpdateTableName do
  645.       if ((ItemIndex <> -1) and (Items.Objects[ItemIndex] <> nil)) or
  646.          (DatabaseOpen {and not Database.IsSQLBased} and (Pos('.', BaseName) > 0)) then
  647.          Result := Format('"%s"', [BaseName]) else
  648.          Result := BaseName;
  649.   end;
  650.  
  651. var
  652.   KeyFields: TStringList;
  653.   UpdateFields: TStringList;
  654.   QuoteChar, TableName: string;
  655. begin
  656.   if (KeyFieldList.SelCount = 0) or (UpdateFieldList.SelCount = 0) then
  657.     raise Exception.CreateRes(@SSQLGenSelect);
  658.   KeyFields := TStringList.Create;
  659.   try
  660.     GetSelectedItems(KeyFieldList, KeyFields);
  661.     UpdateFields := TStringList.Create;
  662.     try
  663.       GetSelectedItems(UpdateFieldList, UpdateFields);
  664.       TableName := QuotedTableName(UpdateTableName.Text);
  665.       if QuoteFields.Checked then
  666.         QuoteChar := '"' else
  667.         QuoteChar := '';
  668.       GenDeleteSQL(TableName, QuoteChar, KeyFields, SQLText[ukDelete]);
  669.       GenInsertSQL(TableName, QuoteChar, UpdateFields, SQLText[ukInsert]);
  670.       GenModifySQL(TableName, QuoteChar, KeyFields, UpdateFields,
  671.         SQLText[ukModify]);
  672.       SQLMemo.Modified := False;
  673.       StatementTypeClick(Self);
  674.       PageControl.SelectNextPage(True);
  675.     finally
  676.       UpdateFields.Free;
  677.     end;
  678.   finally
  679.     KeyFields.Free;
  680.   end;
  681. end;
  682.  
  683. procedure TAOraUpdateSQLEditForm.GetDataSetFieldNames;
  684. begin
  685.   if Assigned(DataSet) then
  686.   begin
  687.     GetDataFieldNames(DataSet, DataSet.Name, KeyFieldList.Items);
  688.     UpdateFieldList.Items.Assign(KeyFieldList.Items);
  689.   end;
  690. end;
  691.  
  692. procedure TAOraUpdateSQLEditForm.GetTableFieldNames;
  693. begin
  694.   GetDataFieldNames(TempTable, UpdateTableName.Text {TempTable.TableName}, KeyFieldList.Items);
  695.   UpdateFieldList.Items.Assign(KeyFieldList.Items);
  696.   FDatasetDefaults := False;
  697. end;
  698.  
  699. function TAOraUpdateSQLEditForm.GetTableRef(const TabName, QuoteChar: string): string;
  700. begin
  701.   if QuoteChar <> '' then
  702.     Result :=  TabName + '.' else
  703.     REsult := '';
  704. end;
  705.  
  706. procedure TAOraUpdateSQLEditForm.InitGenerateOptions;
  707. var
  708.   UpdTabName: string;
  709.  
  710.   procedure InitFromDataSet;
  711.   begin
  712.     // If this is a Query with more than 1 table in the "from" clause then
  713.     //  initialize the list of fields from the table rather than the dataset.
  714.     if (UpdateTableName.Items.Count > 1) then
  715.       GetTableFieldNames
  716.     else
  717.     begin
  718.       GetDataSetFieldNames;
  719.       FDatasetDefaults := True;
  720.     end;
  721.     SetDefaultSelections;
  722.   end;
  723.  
  724.   procedure InitFromUpdateSQL;
  725.   var
  726.     UpdFields,
  727.     WhFields: TStrings;
  728.   begin
  729.     UpdFields := TStringList.Create;
  730.     try
  731.       WhFields := TStringList.Create;
  732.       try
  733.         ParseUpdateSQL(SQLText[ukModify].Text, UpdTabName, UpdFields, WhFields);
  734.         GetDataSetFieldNames;
  735.         if SetSelectedItems(UpdateFieldList, UpdFields) < 1 then
  736.           SelectAll(UpdateFieldList);
  737.         if SetSelectedItems(KeyFieldList, WhFields) < 1 then
  738.           SelectAll(KeyFieldList);
  739.       finally
  740.         WhFields.Free;
  741.       end;
  742.     finally
  743.       UpdFields.Free;
  744.     end;
  745.   end;
  746.  
  747. begin
  748.   // If there are existing update SQL statements, try to initialize the
  749.   // dialog with the fields that correspond to them.
  750.   if SQLText[ukModify].Count > 0 then
  751.   begin
  752.     ParseUpdateSQL(SQLText[ukModify].Text, UpdTabName, nil, nil);
  753.     // If the table name from the update statement is not part of the
  754.     // dataset, then initialize from the dataset instead.
  755.     if (UpdateTableName.Items.Count > 0) and
  756.        (UpdateTableName.Items.IndexOf(UpdTabName) > -1) then
  757.     begin
  758.       UpdateTableName.Text := UpdTabName;
  759.       InitFromUpdateSQL;
  760.     end else
  761.     begin
  762.       InitFromDataSet;
  763.       UpdateTableName.Items.Add(UpdTabName);
  764.     end;
  765.   end else
  766.     InitFromDataSet;
  767.   SetButtonStates;
  768. end;
  769.  
  770. procedure TAOraUpdateSQLEditForm.InitUpdateTableNames;
  771. begin
  772.   UpdateTableName.Items.Clear;
  773.   if Assigned(DataSet) then
  774.   begin
  775. //    if DataSet is TQuery then
  776.       GetSQLTableNames(TOraSQL(DataSet).SQL.Text, UpdateTableName.Items)
  777. //    else if (DataSet is TTable) and (TTable(DataSet).TableName <> '') then
  778. //      UpdateTableName.Items.Add(TTable(DataSet).TableName);
  779.   end;
  780.   if UpdateTableName.Items.Count > 0 then
  781.      UpdateTableName.ItemIndex := 0;
  782. end;
  783.  
  784. procedure TAOraUpdateSQLEditForm.SetButtonStates;
  785. begin
  786.   GetTableFieldsButton.Enabled := UpdateTableName.Text <> '';
  787.   PrimaryKeyButton.Enabled := GetTableFieldsButton.Enabled and
  788.     (KeyFieldList.Items.Count > 0);
  789.   GenerateButton.Enabled := GetTableFieldsButton.Enabled and
  790.     (UpdateFieldList.Items.Count > 0) and (KeyFieldList.Items.Count > 0);
  791.   DefaultButton.Enabled := Assigned(DataSet) and not FDatasetDefaults;
  792. end;
  793.  
  794. procedure TAOraUpdateSQLEditForm.SelectPrimaryKeyFields;
  795. var
  796.   SepPos, I, Index: Integer;
  797.   FName, FieldNames: string;
  798. begin
  799.   if KeyFieldList.Items.Count < 1 then Exit;
  800. {  with TempTable do
  801.   begin
  802.     IndexDefs.Update;
  803.     for I := 0 to KeyFieldList.Items.Count - 1  do
  804.       KeyFieldList.Selected[I] := False;
  805.     for I := 0 to IndexDefs.Count - 1  do
  806.       if ixPrimary in IndexDefs[I].Options then
  807.       begin
  808.         FieldNames := IndexDefs[I].Fields + ';';
  809.         while Length(FieldNames) > 0 do
  810.         begin
  811.           SepPos := Pos(';', FieldNames);
  812.           if SepPos < 1 then Break;
  813.           FName := Copy(FieldNames, 1, SepPos - 1);
  814.           System.Delete(FieldNames, 1, SepPos);
  815.           Index := KeyFieldList.Items.IndexOf(FName);
  816.           if Index > -1 then KeyFieldList.Selected[Index] := True;
  817.         end;
  818.         break;
  819.       end;
  820.   end;}
  821. end;
  822.  
  823. procedure TAOraUpdateSQLEditForm.SetDefaultSelections;
  824. var
  825.   DSFields: TStringList;
  826. begin
  827.   if FDatasetDefaults or not Assigned(DataSet) then
  828.   begin
  829.     SelectAll(UpdateFieldList);
  830.     SelectAll(KeyFieldList);
  831.   end
  832.   else if (DataSet.FieldDefs.Count > 0) then
  833.   begin
  834.     DSFields := TStringList.Create;
  835.     try
  836.       GetDataFieldNames(DataSet, '', DSFields);
  837.       SetSelectedItems(KeyFieldList, DSFields);
  838.       SetSelectedItems(UpdateFieldList, DSFields);
  839.     finally
  840.       DSFields.Free;
  841.     end;
  842.   end;
  843. end;
  844.  
  845. procedure TAOraUpdateSQLEditForm.ShowWait(WaitMethod: TWaitMethod);
  846. begin
  847.   Screen.Cursor := crHourGlass;
  848.   try
  849.     WaitMethod;
  850.   finally
  851.     Screen.Cursor := crDefault;
  852.   end;
  853. end;
  854.  
  855. function TAOraUpdateSQLEditForm.TempTable: TOraSQL;
  856. var s:string;
  857. begin
  858.   s:=Format('SELECT * FROM %s',[UpdateTableName.Text]);
  859.   if FTempSQL.SQL.Text <> s then begin
  860.     FTempSQL.Close;
  861.     FTempSQL.SQL.Text := s;
  862.   end;
  863.   Result := FTempSQL;
  864. {  if FTempTable.TableName <> UpdateTableName.Text then
  865.   begin
  866.     FTempTable.Close;
  867.     FTempTable.TableName := UpdateTableName.Text;
  868.   end;
  869.   Result := FTempTable;}
  870. end;
  871.  
  872. { Event Handlers }
  873.  
  874. procedure TAOraUpdateSQLEditForm.FormCreate(Sender: TObject);
  875. begin
  876.   HelpContext := hcDUpdateSQL;
  877. end;
  878.  
  879. procedure TAOraUpdateSQLEditForm.HelpButtonClick(Sender: TObject);
  880. begin
  881.   Application.HelpContext(HelpContext);
  882. end;
  883.  
  884. procedure TAOraUpdateSQLEditForm.StatementTypeClick(Sender: TObject);
  885. begin
  886.   if SQLMemo.Modified then
  887.     SQLText[TUpdateKind(StmtIndex)].Assign(SQLMemo.Lines);
  888.   StmtIndex := StatementType.ItemIndex;
  889.   SQLMemo.Lines.Assign(SQLText[TUpdateKind(StmtIndex)]);
  890. end;
  891.  
  892. procedure TAOraUpdateSQLEditForm.OkButtonClick(Sender: TObject);
  893. begin
  894.   if SQLMemo.Modified then
  895.     SQLText[TUpdateKind(StmtIndex)].Assign(SQLMemo.Lines);
  896. end;
  897.  
  898. procedure TAOraUpdateSQLEditForm.DefaultButtonClick(Sender: TObject);
  899. begin
  900.   with UpdateTableName do
  901.     if Items.Count > 0 then ItemIndex := 0;
  902.   ShowWait(GetDataSetFieldNames);
  903.   FDatasetDefaults := True;
  904.   SetDefaultSelections;
  905.   KeyfieldList.SetFocus;
  906.   SetButtonStates;
  907. end;
  908.  
  909. procedure TAOraUpdateSQLEditForm.GenerateButtonClick(Sender: TObject);
  910. begin
  911.   GenerateSQL;
  912.   FSettingsChanged := False;
  913. end;
  914.  
  915. procedure TAOraUpdateSQLEditForm.PrimaryKeyButtonClick(Sender: TObject);
  916. begin
  917.   ShowWait(SelectPrimaryKeyFields);
  918.   SettingsChanged(Sender);
  919. end;
  920.  
  921. procedure TAOraUpdateSQLEditForm.PageControlChanging(Sender: TObject;
  922.   var AllowChange: Boolean);
  923. begin
  924.   if (PageControl.ActivePage = PageControl.Pages[0]) and
  925.     not SQLPage.Enabled then
  926.     AllowChange := False;
  927. end;
  928.  
  929. procedure TAOraUpdateSQLEditForm.FormDestroy(Sender: TObject);
  930. begin
  931.   if DatabaseOpened then
  932. //    Database.Session.CloseDatabase(Database);
  933.    Database.Close;
  934. end;
  935.  
  936. procedure TAOraUpdateSQLEditForm.GetTableFieldsButtonClick(Sender: TObject);
  937. begin
  938.   ShowWait(GetTableFieldNames);
  939.   SetDefaultSelections;
  940.   SettingsChanged(Sender);
  941. end;
  942.  
  943. procedure TAOraUpdateSQLEditForm.SettingsChanged(Sender: TObject);
  944. begin
  945.   FSettingsChanged := True;
  946.   FDatasetDefaults := False;
  947.   SetButtonStates;
  948. end;
  949.  
  950. procedure TAOraUpdateSQLEditForm.FormCloseQuery(Sender: TObject;
  951.   var CanClose: Boolean);
  952. begin
  953.   if (ModalResult = mrOK) and FSettingsChanged then
  954.     CanClose := MessageDlg(SSQLNotGenerated, mtConfirmation,
  955.       mbYesNoCancel, 0) = mrYes;
  956. end;
  957.  
  958. procedure TAOraUpdateSQLEditForm.UpdateTableNameChange(Sender: TObject);
  959. begin
  960.   SettingsChanged(Sender);
  961. end;
  962.  
  963. procedure TAOraUpdateSQLEditForm.UpdateTableNameClick(Sender: TObject);
  964. begin
  965.   if not Visible then Exit;
  966.   GetTableFieldsButtonClick(Sender);
  967. end;
  968.  
  969. procedure TAOraUpdateSQLEditForm.SelectAllClick(Sender: TObject);
  970. begin
  971.   SelectAll(FieldListPopup.PopupComponent as TListBox);
  972. end;
  973.  
  974. procedure TAOraUpdateSQLEditForm.ClearAllClick(Sender: TObject);
  975. var
  976.   I: Integer;
  977. begin
  978.   with FieldListPopup.PopupComponent as TListBox do
  979.   begin
  980.     Items.BeginUpdate;
  981.     try
  982.       for I := 0 to Items.Count - 1 do
  983.         Selected[I] := False;
  984.     finally
  985.       Items.EndUpdate;
  986.     end;
  987.   end;
  988. end;
  989.  
  990. procedure TAOraUpdateSQLEditForm.SQLMemoKeyPress(Sender: TObject;
  991.   var Key: Char);
  992. begin
  993.   if Key = #27 then Close;
  994. end;
  995.  
  996. end.
  997.