home *** CD-ROM | disk | FTP | other *** search
/ Delphi 5 for Professionals / DELPHI5.iso / Runimage / Delphi50 / Demos / Midas / Alchtest / alchmain.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1999-08-11  |  69.6 KB  |  2,357 lines

  1. unit AlchMain;
  2.  
  3. { Test program for Client DataSets }
  4.  
  5. interface
  6.  
  7. uses
  8.   Windows, Sysutils, Forms, IniFiles, DBTables, ImgList, Controls, Classes,
  9.   ActnList, Menus, Dialogs, Provider, DBClient, Db, ComCtrls, ToolWin,
  10.   Grids, DBGrids, ExtCtrls, DBCtrls, StdCtrls, Buttons;
  11.   
  12. type
  13.   TDBClientTest = class(TForm)
  14.  
  15.     { DB Controls }
  16.     Database1: TDatabase;
  17.     DetailQuery: TQuery;
  18.     MasterQuery: TQuery;
  19.     DetailTable: TTable;
  20.     MasterTable: TTable;
  21.     NestedTable: TNestedTable;
  22.     BDEProvider: TProvider;
  23.     DeltaSet: TClientDataSet;
  24.     ResultSet: TClientDataSet;
  25.     ClientData: TClientDataSet;
  26.     DetailDataSet: TClientDataSet;
  27.     MasterDataSource: TDataSource;
  28.     DetailMasterSource: TDataSource;
  29.     DetailDataSource: TDataSource;
  30.     DetailQuerySource: TDataSource;
  31.     DetailGrid: TDBGrid;
  32.     MasterGrid: TDBGrid;
  33.     DBMemo1: TDBMemo;
  34.     DBImage1: TDBImage;
  35.  
  36.     { Actions }
  37.     ActionList1: TActionList;
  38.     SaveDataPacket: TAction;
  39.     GetSavePoint: TAction;
  40.     RevertToSavepoint: TAction;
  41.     OpenQuery: TAction;
  42.     OpenTable: TAction;
  43.     ApplyUpdates: TAction;
  44.     MergeChangeLog: TAction;
  45.     ExitApplication: TAction;
  46.     CloseActiveDataSet: TAction;
  47.     LoadDataPacket: TAction;
  48.     RequestLiveQuery: TAction;
  49.     SparseArrays: TAction;
  50.     ObjectView: TAction;
  51.     EnableBCD: TAction;
  52.     ResolveToDataSet: TAction;
  53.     DisableProvider: TAction;
  54.     FetchOnDemand: TAction;
  55.     poCascadedDeletes: TAction;
  56.     poCascadedUpdates: TAction;
  57.     poDelayedDetails: TAction;
  58.     poDelayedBlobs: TAction;
  59.     poIncludeFieldProps: TAction;
  60.     poReadOnly: TAction;
  61.     CancelUpdates: TAction;
  62.     LogChanges: TAction;
  63.     ExecuteQuery: TAction;
  64.     StreamFormOut: TAction;
  65.     StreamFormIn: TAction;
  66.     UndoLastEdit: TAction;
  67.     RevertRecord: TAction;
  68.     ClearField: TAction;
  69.     GetNextPacket: TAction;
  70.     SetMaxErrors: TAction;
  71.     SetPacketRecords: TAction;
  72.     ViewEvents: TAction;
  73.     ClearPasswords: TAction;
  74.     PrevQuery: TAction;
  75.     NextQuery: TAction;
  76.     RefreshData: TAction;
  77.     ClearEventLog: TAction;
  78.     IncludeNestedObject: TAction;
  79.     DisplayDetails: TAction;
  80.     SetRefTableName: TAction;
  81.     HelpAbout: TAction;
  82.  
  83.     { Other Controls }
  84.     MainMenu1: TMainMenu;
  85.     FileReopen: TMenuItem;
  86.     FileMenu: TMenuItem;
  87.     PopupMenu1: TPopupMenu;
  88.     ToolBar1: TToolBar;
  89.     ImageList1: TImageList;
  90.     OpenDialog: TOpenDialog;
  91.     SaveDialog: TSaveDialog;
  92.     StatusBar: TStatusBar;
  93.     AreaSelector: TPageControl;
  94.     DataSetSelector: TTabControl;
  95.     FilterPage: TTabSheet;
  96.     FindKeyPage: TTabSheet;
  97.     LocatePage: TTabSheet;
  98.     CreatePage: TTabSheet;
  99.     IndexPage: TTabSheet;
  100.     FieldsPage: TTabSheet;
  101.     ProviderPage: TTabSheet;
  102.     IndexList: TListBox;
  103.     FieldList: TMemo;
  104.     FieldDefList: TMemo;
  105.     NavigatorPanel: TPanel;
  106.     BlobCtrlPanel: TPanel;
  107.     GridPanel: TPanel;
  108.     DBNavigator1: TDBNavigator;
  109.     foCaseInsensitive: TCheckBox;
  110.     foNoPartialCompare: TCheckBox;
  111.     idxDescending: TCheckBox;
  112.     idxCaseInsensitive: TCheckBox;
  113.     Filter: TEdit;
  114.     FindFirst: TButton;
  115.     FindNext: TButton;
  116.     Filtered: TCheckBox;
  117.     IndexFields: TEdit;
  118.     KeyFieldList: TLabel;
  119.     PrevQuery1: TSpeedButton;
  120.     CreateDataSetDesc: TComboBox;
  121.     Events: TListBox;
  122.     CreateFieldList: TListBox;
  123.     CreateFieldType: TComboBox;
  124.     UpDown1: TUpDown;
  125.     CreateFieldSize: TEdit;
  126.     CreateFieldParent: TComboBox;
  127.     CreateFieldRequired: TCheckBox;
  128.     AddFieldButton: TButton;
  129.     DataRows: TEdit;
  130.     SparseArrays2: TCheckBox;
  131.     ObjectView2: TCheckBox;
  132.     MixedData: TCheckBox;
  133.     DescFields: TEdit;
  134.     CaseInsFields: TEdit;
  135.     idxPrimary: TCheckBox;
  136.     idxUnique: TCheckBox;
  137.     StatusFilterBox: TGroupBox;
  138.     DatabaseName: TComboBox;
  139.     ModifiedRecords: TCheckBox;
  140.     InsertedRecords: TCheckBox;
  141.     DeletedRecords: TCheckBox;
  142.     MasterTableName: TComboBox;
  143.     DetailTableName: TComboBox;
  144.     MasterSQL: TMemo;
  145.     DetailSQL: TMemo;
  146.     GridSplitter: TSplitter;
  147.     TestButton1: TButton;
  148.     ToolButton1: TToolButton;
  149.     FindKey: TButton;
  150.     FindNearest: TButton;
  151.     FindValue: TEdit;
  152.     LocateEdit: TEdit;
  153.     KeyExclusive: TCheckBox;
  154.     FindPartial: TCheckBox;
  155.     LocateField: TComboBox;
  156.     locCaseInsensitive: TCheckBox;
  157.     locPartialKey: TCheckBox;
  158.     LocateNull: TCheckBox;
  159.     XMLDataPackets: TAction;
  160.     UseXMLDataPackets1: TMenuItem;
  161.     
  162.     procedure FilterKeyPress(Sender: TObject; var Key: Char);
  163.     procedure FormCreate(Sender: TObject);
  164.     procedure FormDestroy(Sender: TObject);
  165.     procedure MasterSQLKeyPress(Sender: TObject; var Key: Char);
  166.     procedure IndexListClick(Sender: TObject);
  167.     procedure GridTitleClick(Column: TColumn);
  168.     procedure CreateIndexClick(Sender: TObject);
  169.     procedure LocateButtonClick(Sender: TObject);
  170.     procedure FindFirstClick(Sender: TObject);
  171.     procedure FilterExit(Sender: TObject);
  172.     procedure DataSourceDataChange(Sender: TObject; Field: TField);
  173.     procedure DataSetSelectorChange(Sender: TObject);
  174.     procedure ClientDataAfterOpen(DataSet: TDataSet);
  175.     procedure LocateFieldDropDown(Sender: TObject);
  176.     procedure DeleteIndexClick(Sender: TObject);
  177.     procedure FindKeyClick(Sender: TObject);
  178.     procedure SetFilterOptions(Sender: TObject);
  179.     procedure FindNextClick(Sender: TObject);
  180.     procedure ClientDataReconcileError(DataSet: TClientDataSet;
  181.       E: EReconcileError; UpdateKind: TUpdateKind;
  182.       var Action: TReconcileAction);
  183.     procedure MasterTableNameClick(Sender: TObject);
  184.     procedure PopupMenu1Popup(Sender: TObject);
  185.     procedure FieldSelect(Sender: TObject);
  186.     procedure GridColEnter(Sender: TObject);
  187.     procedure StreamFormInExecute(Sender: TObject);
  188.     procedure StreamFormOutExecute(Sender: TObject);
  189.     procedure LoadDatapacket1Click(Sender: TObject);
  190.     procedure SaveDataPacketExecute(Sender: TObject);
  191.     procedure GetSavePointExecute(Sender: TObject);
  192.     procedure EditActionsUpdate(Sender: TObject);
  193.     procedure RevertToSavepointExecute(Sender: TObject);
  194.     procedure FieldsPageShow(Sender: TObject);
  195.     procedure ClientDataAfterClose(DataSet: TDataSet);
  196.     procedure OpenQueryExecute(Sender: TObject);
  197.     procedure OpenTableExecute(Sender: TObject);
  198.     procedure ApplyUpdatesExecute(Sender: TObject);
  199.     procedure ProviderDataSetAfterOpen(DataSet: TDataSet);
  200.     procedure MasterTableNameDropDown(Sender: TObject);
  201.     procedure DatabaseNameDropDown(Sender: TObject);
  202.     procedure DatabaseNameClick(Sender: TObject);
  203.     procedure DatabaseNameKeyPress(Sender: TObject; var Key: Char);
  204.     procedure DataSetBeforeOpen(DataSet: TDataSet);
  205.     procedure FilteredClick(Sender: TObject);
  206.     procedure CreateDataSetDescClick(Sender: TObject);
  207.     procedure CreateDataSetDescKeyPress(Sender: TObject; var Key: Char);
  208.     procedure CreateFieldListClick(Sender: TObject);
  209.     procedure CreateClientData(Sender: TObject);
  210.     procedure CreatePageShow(Sender: TObject);
  211.     procedure AddFieldButtonClick(Sender: TObject);
  212.     procedure CreateFieldParentDropDown(Sender: TObject);
  213.     procedure MergeChangeLogExecute(Sender: TObject);
  214.     procedure FilterPageShow(Sender: TObject);
  215.     procedure IndexPageShow(Sender: TObject);
  216.     procedure ExitApplicationExecute(Sender: TObject);
  217.     procedure CloseActiveDataSetExecute(Sender: TObject);
  218.     procedure FileActionsUpdate(Sender: TObject);
  219.     procedure StatusFilterClick(Sender: TObject);
  220.     procedure MasterTableNameKeyPress(Sender: TObject; var Key: Char);
  221.     procedure DetailTableNameClick(Sender: TObject);
  222.     procedure MasterTableAfterOpen(DataSet: TDataSet);
  223.     procedure MasterTableBeforeClose(DataSet: TDataSet);
  224.     procedure GridSetFocus(Sender: TObject);
  225.     procedure LocatePageShow(Sender: TObject);
  226.     procedure LocateNullClick(Sender: TObject);
  227.     function BDEProviderDataRequest(Sender: TObject;
  228.       Input: OleVariant): OleVariant;
  229.     procedure BDEProviderGetData(Sender: TObject; DataSet: TClientDataSet);
  230.     procedure BDEProviderUpdateData(Sender: TObject;
  231.       DataSet: TClientDataSet);
  232.     procedure BDEProviderUpdateError(Sender: TObject;
  233.       DataSet: TClientDataSet; E: EUpdateError; UpdateKind: TUpdateKind;
  234.       var Response: TResolverResponse);
  235.     procedure ClientDataAfterScroll(DataSet: TDataSet);
  236.     procedure ClientDataBeforeCancel(DataSet: TDataSet);
  237.     procedure ClientDataBeforeDelete(DataSet: TDataSet);
  238.     procedure ClientDataBeforeEdit(DataSet: TDataSet);
  239.     procedure ClientDataBeforeInsert(DataSet: TDataSet);
  240.     procedure ClientDataBeforePost(DataSet: TDataSet);
  241.     procedure ClientDataBeforeScroll(DataSet: TDataSet);
  242.     procedure ClientDataCalcFields(DataSet: TDataSet);
  243.     procedure ClientDataDeleteError(DataSet: TDataSet; E: EDatabaseError;
  244.       var Action: TDataAction);
  245.     procedure ClientDataNewRecord(DataSet: TDataSet);
  246.     procedure ClientDataAfterPost(DataSet: TDataSet);
  247.     procedure ClientDataAfterInsert(DataSet: TDataSet);
  248.     procedure ClientDataAfterEdit(DataSet: TDataSet);
  249.     procedure ClientDataAfterDelete(DataSet: TDataSet);
  250.     procedure ClientDataAfterCancel(DataSet: TDataSet);
  251.     procedure BDEProviderGetDataSetProperties(Sender: TObject;
  252.       DataSet: TDataSet; out Properties: OleVariant);
  253.     procedure MasterQueryAfterOpen(DataSet: TDataSet);
  254.     procedure MasterQueryBeforeClose(DataSet: TDataSet);
  255.     procedure CancelUpdatesExecute(Sender: TObject);
  256.     procedure ApplyUpdatesUpdate(Sender: TObject);
  257.     procedure LogChangesExecute(Sender: TObject);
  258.     procedure UndoLastEditExecute(Sender: TObject);
  259.     procedure RevertRecordExecute(Sender: TObject);
  260.     procedure ClearFieldExecute(Sender: TObject);
  261.     procedure GetNextPacketExecute(Sender: TObject);
  262.     procedure SetMaxErrorsExecute(Sender: TObject);
  263.     procedure SetPacketRecordsExecute(Sender: TObject);
  264.     procedure ViewEventsExecute(Sender: TObject);
  265.     procedure BDEProviderAfterUpdateRecord(Sender: TObject;
  266.       SourceDS: TDataSet; DeltaDS: TClientDataSet;
  267.       UpdateKind: TUpdateKind);
  268.     procedure BDEProviderBeforeUpdateRecord(Sender: TObject;
  269.       SourceDS: TDataSet; DeltaDS: TClientDataSet; UpdateKind: TUpdateKind;
  270.       var Applied: Boolean);
  271.     procedure CreateFieldTypeDropDown(Sender: TObject);
  272.     procedure CreateFieldTypeChange(Sender: TObject);
  273.     procedure CreateFieldSizeChange(Sender: TObject);
  274.     procedure SetRefTableNameExecute(Sender: TObject);
  275.     procedure NestedTableBeforeInsert(DataSet: TDataSet);
  276.     procedure DataSourceStateChange(Sender: TObject);
  277.     procedure DataSourceUpdateData(Sender: TObject);
  278.     procedure RefreshDataExecute(Sender: TObject);
  279.     procedure ClearEventLogExecute(Sender: TObject);
  280.     procedure ClearEventLogUpdate(Sender: TObject);
  281.     procedure HelpAboutExecute(Sender: TObject);
  282.     procedure FindKeyPageInit(Sender: TObject);
  283.     procedure DataSetAfterClose(DataSet: TDataSet);
  284.     procedure ClearPasswordsExecute(Sender: TObject);
  285.     procedure MasterTableAfterClose(DataSet: TDataSet);
  286.     procedure FileMenuClick(Sender: TObject);
  287.     procedure ClosedFileClick(Sender: TObject);
  288.     procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  289.     procedure PrevQueryExecute(Sender: TObject);
  290.     procedure PrevQueryUpdate(Sender: TObject);
  291.     procedure NextQueryExecute(Sender: TObject);
  292.     procedure MasterTableAfterScroll(DataSet: TDataSet);
  293.     procedure MasterTableBeforeScroll(DataSet: TDataSet);
  294.     procedure BinaryGetText(Sender: TField; var Text: string;
  295.       DisplayText: Boolean);
  296.     procedure BinarySetText(Sender: TField; const Text: string);
  297.     procedure TestButton1Click(Sender: TObject);
  298.     procedure BooleanActionExecute(Sender: TObject);
  299.     procedure EnableBCDExecute(Sender: TObject);
  300.   private
  301.     FConfig: TIniFile;
  302.     FMaxErrors: Integer;
  303.     FPacketRecs: Integer;
  304.     FSavePoint: Integer;
  305.     FActiveDataSet: TDataSet;
  306.     FActiveDataSource: TDataSource;
  307.     FRefTabName: string;
  308.     FStatusMsg: string;
  309.     FClosedTables: TStringList;
  310.     FMasterQueries: TStringList;
  311.     FDetailQueries: TStringList;
  312.     FQueryIndex: Integer;
  313.     function GetConfigFile: TIniFile;
  314.     function FilterOptions: TFilterOptions;
  315.     procedure InsertData(DataSet: TDataSet; Rows,Start: Integer);
  316.     procedure RefreshIndexNames(NewItemIndex: Integer);
  317.     procedure SetEventsVisible(Visible: Boolean);
  318.     procedure SetProviderOptions;
  319.     procedure SetQueryText;
  320.     procedure SetStatusMsg(const Msg: string);
  321.     procedure ShowHeapStatus(Sender: TObject; var Done: Boolean);
  322.     procedure ShowIndexParams;
  323.     procedure UpdateFieldList;
  324.     procedure UpdateReOpenMenu;
  325.     procedure OnHint(Sender: TObject);
  326.   public
  327.     procedure BindControls(DataSet: TDataSet);
  328.     procedure CheckDatabase(CloseFirst: Boolean);
  329.     procedure OpenDataSet(Source: TDBDataSet);
  330.     procedure SetActiveDataSet(Value: TDataSet);
  331.     procedure StreamSettings(Write: Boolean);
  332.     procedure LogEvent(const EventStr: string; Component: TComponent = nil);
  333.     property StatusMsg: string read FStatusMsg write SetStatusMsg;
  334.     property ActiveDataSet: TDataSet read FActiveDataSet write SetActiveDataSet;
  335.     property ActiveDataSource: TDataSource read FActiveDataSource write FActiveDataSource;
  336.     property ConfigFile: TIniFile read GetConfigFile;
  337.   end;
  338.  
  339. var
  340.   DBClientTest: TDBClientTest;
  341.  
  342. implementation
  343.  
  344. uses DBLogDlg, BDE, RecError;
  345.  
  346. {$R *.DFM}
  347.  
  348. procedure TDBClientTest.FormCreate(Sender: TObject);
  349. var
  350.   I: Integer;
  351. begin
  352.   Database1.Close;
  353.   FMaxErrors := -1;
  354.   FPacketRecs := -1;
  355.   ActiveDataSource := MasterDataSource;
  356.   SetCurrentDirectory(PChar(ExtractFilePath(ParamStr(0))));
  357.   for I := 0 to StatusBar.Panels.Count - 1 do
  358.     StatusBar.Panels[I].Text := '';
  359.   Application.OnIdle := ShowHeapStatus;
  360.   Application.OnHint := OnHint;
  361.   FClosedTables := TStringList.Create;
  362.   FMasterQueries := TStringList.Create;
  363.   FDetailQueries := TStringList.Create;
  364.   StreamSettings(False);
  365.   SetEventsVisible(ViewEvents.Checked);
  366. end;
  367.  
  368. procedure TDBClientTest.FormDestroy(Sender: TObject);
  369. begin
  370.   if Assigned(FConfig) then
  371.     StreamSettings(True);
  372.   FConfig.Free;
  373.   FDetailQueries.Free;
  374.   FMasterQueries.Free;
  375.   FClosedTables.Free;
  376. end;
  377.  
  378. procedure TDBClientTest.ExitApplicationExecute(Sender: TObject);
  379. begin
  380.   Application.Terminate;
  381. end;
  382.  
  383. procedure TDBClientTest.HelpAboutExecute(Sender: TObject);
  384. begin
  385.   ShowMessage('Client DataSet Test Application'#13#10+
  386.               'Copyright (c) 1998 Inprise Corporation');
  387. end;
  388.  
  389. procedure TDBClientTest.OnHint(Sender: TObject);
  390. begin
  391.   StatusMsg := Application.Hint;
  392. end;
  393.  
  394. { View Options }
  395.  
  396. procedure TDBClientTest.SetEventsVisible(Visible: Boolean);
  397. var
  398.   EventsWidth: Integer;
  399. begin
  400.   if Events.Visible = Visible then Exit;
  401.   DisableAlign;
  402.   try
  403.     Events.Visible := Visible;
  404.     EventsWidth := Events.Width + 10;
  405.     if not Visible then
  406.       EventsWidth := -EventsWidth;
  407.     ClientWidth := ClientWidth + EventsWidth;
  408.   finally
  409.     DataSetSelector.ControlState := DataSetSelector.ControlState - [csAlignmentNeeded];
  410.     AreaSelector.ControlState := AreaSelector.ControlState - [csAlignmentNeeded];
  411.     EnableAlign;
  412.   end;
  413. end;
  414.  
  415. procedure TDBClientTest.ViewEventsExecute(Sender: TObject);
  416. begin
  417.   ViewEvents.Checked := not ViewEvents.Checked;
  418.   SetEventsVisible(ViewEvents.Checked);
  419. end;
  420.  
  421. { Settings }
  422.  
  423. function TDBClientTest.GetConfigFile: TIniFile;
  424. begin
  425.   if FConfig = nil then
  426.     FConfig := TIniFile.Create(ChangeFileExt(ParamStr(0), '.INI'));
  427.   Result := FConfig;
  428. end;
  429.  
  430. procedure TDBClientTest.StreamSettings(Write: Boolean);
  431.  
  432.   procedure WriteStr(const OptName, Value: string);
  433.   begin
  434.     FConfig.WriteString('Settings', OptName, Value);
  435.   end;
  436.  
  437.   procedure WriteBool(const OptName: string; Value: Boolean);
  438.   begin
  439.     FConfig.WriteBool('Settings', OptName, Value);
  440.   end;
  441.  
  442.   procedure WriteStrings(const SectName: string; Values: TStrings);
  443.   var
  444.     I: Integer;
  445.   begin
  446.     FConfig.EraseSection(SectName);
  447.     for I := 0 to Values.Count - 1 do
  448.       FConfig.WriteString(SectName, IntToStr(I), Values[I]);
  449.   end;
  450.  
  451.   function ReadStr(const OptName: string): string;
  452.   begin
  453.     Result := FConfig.ReadString('Settings', OptName, '');
  454.   end;
  455.  
  456.   function ReadBool(const OptName: string): Boolean;
  457.   begin
  458.     Result := FConfig.ReadBool('Settings', OptName, False);
  459.   end;
  460.  
  461.   procedure ReadStrings(const SectName: string; Values: TStrings);
  462.   var
  463.     I: Integer;
  464.   begin
  465.     FConfig.ReadSectionValues(SectName, Values);
  466.     { Strip off the 0=, 1=, etc parts }
  467.     for I := 0 to Values.Count - 1 do
  468.       Values[I] := Copy(Values[I], 3, MAXINT);
  469.   end;
  470.  
  471.   function FindPage(const PageName: string): TTabSheet;
  472.   var
  473.     I: Integer;
  474.   begin
  475.     for I := AreaSelector.PageCount - 1 downto 0 do
  476.     begin
  477.       Result := AreaSelector.Pages[I];
  478.       if Result.Caption = PageName then Exit;
  479.     end;
  480.     Result := ProviderPage;
  481.   end;
  482.  
  483.   procedure ProcessComponents(Components: array of TComponent);
  484.   var
  485.     I: Integer;
  486.   begin
  487.     if Write then
  488.     begin
  489.       for I := Low(Components) to High(Components) do
  490.         if Components[I] is TCustomEdit then
  491.           with TEdit(Components[I]) do
  492.             WriteStr(Name, Text)
  493.         else if Components[I] is TComboBox then
  494.           with TDBComboBox(Components[I]) do
  495.             WriteStr(Name, Text)
  496.         else if Components[I] is TCheckBox then
  497.           with TCheckBox(Components[I]) do
  498.             WriteBool(Name, Checked)
  499.         else if Components[I] is TAction then
  500.           with TAction(Components[I]) do
  501.             WriteBool(Name, Checked)
  502.         else if Components[I] is TPageControl then
  503.           with TPageControl(Components[I]) do
  504.             WriteStr(Name, ActivePage.Caption);
  505.     end
  506.     else
  507.     begin
  508.       for I := Low(Components) to High(Components) do
  509.         if Components[I] is TCustomEdit then
  510.           with TEdit(Components[I]) do
  511.             Text := ReadStr(Name)
  512.         else if Components[I] is TComboBox then
  513.           with TComboBox(Components[I]) do
  514.             Text := ReadStr(Name)
  515.         else if Components[I] is TCheckBox then
  516.           with TCheckBox(Components[I]) do
  517.             Checked := ReadBool(Name)
  518.         else if Components[I] is TAction then
  519.           with TAction(Components[I]) do
  520.             Checked := ReadBool(Name)
  521.         else if Components[I] is TPageControl then
  522.           with TPageControl(Components[I]) do
  523.             ActivePage := FindPage(ReadStr(Name));
  524.     end;
  525.   end;
  526.  
  527. begin
  528.   GetConfigFile;
  529.   if not Write and (ReadStr('AreaSelector') = '') then Exit;
  530.   ProcessComponents([AreaSelector, DatabaseName, MasterTableName,
  531.     DetailTableName, MasterSQL, DetailSQL, poCascadedDeletes, poCascadedUpdates,
  532.     poDelayedDetails, poDelayedBlobs, poIncludeFieldProps, poReadOnly,
  533.     DisableProvider, ObjectView, SparseArrays, MixedData, FetchOnDemand,
  534.     DisableProvider, ResolveToDataSet, DataRows, CreateDataSetDesc,
  535.     EnableBCD, RequestLiveQuery, ViewEvents, DisplayDetails,
  536.     IncludeNestedObject, XMLDataPackets]);
  537.   if Write then
  538.   begin
  539.     WriteStrings('ClosedTables', FClosedTables);
  540.     WriteStrings('MasterQueries', FMasterQueries);
  541.     WriteStrings('DetailQueries', FDetailQueries);
  542.   end else
  543.   begin
  544.     ReadStrings('ClosedTables', FClosedTables);
  545.     ReadStrings('MasterQueries', FMasterQueries);
  546.     ReadStrings('DetailQueries', FDetailQueries);
  547.   end;
  548. end;
  549.  
  550. procedure TDBClientTest.BooleanActionExecute(Sender: TObject);
  551. begin
  552.   TAction(Sender).Checked := not TAction(Sender).Checked;
  553. end;
  554.  
  555. procedure TDBClientTest.EnableBCDExecute(Sender: TObject);
  556. begin
  557.   BooleanActionExecute(Sender);
  558.   Database1.Close;
  559. end;
  560.  
  561. procedure TDBClientTest.LogChangesExecute(Sender: TObject);
  562. begin
  563.   BooleanActionExecute(Sender);
  564.   ClientData.LogChanges := LogChanges.Checked;
  565. end;
  566.  
  567. procedure TDBClientTest.SetPacketRecordsExecute(Sender: TObject);
  568. var
  569.   SPacketRecs: string;
  570. begin
  571.   SPacketRecs := IntToStr(FPacketRecs);
  572.   if InputQuery(Application.Title, 'Enter PacketRecs for ApplyUpdates:', SPacketRecs) then
  573.     FPacketRecs := StrToInt(SPacketRecs);
  574. end;
  575.  
  576. procedure TDBClientTest.SetMaxErrorsExecute(Sender: TObject);
  577. var
  578.   SMaxErrors: string;
  579. begin
  580.   SMaxErrors := IntToStr(FMaxErrors);
  581.   if InputQuery(Application.Title, 'Enter MaxErrors for ApplyUpdates:', SMaxErrors) then
  582.     FMaxErrors := StrToInt(SMaxErrors);
  583. end;
  584.  
  585. procedure TDBClientTest.SetRefTableNameExecute(Sender: TObject);
  586. begin
  587.   if InputQuery(Application.Title,
  588.      'Enter ReferenceTableName for inserted references', FRefTabName) and
  589.      NestedTable.Active and (NestedTable.DataSetField is TReferenceField) then
  590.     TReferenceField(NestedTable.DataSetField).ReferenceTableName := FRefTabName;
  591. end;
  592.  
  593. procedure TDBClientTest.NestedTableBeforeInsert(DataSet: TDataSet);
  594. begin
  595.   if DataSet.DataSetField.DataType = ftReference then
  596.     TReferenceField(DataSet.DataSetField).ReferenceTableName := FRefTabName;
  597. end;
  598.  
  599. { Provider Options }
  600.  
  601. procedure TDBClientTest.SetProviderOptions;
  602. var
  603.   Opts: TProviderOptions;
  604. begin
  605.   Opts := [];
  606.   if poDelayedDetails.Checked then
  607.     Include(Opts, poFetchDetailsOnDemand);
  608.   if poDelayedBlobs.Checked then
  609.     Include(Opts, poFetchBlobsOnDemand);
  610.   if poCascadedDeletes.Checked then
  611.     Include(Opts, poCascadeDeletes);
  612.   if poCascadedUpdates.Checked then
  613.     Include(Opts, poCascadeUpdates);
  614.   if poReadOnly.Checked then
  615.     Include(Opts, Provider.poReadOnly);
  616.   if poIncludeFieldProps.Checked then
  617.     Include(Opts, poIncFieldProps);
  618.   BDEProvider.Options := Opts;
  619. end;
  620.  
  621. { Status Information }
  622.  
  623. procedure TDBClientTest.ShowHeapStatus(Sender: TObject; var Done: Boolean);
  624. begin
  625.   Caption := Format('Client DataSet Test Form - (Blocks=%d Bytes=%d)',
  626.     [AllocMemCount, AllocMemSize]);
  627. end;
  628.  
  629. procedure TDBClientTest.SetStatusMsg(const Msg: string);
  630. begin
  631.   StatusBar.Panels[0].Text := Msg;
  632. end;
  633.  
  634. procedure TDBClientTest.DataSourceDataChange(Sender: TObject;
  635.   Field: TField);
  636. const
  637.   StatusStrs: array[TUpdateStatus] of string = ('Unmodified',
  638.     'Modified', 'Inserted', 'Deleted');
  639. begin
  640.   if (Sender = ActiveDataSource) and ActiveDataSource.DataSet.IsSequenced then
  641.   begin
  642.     with ActiveDataSource.DataSet do
  643.     begin
  644.       if IsEmpty then
  645.       begin
  646.         StatusBar.Panels[1].Text := '';
  647.         StatusBar.Panels[3].Text := '(empty)';
  648.       end else
  649.       begin
  650.         StatusBar.Panels[1].Text := StatusStrs[UpdateStatus];
  651.         if (State = dsBrowse) and (Field = nil) then
  652.         begin
  653.           StatusBar.Panels[3].Text := Format('%d of %d', [RecNo, RecordCount]);
  654.           StatusMsg := '';
  655.         end;
  656.       end;
  657.     end;
  658.   end;
  659.   LogEvent('OnDataChange', Sender as TComponent);
  660. end;
  661.  
  662. procedure TDBClientTest.GridColEnter(Sender: TObject);
  663. const
  664.   NullStr: array[Boolean] of string = ('','[NULL]');
  665. var
  666.   Field: TField;
  667.  
  668.   procedure TrackBlobs;
  669.   begin
  670.     if Field.DataSet <> MasterDataSource.DataSet then Exit;
  671.     if (Field is TMemoField) and (Field <> DBMemo1.Field) then
  672.       DBMemo1.DataField := Field.FieldName
  673.     else if (Field is TGraphicField) and (Field <> DBImage1.Field) then
  674.       DBImage1.DataField := Field.FieldName;
  675.   end;
  676.  
  677.   procedure ShowOriginalValues;
  678.   var
  679.     V: Variant;
  680.   begin
  681.     if (Field.DataSet is TClientDataSet) and
  682.        (TClientDataSet(Field.DataSet).UpdateStatus = usModified) then
  683.     begin
  684.       V := Field.OldValue;
  685.       if not VarIsNull(V) and (V <> Field.Value) then
  686.         StatusMsg := Format('Orignal Value: %s', [VarToStr(V)]) else
  687.         StatusMsg := '';
  688.     end;
  689.   end;
  690.  
  691. begin
  692.   Field := (Sender as TDBGrid).SelectedField;
  693.   if Assigned(Field) then
  694.   begin
  695.     (Sender as TDBGrid).Hint := Field.ClassName;
  696.     StatusBar.Panels[2].Text := NullStr[Field.IsNull];
  697.     TrackBlobs;
  698.     ShowOriginalValues;
  699.   end;
  700. end;
  701.  
  702. { File Operations / GetData }
  703.  
  704. procedure TDBClientTest.CheckDatabase(CloseFirst: Boolean);
  705. var
  706.   SPassword,
  707.   SUserName: string;
  708. begin
  709.   if not CloseFirst and Database1.Connected and
  710.     (Database1.AliasName = DatabaseName.Text) then Exit;
  711.   Database1.Close;
  712.   Database1.AliasName := DatabaseName.Text;
  713.   Session.GetAliasParams(Database1.AliasName, Database1.Params);
  714.   { No password prompt for standard aliases (as indicated by a 'PATH' param }
  715.   if Database1.Params.IndexOfName('PATH') = -1 then
  716.   begin
  717.     SPassword := ConfigFile.ReadString('Passwords', Database1.AliasName, '');
  718.     if SPassword = '' then
  719.     begin
  720.       SUserName := Database1.Params.Values['USER NAME'];
  721.       if not LoginDialog('DatabaseName.Text', SUserName, SPassword) then Exit;
  722.       Database1.Params.Values['USER NAME'] := SUserName;
  723.     end;
  724.     Database1.Params.Values['PASSWORD'] := SPassword;
  725.   end;
  726.   if EnableBCD.Checked then
  727.     Database1.Params.Values['ENABLE BCD'] := 'True' else
  728.     Database1.Params.Values['ENABLE BCD'] := 'False';
  729.   Database1.Open;
  730.   if Database1.IsSQLBased and (SPassword <> '') then
  731.     ConfigFile.WriteString('Passwords', Database1.AliasName, SPassword);
  732. end;
  733.  
  734. procedure TDBClientTest.ClearPasswordsExecute(Sender: TObject);
  735. begin
  736.   ConfigFile.EraseSection('Passwords');
  737. end;
  738.  
  739. procedure TDBClientTest.DatabaseNameDropDown(Sender: TObject);
  740. begin
  741.   if DatabaseName.Items.Count = 0 then
  742.     Session.GetDatabaseNames(DatabaseName.Items);
  743. end;
  744.  
  745. procedure TDBClientTest.DatabaseNameClick(Sender: TObject);
  746. begin
  747.   if (DatabaseName.Text <> '') and not DatabaseName.DroppedDown then
  748.   begin
  749.     CheckDatabase(True);
  750.     MasterTableName.Items.Clear;
  751.     MasterTableName.Text := '';
  752.     DetailTableName.Items.Clear;
  753.     DetailTableName.Text := '';
  754.     ClientData.Close;
  755.   end;
  756. end;
  757.  
  758. procedure TDBClientTest.DatabaseNameKeyPress(Sender: TObject; var Key: Char);
  759. begin
  760.   if Key = #13 then
  761.   begin
  762.     if DatabaseName.DroppedDown then
  763.       DatabaseName.DroppedDown := False;
  764.     DatabaseNameClick(Sender);
  765.     Key := #0;
  766.   end;
  767. end;
  768.  
  769. procedure TDBClientTest.MasterTableNameDropDown(Sender: TObject);
  770. begin
  771.   CheckDatabase(False);
  772.   with Sender as TComboBox do
  773.     if (Items.Count < 1) and (Database1.AliasName <> '') then
  774.       Session.GetTableNames(Database1.DatabaseName, '', True, False, Items);
  775. end;
  776.  
  777. procedure TDBClientTest.MasterTableNameKeyPress(Sender: TObject; var Key: Char);
  778. begin
  779.   if Key = #13 then
  780.   begin
  781.     with Sender as TComboBox do
  782.     if DroppedDown then DroppedDown := False;
  783.     OpenTable.Execute;
  784.     Key := #0;
  785.   end;
  786. end;
  787.  
  788. procedure TDBClientTest.SetActiveDataSet(Value: TDataSet);
  789. var
  790.   RecsOut: Integer;
  791.   Options: TGetRecordOptions;
  792. begin
  793.   MasterDataSource.Enabled := False;
  794.   DetailDataSource.Enabled := False;
  795.   MasterDataSource.DataSet := Value;
  796.   FActiveDataSet := Value;
  797.   Options := [grMetaData, grXML];
  798.   try
  799.     if Assigned(Value) and not Value.Active then
  800.       if (Value = ClientData) and XMLDataPackets.Checked then
  801.         ClientData.Data := BDEProvider.GetRecords(FPacketRecs, RecsOut, Byte(Options)) else
  802.         Value.Open;
  803.   finally
  804.     if (Value = MasterTable) and DetailTable.Active then
  805.       DetailDataSource.DataSet := DetailTable
  806.     else if (Value = MasterQuery) and DetailQuery.Active then
  807.       DetailDataSource.DataSet := DetailQuery
  808.     else if (Value = ClientData) and DetailDataSet.Active then
  809.       DetailDataSource.DataSet := DetailDataSet
  810.     else
  811.       DetailDataSource.DataSet := nil;
  812.     BindControls(Value);
  813.     MasterDataSource.Enabled := True;
  814.     DetailDataSource.Enabled := True;
  815.   end;
  816. end;
  817.  
  818.  
  819. procedure TDBClientTest.DataSetSelectorChange(Sender: TObject);
  820. var
  821.   NewActive: TDataSet;
  822. begin
  823.   NewActive := nil;
  824.   case DataSetSelector.TabIndex of
  825.     0: if ClientData.Active or (ClientData.ProviderName <> '') then
  826.          NewActive := ClientData;
  827.     1: if ClientData.ChangeCount > 0 then
  828.        begin
  829.          DeltaSet.Data := ClientData.Delta;
  830.          NewActive := DeltaSet;
  831.        end;
  832.     2: if ResultSet.Active then
  833.          NewActive := ResultSet;
  834.     3: NewActive := MasterQuery;
  835.     4: NewActive := MasterTable;
  836.   end;
  837.   ActiveDataSet := NewActive;
  838. end;
  839.  
  840. procedure TDBClientTest.OpenDataSet(Source: TDBDataSet);
  841. begin
  842.   ClearEventLog.Execute;
  843.   Screen.Cursor := crHourGlass;
  844.   try
  845.     ClientData.Data := Null;
  846.     Source.Close;
  847.     if not DisableProvider.Checked then
  848.     begin
  849.       BDEProvider.DataSet := Source;
  850.       SetProviderOptions;
  851.       ClientData.ProviderName := BDEProvider.Name;
  852.       ActiveDataSet := ClientData;
  853.     end else
  854.       ActiveDataSet := Source;
  855.     MasterGrid.SetFocus;
  856.     StatusMsg := 'Dataset Opened';
  857.   finally
  858.     Screen.Cursor := crDefault;
  859.   end;
  860.   StreamSettings(True);
  861. end;
  862.  
  863. procedure TDBClientTest.OpenTableExecute(Sender: TObject);
  864. begin
  865.   if MasterTableName.Text <> '' then
  866.     OpenDataSet(MasterTable);
  867. end;
  868.  
  869. procedure TDBClientTest.MasterTableNameClick(Sender: TObject);
  870. begin
  871.   with Sender as TComboBox do
  872.   if not DroppedDown and (MasterTable.TableName <> Text) then
  873.     OpenTable.Execute;
  874. end;
  875.  
  876. procedure TDBClientTest.DetailTableNameClick(Sender: TObject);
  877. begin
  878.   with Sender as TComboBox do
  879.     if not DroppedDown and (DetailTable.TableName <> Text) then
  880.       OpenTable.Execute;
  881. end;
  882.  
  883. procedure TDBClientTest.OpenQueryExecute(Sender: TObject);
  884.  
  885.   procedure UpdateQueryHistory;
  886.   var
  887.     DSQL: string;
  888.   begin
  889.     FMasterQueries.Add(MasterSQL.Text);
  890.     DSQL := DetailSQL.Text;
  891.     if DSQL = '' then DSQL := '(empty)';
  892.     FDetailQueries.Insert(0, DSQL);
  893.     if FMasterQueries.Count > 9 then
  894.     begin
  895.       FMasterQueries.Delete(0);
  896.       FDetailQueries.Delete(0);
  897.     end;
  898.   end;
  899.  
  900. begin
  901.   if UpperCase(Copy(MasterSQL.Text, 1, 6)) = 'SELECT' then
  902.   begin
  903.     MasterQuery.RequestLive := RequestLiveQuery.Checked;
  904.     OpenDataSet(MasterQuery)
  905.   end else
  906.   begin
  907.     CheckDatabase(False);
  908.     MasterQuery.RequestLive := False;
  909.     MasterQuery.SQL.Text := MasterSQL.Text;
  910.     MasterQuery.ExecSQL;
  911.     StatusMsg := Format('%d rows were affected', [MasterQuery.RowsAffected]);
  912.   end;
  913.   UpdateQueryHistory;
  914. end;
  915.  
  916. procedure TDBClientTest.PrevQueryUpdate(Sender: TObject);
  917. begin
  918.   PrevQuery.Enabled := FQueryIndex < (FMasterQueries.Count - 1);
  919. end;
  920.  
  921. procedure TDBClientTest.SetQueryText;
  922. var
  923.   DSQL: string;
  924. begin
  925.   if FQueryIndex > -1 then
  926.   begin
  927.     MasterSQL.Text := FMasterQueries[FQueryIndex];
  928.     DSQL := FDetailQueries[FQueryIndex];
  929.     if DSQL = '(empty)' then DSQL := '';
  930.     DetailSQL.Text := DSQL;
  931.   end else
  932.   begin
  933.     MasterSQL.Text := '';
  934.     DetailSQL.Text := '';
  935.   end;
  936. end;
  937.  
  938. procedure TDBClientTest.PrevQueryExecute(Sender: TObject);
  939. begin
  940.   Assert(FQueryIndex < (FMasterQueries.Count - 1));
  941.   Inc(FQueryIndex);
  942.   SetQueryText;
  943. end;
  944.  
  945. procedure TDBClientTest.NextQueryExecute(Sender: TObject);
  946. begin
  947.   if FQueryIndex > -1 then
  948.     Dec(FQueryIndex);
  949.   SetQueryText;
  950. end;
  951.  
  952. procedure TDBClientTest.MasterSQLKeyPress(Sender: TObject; var Key: Char);
  953. begin
  954.   if Key = #13 then
  955.   begin
  956.     OpenQuery.Execute;
  957.     Key := #0;
  958.   end;
  959. end;
  960.  
  961. procedure TDBClientTest.DataSetBeforeOpen(DataSet: TDataSet);
  962. begin
  963.   DataSet.ObjectView := ObjectView.Checked;
  964.   DataSet.SparseArrays := SparseArrays.Checked;
  965.   if DataSet is TClientDataSet then
  966.   begin
  967.     ClientData.PacketRecords := FPacketRecs;
  968.     ClientData.FetchOnDemand := FetchOnDemand.Checked;
  969.     ClientData.IndexName := '';
  970.   end
  971.   else if DataSet is TDBDataSet then
  972.   begin
  973.     CheckDatabase(False);
  974.     if DataSet = MasterTable then
  975.       MasterTable.TableName := MasterTableName.Text
  976.     else if DataSet = DetailTable then
  977.       DetailTable.TableName := DetailTableName.Text
  978.     else if DataSet = MasterQuery then
  979.     begin
  980.       MasterQuery.RequestLive := RequestLiveQuery.Checked;
  981.       DetailQuery.RequestLive := RequestLiveQuery.Checked;
  982.       if MasterQuery.SQL.Text <> MasterSQL.Text then
  983.       begin
  984.         MasterQuery.SQL.Text := MasterSQL.Text;
  985.         DetailQuery.SQL.Text := DetailSQL.Text;
  986.       end
  987.     end;
  988.   end;
  989. end;
  990.  
  991. procedure TDBClientTest.ClientDataAfterClose(DataSet: TDataSet);
  992. begin
  993.   FSavePoint := -1;
  994.   if ResultSet.Active then ResultSet.Data := NULL;
  995.   if DeltaSet.Active then DeltaSet.Data := NULL;
  996.   BindControls(nil);
  997.   ClientData.IndexName := '';
  998.   DataSetAfterClose(DataSet);
  999. end;
  1000.  
  1001. procedure TDBClientTest.MasterTableAfterClose(DataSet: TDataSet);
  1002. begin
  1003.   MasterTable.IndexName := '';
  1004.   DataSetAfterClose(DataSet);
  1005. end;
  1006.  
  1007. procedure TDBClientTest.DataSetAfterClose(DataSet: TDataSet);
  1008. begin
  1009.   DataSet.Filtered := False;
  1010.   DataSet.Filter := '';
  1011. end;
  1012.  
  1013. procedure TDBClientTest.GetNextPacketExecute(Sender: TObject);
  1014. begin
  1015.   ClientData.GetNextPacket;
  1016.   ClientData.UpdateCursorPos;
  1017.   ClientData.Resync([]);
  1018. end;
  1019.  
  1020. procedure TDBClientTest.ClientDataAfterOpen(DataSet: TDataSet);
  1021. var
  1022.   I: Integer;
  1023. begin
  1024.   ClientData.LogChanges := LogChanges.Checked;
  1025.   if DataSetSelector.TabIndex <> 0 then
  1026.   begin
  1027.     DataSetSelector.TabIndex := 0;
  1028.     DataSetSelectorChange(nil);
  1029.   end;
  1030.   for I := 0 to DataSet.FieldCount - 1 do
  1031.   if DataSet.Fields[I].DataType in [ftDataSet, ftReference] then
  1032.   begin
  1033.     DetailDataSet.DataSetField := TDataSetField(DataSet.Fields[I]);
  1034.     Break;
  1035.   end;
  1036. end;
  1037.  
  1038. procedure TDBClientTest.MasterTableAfterOpen(DataSet: TDataSet);
  1039. var
  1040.   I: Integer;
  1041.   Field: TField;
  1042.   MasterFields: string;
  1043. begin
  1044.   if DetailTableName.Text <> '' then
  1045.   begin
  1046.     DetailTable.Open;
  1047.     DetailTable.IndexDefs.Update;
  1048.     for I := 0 to DetailTable.Fields.Count - 1do
  1049.     begin
  1050.       Field := MasterTable.FindField(DetailTable.Fields[I].FieldName);
  1051.       if Field <> nil then
  1052.       begin
  1053.         if DetailTable.IndexDefs.GetIndexForFields(MasterFields + Field.FieldName, False) <> nil then
  1054.           MasterFields := MasterFields + Field.FieldName + ';';
  1055.       end;
  1056.     end;
  1057.     if MasterFields = '' then
  1058.       DatabaseError('Cannot determine linking fields for detail');
  1059.     SetLength(MasterFields, Length(MasterFields)-1);
  1060.     DetailTable.IndexFieldNames := MasterFields;
  1061.     DetailTable.MasterFields := MasterFields;
  1062.     DetailTable.MasterSource := DetailMasterSource;
  1063.   end;
  1064.   for I := 0 to DataSet.FieldCount - 1 do
  1065.   if DataSet.Fields[I].DataType in [ftDataSet, ftReference] then
  1066.   begin
  1067.     TDataSetField(DataSet.Fields[I]).IncludeObjectField := IncludeNestedObject.Checked;
  1068.     NestedTable.DataSetField := TDataSetField(DataSet.Fields[I]);
  1069.     Break;
  1070.   end;
  1071.   ProviderDataSetAfterOpen(DataSet);
  1072. end;
  1073.  
  1074. procedure TDBClientTest.MasterTableBeforeClose(DataSet: TDataSet);
  1075.  
  1076.   procedure UpdateClosedTables;
  1077.   var
  1078.     TableEntry: string;
  1079.   begin
  1080.     TableEntry := Database1.AliasName + ':' + MasterTable.TableName;
  1081.     if DetailTable.Active then
  1082.     begin
  1083.       TableEntry := TableEntry + '/' + DetailTable.TableName;
  1084.       DetailTable.Close;
  1085.     end;
  1086.     if FClosedTables.IndexOf(TableEntry) = -1 then
  1087.     begin
  1088.       FClosedTables.Insert(0, TableEntry);
  1089.       if FClosedTables.Count > 9 then
  1090.         FClosedTables.Delete(9);
  1091.     end;
  1092.   end;
  1093.  
  1094. begin
  1095.   UpdateClosedTables;
  1096.   with DetailTable do
  1097.   begin
  1098.     Close;
  1099.     IndexFieldNames := '';
  1100.     MasterFields := '';
  1101.     MasterSource := nil;
  1102.   end;
  1103. end;
  1104.  
  1105. procedure TDBClientTest.MasterQueryAfterOpen(DataSet: TDataSet);
  1106. begin
  1107.   if Length(Trim(DetailSQL.Text)) <> 0 then
  1108.   begin
  1109.     DetailQuerySource.Dataset := MasterQuery;
  1110.     DetailQuery.Open;
  1111.   end
  1112.   else
  1113.     DetailQuerySource.Dataset := nil;
  1114.   ProviderDataSetAfterOpen(DataSet);
  1115. end;
  1116.  
  1117. procedure TDBClientTest.MasterQueryBeforeClose(DataSet: TDataSet);
  1118. begin
  1119.   DetailQuery.Close;
  1120. end;
  1121.  
  1122. procedure TDBClientTest.ProviderDataSetAfterOpen(DataSet: TDataSet);
  1123. begin
  1124.   if MasterDataSource.DataSet = DataSet then
  1125.     if DataSet = MasterQuery then
  1126.       DataSetSelector.TabIndex := 3 else
  1127.       DataSetSelector.TabIndex := 4;
  1128. end;
  1129.  
  1130. procedure TDBClientTest.CloseActiveDataSetExecute(Sender: TObject);
  1131. begin
  1132.   if Assigned(ActiveDataSet) then
  1133.     ActiveDataSet.Close;
  1134. end;
  1135.  
  1136. procedure TDBClientTest.UpdateReOpenMenu;
  1137. var
  1138.   I: Integer;
  1139. begin
  1140.   while FileReOpen.Count > 0 do
  1141.     FileReOpen.Items[0].Free;
  1142.   for I := 0 to FClosedTables.Count - 1 do
  1143.     FileReOpen.Add(NewItem(Format('%d) %s', [I, FClosedTables[I]]), 0, False,
  1144.       True, ClosedFileClick, 0, ''));
  1145. end;
  1146.  
  1147. procedure TDBClientTest.ClosedFileClick(Sender: TObject);
  1148. var
  1149.   S: string;
  1150.   P, P2: Integer;
  1151. begin
  1152.   S := Copy(TMenuItem(Sender).Caption, 4, MAXINT);
  1153.   P := Pos(':', S);
  1154.   P2 := Pos('/', S);
  1155.   DatabaseName.Text := Copy(S, 1, P-1);
  1156.   if P2 > 0 then
  1157.     DetailTableName.Text := Copy(S, P2+1, MAXINT) else
  1158.   begin
  1159.     DetailTableName.Text := '';
  1160.     P2 := MAXINT;
  1161.   end;
  1162.   MasterTableName.Text := Copy(S, P+1, P2-P-1);
  1163.   FClosedTables.Delete(FClosedTables.IndexOf(S));
  1164.   OpenTable.Execute;
  1165. end;
  1166.  
  1167. procedure TDBClientTest.FormCloseQuery(Sender: TObject;
  1168.   var CanClose: Boolean);
  1169. begin
  1170.   CloseActiveDataSet.Execute;
  1171. end;
  1172.  
  1173. procedure TDBClientTest.FileMenuClick(Sender: TObject);
  1174. begin
  1175.   UpdateReOpenMenu;
  1176.   FileReOpen.Enabled := FClosedTables.Count > 0;
  1177. end;
  1178.  
  1179. { Packet Save/Load }
  1180.  
  1181. procedure TDBClientTest.LoadDatapacket1Click(Sender: TObject);
  1182. begin
  1183.   OpenDialog.FilterIndex := 1;
  1184.   if OpenDialog.Execute then
  1185.   begin
  1186.     ClientData.LoadFromFile(OpenDialog.FileName);
  1187.     DataSetSelector.TabIndex := 0;
  1188.     DataSetSelectorChange(nil);
  1189.   end;
  1190. end;
  1191.  
  1192. procedure TDBClientTest.SaveDataPacketExecute(Sender: TObject);
  1193. const
  1194.   PacketFormat: array[Boolean] of TDataPacketFormat = (dfBinary, dfXML);
  1195. begin
  1196.   if XMLDataPackets.Checked then
  1197.     SaveDialog.FilterIndex := 2 else
  1198.     SaveDialog.FilterIndex := 1;
  1199.   if SaveDialog.Execute then
  1200.     if ActiveDataSet is TClientDataSet then
  1201.       TClientDataSet(ActiveDataSet).SaveToFile(SaveDialog.FileName,
  1202.       PacketFormat[XMLDataPackets.Checked])
  1203.     else
  1204.       ClientData.SaveToFile(SaveDialog.FileName);
  1205. end;
  1206.  
  1207. procedure TDBClientTest.FileActionsUpdate(Sender: TObject);
  1208. begin
  1209.   CloseActiveDataSet.Enabled := Assigned(ActiveDataSet) and ActiveDataSet.Active;
  1210.   SaveDataPacket.Enabled := (ActiveDataSet is TClientDataSet);
  1211. end;
  1212.  
  1213. { Streaming }
  1214.  
  1215. procedure TDBClientTest.StreamFormOutExecute(Sender: TObject);
  1216. begin
  1217.   SaveDialog.FilterIndex := 2;
  1218.   if SaveDialog.Execute then
  1219.     WriteComponentResFile(SaveDialog.FileName, Self);
  1220. end;
  1221.  
  1222. procedure TDBClientTest.StreamFormInExecute(Sender: TObject);
  1223. var
  1224.   Form: TDBClientTest;
  1225. begin
  1226.   OpenDialog.FilterIndex := 2;
  1227.   if OpenDialog.Execute then
  1228.   begin
  1229.     RegisterClasses([TStringField, TIntegerField, TADTField, TArrayField, TDataSetField]);
  1230.     Form := TDBClientTest.CreateNew(Application, 0);
  1231.     ReadComponentResFile(OpenDialog.FileName, Form);
  1232.   end;
  1233. end;
  1234.  
  1235. { DB Control Linking }
  1236.  
  1237. procedure TDBClientTest.BindControls(DataSet: TDataSet);
  1238. var
  1239.   I: Integer;
  1240.   Field: TField;
  1241. begin
  1242.   DBMemo1.DataField := '';
  1243.   DBImage1.DataField := '';
  1244.   DetailGrid.Visible := False;
  1245.   GridSplitter.Visible := False;
  1246.   BlobCtrlPanel.Visible := False;
  1247.   DBImage1.Visible := False;
  1248.   DBMemo1.Visible := False;
  1249.   if Assigned(DataSet) then
  1250.   begin
  1251.     for I := 0 to DataSet.FieldCount - 1 do
  1252.     begin
  1253.       Field := DataSet.Fields[I];
  1254.       case Field.DataType of
  1255.         ftMemo, ftOraClob:
  1256.           if DBMemo1.DataField = '' then
  1257.           begin
  1258.              DBMemo1.DataField := Field.FieldName;
  1259.              DBMemo1.Visible := True;
  1260.           end;
  1261.         ftGraphic:
  1262.           if DBImage1.DataField = '' then
  1263.           begin
  1264.             DBImage1.DataField := DataSet.Fields[I].FieldName;
  1265.             DBImage1.Visible := True;
  1266.           end;
  1267.         ftDataSet, ftReference:
  1268.           if DisplayDetails.Checked and (DetailDataSource.DataSet = nil) then
  1269.           begin
  1270.             DetailDataSource.DataSet := TDataSetField(DataSet.Fields[I]).NestedDataSet;
  1271.           end;
  1272.         ftBytes, ftVarBytes:
  1273.           begin
  1274.             Field.OnGetText := BinaryGetText;
  1275.             Field.OnSetText := BinarySetText;
  1276.             Field.DisplayWidth := (Field.Size + 3);
  1277.           end;
  1278.       end;
  1279.     end;
  1280.     BlobCtrlPanel.Visible := DBMemo1.Visible or DBImage1.Visible;
  1281.     if Assigned(DetailDataSource.DataSet) then
  1282.     begin
  1283.       GridSplitter.Visible := True;
  1284.       DetailGrid.Visible := True;
  1285.     end;
  1286.   end;
  1287. end;
  1288.  
  1289. procedure TDBClientTest.GridSetFocus(Sender: TObject);
  1290. begin
  1291.   ActiveDataSource := (Sender as TDBGrid).DataSource;
  1292.   DBNavigator1.DataSource := ActiveDataSource;
  1293.   DataSourceDataChange(ActiveDataSource, nil);
  1294. end;
  1295.  
  1296. procedure TDBClientTest.PopupMenu1Popup(Sender: TObject);
  1297. var
  1298.   I: Integer;
  1299.   MI: TMenuItem;
  1300.   F, CurField: TField;
  1301. begin
  1302.   with PopupMenu1, ActiveDataSet do
  1303.   begin
  1304.     if PopupMenu1.PopupComponent = DBMemo1 then
  1305.       CurField := DBMemo1.Field else
  1306.       CurField := DBImage1.Field;
  1307.     while Items.Count > 0 do Items.Delete(0);
  1308.     MI := NewItem('(None)', 0, False, True, FieldSelect, 0, 'None');
  1309.     Items.Add(MI);
  1310.     for I := 0 to FieldCount - 1 do
  1311.       if Fields[I] is TBlobField then
  1312.       begin
  1313.         F := Fields[I];
  1314.         MI := NewItem(F.FieldName, 0, F=CurField, True, FieldSelect, 0, 'mi'+F.FieldName);
  1315.         MI.Tag := Integer(F);
  1316.         Items.Add(MI);
  1317.       end;
  1318.   end;
  1319. end;
  1320.  
  1321. procedure TDBClientTest.FieldSelect(Sender: TObject);
  1322. var
  1323.   MI: TMenuItem;
  1324. begin
  1325.   MI := TMenuItem(Sender);
  1326.   if PopupMenu1.PopupComponent = DBImage1 then
  1327.   try
  1328.     if MI.Tag = 0 then
  1329.       DBImage1.DataField := '' else
  1330.       DBImage1.DataField := TField(MI.Tag).FieldName;
  1331.   except
  1332.     DBImage1.DataField := '';
  1333.     raise;
  1334.   end
  1335.   else if PopupMenu1.PopupComponent = DBMemo1 then
  1336.   try
  1337.     if MI.Tag = 0 then
  1338.       DBMemo1.DataField := '' else
  1339.       DBMemo1.DataField := TField(MI.Tag).FieldName;
  1340.   except
  1341.     DBMemo1.DataField := '';
  1342.     raise;
  1343.   end;
  1344. end;
  1345.  
  1346. procedure TDBClientTest.BinaryGetText(Sender: TField; var Text: string;
  1347.   DisplayText: Boolean);
  1348. begin
  1349.   Text := Sender.AsString;
  1350.   TrimRight(Text);
  1351. end;
  1352.  
  1353. procedure TDBClientTest.BinarySetText(Sender: TField; const Text: string);
  1354. begin
  1355.   Sender.AsString := Text;
  1356. end;
  1357.  
  1358. { Editing / Updates }
  1359.  
  1360. procedure TDBClientTest.EditActionsUpdate(Sender: TObject);
  1361. var
  1362.   Enabled: Boolean;
  1363. begin
  1364.   with ClientData do
  1365.     Enabled := (ActiveDataSet = ClientData) and Active and
  1366.       ((ChangeCount > 0) or (State <> dsBrowse) or
  1367.        (DetailDataSet.State in dsEditModes));
  1368.   ApplyUpdates.Enabled := Enabled;
  1369.   MergeChangeLog.Enabled := Enabled;
  1370.   CancelUpdates.Enabled := Enabled;
  1371.   GetSavePoint.Enabled := (ActiveDataSet = ClientData) and ClientData.Active;
  1372.   RevertToSavePoint.Enabled := FSavePoint > 0;
  1373.   UndoLastEdit.Enabled := Enabled;
  1374.   RevertRecord.Enabled := Enabled and
  1375.     ((ActiveDataSource.DataSet as TClientDataSet).UpdateStatus <> usUnmodified);
  1376.   GetNextPacket.Enabled := GetSavePoint.Enabled and
  1377.     (ClientData.PacketRecords <> -1);
  1378.   ClearField.Enabled := Assigned(ActiveDataSet) and ActiveDataSet.Active;
  1379.   RefreshData.Enabled := ClearField.Enabled;
  1380. end;
  1381.  
  1382. procedure TDBClientTest.ApplyUpdatesExecute(Sender: TObject);
  1383. var
  1384.   Delta, Results, OwnerData: OleVariant;
  1385.   ErrorCount: Integer;
  1386. begin
  1387.   BDEProvider.ResolveToDataSet := ResolveToDataSet.Checked;
  1388.   ClientData.CheckBrowseMode;
  1389.   Delta := ClientData.Delta;
  1390.   Results := ClientData.AppServer.AS_ApplyUpdates('', Delta, FMaxErrors, ErrorCount, OwnerData);
  1391.   ResultSet.Data := Results;
  1392.   ClientData.Reconcile(Results);
  1393.   if ErrorCount = 0 then
  1394.     StatusMsg := 'Update Successful' else
  1395.     StatusMsg := Format('%d errors during update', [ErrorCount]);
  1396.   Beep;
  1397. end;
  1398.  
  1399. procedure TDBClientTest.ApplyUpdatesUpdate(Sender: TObject);
  1400. begin
  1401.   ApplyUpdates.Enabled := ClientData.Active and (ClientData.ChangeCount > 0);
  1402. end;
  1403.  
  1404. procedure TDBClientTest.CancelUpdatesExecute(Sender: TObject);
  1405. begin
  1406.   ClientData.CancelUpdates;
  1407. end;
  1408.  
  1409. procedure TDBClientTest.ClientDataReconcileError(DataSet: TClientDataSet;
  1410.   E: EReconcileError; UpdateKind: TUpdateKind;
  1411.   var Action: TReconcileAction);
  1412. begin
  1413.   Action := HandleReconcileError(DataSet, UpdateKind, E);
  1414. end;
  1415.  
  1416. procedure TDBClientTest.UndoLastEditExecute(Sender: TObject);
  1417. begin
  1418.   ClientData.UndoLastChange(True);
  1419. end;
  1420.  
  1421. procedure TDBClientTest.RevertRecordExecute(Sender: TObject);
  1422. begin
  1423.   ClientData.RevertRecord;
  1424. end;
  1425.  
  1426. procedure TDBClientTest.ClearFieldExecute(Sender: TObject);
  1427. var
  1428.   Field: TField;
  1429. begin
  1430.   Field := MasterGrid.SelectedField;
  1431.   if Field = nil then Exit;
  1432.   ActiveDataSet.Edit;
  1433.   Field.Clear;
  1434. end;
  1435.  
  1436. procedure TDBClientTest.GetSavePointExecute(Sender: TObject);
  1437. begin
  1438.   FSavePoint := ClientData.SavePoint;
  1439. end;
  1440.  
  1441. procedure TDBClientTest.RevertToSavepointExecute(Sender: TObject);
  1442. begin
  1443.   ClientData.SavePoint := FSavePoint;
  1444. end;
  1445.  
  1446. procedure TDBClientTest.MergeChangeLogExecute(Sender: TObject);
  1447. begin
  1448.   ClientData.MergeChangeLog;
  1449. end;
  1450.  
  1451. procedure TDBClientTest.RefreshDataExecute(Sender: TObject);
  1452. begin
  1453.   ActiveDataSet.Refresh;
  1454. end;
  1455.  
  1456. { Indexes }
  1457.  
  1458. procedure TDBClientTest.IndexPageShow(Sender: TObject);
  1459. begin
  1460.   if not Assigned(ActiveDataSet) or not ActiveDataSet.Active then
  1461.     OpenTable.Execute;
  1462.   RefreshIndexNames(0);
  1463. end;
  1464.  
  1465. procedure TDBClientTest.RefreshIndexNames(NewItemIndex: Integer);
  1466. var
  1467.   I: Integer;
  1468.   IndexDefs: TIndexDefs;
  1469. begin
  1470.   IndexList.Clear;
  1471.   if ActiveDataSet = MasterTable then
  1472.     IndexDefs := MasterTable.IndexDefs else
  1473.     IndexDefs := ClientData.IndexDefs;
  1474.   IndexDefs.Update;
  1475.   for I := 0 to IndexDefs.Count - 1 do
  1476.     if IndexDefs[I].Name = '' then
  1477.       IndexList.Items.Add('<primary>') else
  1478.       IndexList.Items.Add(IndexDefs[I].Name);
  1479.   if IndexList.Items.Count > 0 then
  1480.   begin
  1481.     if NewItemIndex < IndexList.Items.Count then
  1482.       IndexList.ItemIndex := NewItemIndex else
  1483.       IndexList.ItemIndex := 0;
  1484.     ShowIndexParams;
  1485.   end;
  1486. end;
  1487.  
  1488. procedure TDBClientTest.ShowIndexParams;
  1489. var
  1490.   IndexDef: TIndexDef;
  1491. begin
  1492.   if ActiveDataSet = MasterTable then
  1493.     IndexDef := MasterTable.IndexDefs[IndexList.ItemIndex] else
  1494.     IndexDef := ClientData.IndexDefs[IndexList.ItemIndex];
  1495.   idxCaseInsensitive.Checked := ixCaseInsensitive in IndexDef.Options;
  1496.   idxDescending.Checked := ixDescending in IndexDef.Options;
  1497.   idxUnique.Checked := ixUnique in IndexDef.Options;
  1498.   idxPrimary.Checked := ixPrimary in IndexDef.Options;
  1499.   IndexFields.Text := IndexDef.Fields;
  1500.   DescFields.Text := IndexDef.DescFields;
  1501.   CaseInsFields.Text := IndexDef.CaseInsFields;
  1502. end;
  1503.  
  1504. procedure TDBClientTest.IndexListClick(Sender: TObject);
  1505. begin
  1506.   if ActiveDataSet = MasterTable then
  1507.     MasterTable.IndexName := MasterTable.IndexDefs[IndexList.ItemIndex].Name else
  1508.     ClientData.IndexName := ClientData.IndexDefs[IndexList.ItemIndex].Name;
  1509.   ShowIndexParams;
  1510. end;
  1511.  
  1512. procedure TDBClientTest.CreateIndexClick(Sender: TObject);
  1513. var
  1514.   IndexName: string;
  1515.   Options: TIndexOptions;
  1516. begin
  1517.   IndexName := Format('Index%d', [IndexList.Items.Count+1]);
  1518.   if InputQuery('Create Index', 'Enter IndexName:', IndexName) then
  1519.   begin
  1520.     Options := [];
  1521.     if idxCaseInsensitive.Checked then Include(Options, ixCaseInsensitive);
  1522.     if idxDescending.Checked then Include(Options, ixDescending);
  1523.     if idxUnique.Checked then Include(Options, ixUnique);
  1524.     if idxPrimary.Checked then Include(Options, ixPrimary);
  1525.     if ActiveDataSet = MasterTable then
  1526.     begin
  1527.       MasterTable.Close;
  1528.       MasterTable.AddIndex(IndexName, IndexFields.Text, Options,
  1529.         DescFields.Text);
  1530.       MasterTable.Open;
  1531.     end else
  1532.       ClientData.AddIndex(IndexName, IndexFields.Text, Options,
  1533.         DescFields.Text, CaseInsFields.Text);
  1534.     StatusMsg := 'Index Created';
  1535.     RefreshIndexNames(IndexList.Items.Count);
  1536.   end;
  1537. end;
  1538.  
  1539. procedure TDBClientTest.DeleteIndexClick(Sender: TObject);
  1540. begin
  1541.   if IndexList.ItemIndex > -1 then
  1542.     if ActiveDataSet = MasterTable then
  1543.     begin
  1544.       MasterTable.Close;
  1545.       MasterTable.DeleteIndex(MasterTable.IndexDefs[IndexList.ItemIndex].Name);
  1546.       MasterTable.Open;
  1547.     end else
  1548.       ClientData.DeleteIndex(ClientData.IndexDefs[IndexList.ItemIndex].Name);
  1549. end;
  1550.  
  1551. procedure TDBClientTest.GridTitleClick(Column: TColumn);
  1552. var
  1553.   DataSet: TDataSet;
  1554.  
  1555. begin
  1556.   DataSet := Column.Field.DataSet;
  1557.   if DataSet is TClientDataSet then
  1558.     TClientDataSet(DataSet).IndexFieldNames := Column.Field.FieldName
  1559.   else if DataSet is TTable then
  1560.   begin
  1561.     if TTable(DataSet).IndexDefs.GetIndexForFields(Column.Field.FieldName, False) = nil then Exit;
  1562.     TTable(DataSet).IndexFieldNames := Column.Field.FieldName;
  1563.   end;
  1564.   StatusMsg := 'Sorted on '+Column.Field.FieldName;
  1565. end;
  1566.  
  1567. { Filters }
  1568.  
  1569. procedure TDBClientTest.FilterPageShow(Sender: TObject);
  1570. var
  1571.   Field: TField;
  1572.   LocValue,
  1573.   QuoteChar: string;
  1574. begin
  1575.   if (Filter.Text = '') and Assigned(ActiveDataSet) and ActiveDataSet.Active then
  1576.   begin
  1577.     Field := MasterGrid.SelectedField;
  1578.     if Field = nil then Exit;
  1579.     with ActiveDataSet do
  1580.     try
  1581.       DisableControls;
  1582.       MoveBy(3);
  1583.       LocValue := Field.Value;
  1584.       First;
  1585.     finally
  1586.       EnableControls;
  1587.     end;
  1588.     if Field.DataType in [ftString, ftMemo, ftFixedChar] then
  1589.       QuoteChar := '''' else
  1590.       QuoteChar := '';
  1591.     Filter.Text := Format('%s=%s%s%1:s', [Field.FullName, QuoteChar, LocValue]);
  1592.   end;
  1593. end;
  1594.  
  1595. procedure TDBClientTest.FilterKeyPress(Sender: TObject; var Key: Char);
  1596. begin
  1597.   if Key = #13 then FilteredClick(Sender);
  1598. end;
  1599.  
  1600. procedure TDBClientTest.FilterExit(Sender: TObject);
  1601. begin
  1602.   if Assigned(ActiveDataSet) then
  1603.     ActiveDataSet.Filter := Filter.Text;
  1604. end;
  1605.  
  1606. procedure TDBClientTest.SetFilterOptions(Sender: TObject);
  1607. begin
  1608.   ActiveDataSet.FilterOptions := FilterOptions;
  1609. end;
  1610.  
  1611. function TDBClientTest.FilterOptions: TFilterOptions;
  1612. begin
  1613.   Result := [];
  1614.   if foCaseInsensitive.Checked then Include(Result, DB.foCaseInsensitive);
  1615.   if foNoPartialCompare.Checked then Include(Result, DB.foNoPartialCompare);
  1616. end;
  1617.  
  1618. procedure TDBClientTest.FilteredClick(Sender: TObject);
  1619. begin
  1620.   if Filtered.Checked then
  1621.   begin
  1622.     ActiveDataSet.FilterOptions := FilterOptions;
  1623.     ActiveDataSet.Filter := Filter.Text;
  1624.   end;
  1625.   ActiveDataSet.Filtered := Filtered.Checked;
  1626. end;
  1627.  
  1628. procedure TDBClientTest.FindFirstClick(Sender: TObject);
  1629. begin
  1630.   ActiveDataSet.FilterOptions := FilterOptions;
  1631.   ActiveDataSet.Filter := Filter.Text;
  1632.   ActiveDataSet.FindFirst;
  1633. end;
  1634.  
  1635. procedure TDBClientTest.FindNextClick(Sender: TObject);
  1636. begin
  1637.   if ActiveDataSet.FilterOptions <> FilterOptions then
  1638.     ActiveDataSet.FilterOptions := FilterOptions;
  1639.   if ActiveDataSet.Filter <> Filter.Text then
  1640.     ActiveDataSet.Filter := Filter.Text;
  1641.   ActiveDataSet.FindNext;
  1642. end;
  1643.  
  1644. procedure TDBClientTest.StatusFilterClick(Sender: TObject);
  1645. var
  1646.   StatusFilter: TUpdateStatusSet;
  1647. begin
  1648.   StatusFilter := [];
  1649.   if ModifiedRecords.Checked then
  1650.     Include(StatusFilter, usModified);
  1651.   if InsertedRecords.Checked then
  1652.     Include(StatusFilter, usInserted);
  1653.   if DeletedRecords.Checked then
  1654.     Include(StatusFilter, usDeleted);
  1655.   ClientData.StatusFilter := StatusFilter;
  1656. end;
  1657.  
  1658. { FindKey }
  1659.  
  1660. procedure TDBClientTest.FindKeyPageInit(Sender: TObject);
  1661. var
  1662.   I: Integer;
  1663.   FirstField: TField;
  1664.   KeyFieldNames: string;
  1665. begin
  1666.   FirstField := nil;
  1667.   if ActiveDataSet is TClientDataSet then
  1668.     with TClientDataSet(ActiveDataSet) do
  1669.     begin
  1670.       for I := 0 to IndexFieldCount - 1 do
  1671.         KeyFieldNames := KeyFieldNames + IndexFields[I].FieldName + ';';
  1672.       FirstField := IndexFields[0];
  1673.     end
  1674.   else if ActiveDataSet is TTable then
  1675.     with TTable(ActiveDataSet) do
  1676.     begin
  1677.       for I := 0 to IndexFieldCount - 1 do
  1678.         KeyFieldNames := KeyFieldNames + IndexFields[I].FieldName + ';';
  1679.       FirstField := IndexFields[0];
  1680.     end;
  1681.   FindValue.Enabled := FirstField <> nil;
  1682.   if FirstField <> nil then
  1683.   begin
  1684.     with ActiveDataSet do
  1685.     try
  1686.       DisableControls;
  1687.       MasterGrid.SelectedField := FirstField;
  1688.       MoveBy(3);
  1689.       FindValue.Text := FirstField.Value;
  1690.       First;
  1691.     finally
  1692.       EnableControls;
  1693.     end;
  1694.     KeyFieldList.Caption := Copy(KeyFieldNames, 1, Length(KeyFieldNames)-1)
  1695.   end else
  1696.     KeyFieldList.Caption := 'No Key Fields';
  1697. end;
  1698.  
  1699. procedure TDBClientTest.FindKeyClick(Sender: TObject);
  1700.  
  1701.   function Min(X, Y: Integer): Integer;
  1702.   begin
  1703.     Result := X;
  1704.     if X > Y then Result := Y;
  1705.   end;
  1706.  
  1707. var
  1708.   Values: TStringList;
  1709.   I: Integer;
  1710. begin
  1711.   Values := TStringList.Create;
  1712.   try
  1713.     Values.CommaText := FindValue.Text;
  1714.     if ActiveDataSet = ClientData then
  1715.       with ClientData do
  1716.       begin
  1717.         SetKey;
  1718.         try
  1719.           KeyExclusive := Self.KeyExclusive.Checked;
  1720.           KeyFieldCount := Min(Values.Count, IndexFieldCount);
  1721.           for I := 0 to KeyFieldCount - 1 do
  1722.             IndexFields[I].AsString := Values[I];
  1723.           if FindPartial.Checked then KeyFieldCount := KeyFieldCount - 1;
  1724.           if Sender = Self.FindNearest then
  1725.             GotoNearest else
  1726.             if GotoKey then
  1727.               StatusMsg := 'Record Found' else
  1728.               StatusMsg := 'Not found';
  1729.         except
  1730.           Cancel;
  1731.           Raise;
  1732.         end;
  1733.       end
  1734.     else if ActiveDataSet = MasterTable then
  1735.       with MasterTable do
  1736.       begin
  1737.         SetKey;
  1738.         try
  1739.           KeyExclusive := Self.KeyExclusive.Checked;
  1740.           KeyFieldCount := Min(Values.Count, IndexFieldCount);
  1741.           for I := 0 to KeyFieldCount - 1 do
  1742.             IndexFields[I].AsString := Values[I];
  1743.           if FindPartial.Checked then KeyFieldCount := KeyFieldCount - 1;
  1744.           if Sender = Self.FindNearest then
  1745.             GotoNearest else
  1746.             if GotoKey then
  1747.               StatusMsg := 'Record Found' else
  1748.               StatusMsg := 'Not found';
  1749.         except
  1750.           Cancel;
  1751.           Raise;
  1752.         end;
  1753.       end;
  1754.   finally
  1755.     Values.Free;
  1756.   end;
  1757. end;
  1758.  
  1759. { Locate }
  1760.  
  1761. procedure TDBClientTest.LocatePageShow(Sender: TObject);
  1762. var
  1763.   Field: TField;
  1764. begin
  1765.   if (ActiveDataSet <> nil) and ActiveDataSet.Active then
  1766.   begin
  1767.     Field := MasterGrid.SelectedField;
  1768.     if LocateField.Items.Count = 0 then
  1769.       LocateFieldDropDown(LocateField);
  1770.     if (LocateField.Text = '') or (LocateField.Items.IndexOf(Field.FieldName) < 1) then
  1771.       LocateField.Text := Field.FieldName;
  1772.     with ActiveDataSet do
  1773.     try
  1774.       DisableControls;
  1775.       MoveBy(3);
  1776.       LocateEdit.Text := Field.Value;
  1777.       First;
  1778.     finally
  1779.       EnableControls;
  1780.     end;
  1781.   end;
  1782. end;
  1783.  
  1784. procedure TDBClientTest.LocateFieldDropDown(Sender: TObject);
  1785. begin
  1786.   if (ActiveDataSet <> nil) and (ActiveDataSet.Active) then
  1787.     ActiveDataSet.GetFieldNames(LocateField.Items);
  1788. end;
  1789.  
  1790. procedure TDBClientTest.LocateButtonClick(Sender: TObject);
  1791.  
  1792.   function LocateValue: Variant;
  1793.   var
  1794.     I: Integer;
  1795.     Values: TStringList;
  1796.   begin
  1797.     if LocateNull.Checked then
  1798.       Result := Null
  1799.     else if Pos(',', LocateEdit.Text) < 1 then
  1800.       LocateValue := LocateEdit.Text
  1801.     else
  1802.     begin
  1803.       Values := TStringList.Create;
  1804.       try
  1805.         Values.CommaText := LocateEdit.Text;
  1806.         Result := VarArrayCreate([0,Values.Count-1], varVariant);
  1807.         for I := 0 to Values.Count - 1 do
  1808.           Result[I] := Values[I];
  1809.       finally
  1810.         Values.Free;
  1811.       end;
  1812.     end;
  1813.   end;
  1814.  
  1815. var
  1816.   Options: TLocateOptions;
  1817. begin
  1818.   if not Assigned(ActiveDataSet) then Exit;
  1819.   Options := [];
  1820.   if locCaseInsensitive.Checked then Include(Options, loCaseInsensitive);
  1821.   if locPartialKey.Checked then Include(Options, loPartialKey);
  1822.   if ActiveDataSet.Locate(LocateField.Text, LocateValue, Options) then
  1823.     StatusMsg := 'Record Found' else
  1824.     StatusMsg := 'Not found';
  1825. end;
  1826.  
  1827. procedure TDBClientTest.LocateNullClick(Sender: TObject);
  1828. begin
  1829.   LocateEdit.Enabled := not LocateNull.Checked;
  1830. end;
  1831.  
  1832. { FieldLists }
  1833.  
  1834. procedure TDBClientTest.FieldsPageShow(Sender: TObject);
  1835.  
  1836.   procedure WriteLists(DataSet: TDataSet);
  1837.   var
  1838.     I: Integer;
  1839.   begin
  1840.     FieldList.Clear;
  1841.     for I := 0 to DataSet.FieldList.Count - 1 do
  1842.       with DataSet.FieldList do
  1843.         FieldList.Lines.Add(Format('%d) %s', [Fields[I].FieldNo, Strings[I]]));
  1844.     FieldDefList.Clear;
  1845.     DataSet.FieldDefs.Updated := False;
  1846.     DataSet.FieldDefList.Update;
  1847.     for I := 0 to DataSet.FieldDefList.Count - 1 do
  1848.       with DataSet.FieldDefList do
  1849.         FieldDefList.Lines.Add(Format('%d) %s', [FieldDefs[I].FieldNo, Strings[I]]));
  1850.   end;
  1851.  
  1852. var
  1853.   DataSet: TDataSet;
  1854. begin
  1855.   DataSet := ActiveDataSource.DataSet;
  1856.   if Assigned(DataSet) and DataSet.Active then
  1857.     WriteLists(DataSet)
  1858.   else
  1859.   begin
  1860.     CheckDatabase(False);
  1861.     MasterTable.TableName := MasterTableName.Text;
  1862.     WriteLists(MasterTable);
  1863.   end;
  1864. end;
  1865.  
  1866. { Create DataSet }
  1867.  
  1868. const
  1869.   DefaultCreateTypes: array[0..10] of string = (
  1870.     'Scalar Types Only',
  1871.     'Object Types',
  1872.     'Array of Scalars',
  1873.     'Array of ADT',
  1874.     'Array of Nested ADTs',
  1875.     'ADT with Scalars',
  1876.     'ADT with Array',
  1877.     'Nested ADTs',
  1878.     'Nested DataSet',
  1879.     'Nested DataSet w/ADTs',
  1880.     'Nested DataSet 3 Levels'
  1881.     );
  1882.  
  1883. procedure TDBClientTest.CreatePageShow(Sender: TObject);
  1884. var
  1885.   I: Integer;
  1886. begin
  1887.   with CreateDataSetDesc.Items do
  1888.     if Count < 1 then
  1889.     begin
  1890.       for I := Low(DefaultCreateTypes) to High(DefaultCreateTypes) do
  1891.         Add(DefaultCreateTypes[I]);
  1892.       if Text = '' then
  1893.         CreateDataSetDesc.ItemIndex := 0
  1894.       else if IndexOf(CreateDataSetDesc.Text) <> -1 then
  1895.         CreateDataSetDesc.ItemIndex := IndexOf(CreateDataSetDesc.Text);
  1896.       UpdateFieldList;
  1897.     end;
  1898. end;
  1899.  
  1900. procedure TDBClientTest.CreateFieldTypeDropDown(Sender: TObject);
  1901. var
  1902.   I: TFieldType;
  1903. begin
  1904.   if CreateFieldType.Items.Count < 2 then
  1905.     for I := Low(TFieldType) to High(TFieldType) do
  1906.       CreateFieldType.Items.Add(FieldTypeNames[I]);
  1907. end;
  1908.  
  1909. procedure TDBClientTest.CreateFieldTypeChange(Sender: TObject);
  1910. begin
  1911.   if (CreateFieldType.ItemIndex >= 0) and
  1912.      (CreateFieldType.ItemIndex <= Ord(High(TFieldType))) and
  1913.      (CreateFieldList.ItemIndex <> -1) then
  1914.     ClientData.FieldDefList[CreateFieldList.ItemIndex].DataType :=
  1915.      TFieldType(CreateFieldType.ItemIndex);
  1916. end;
  1917.  
  1918. procedure TDBClientTest.CreateFieldSizeChange(Sender: TObject);
  1919. begin
  1920.   if (CreateFieldSize.Text <> '') and (CreateFieldList.ItemIndex <> -1) and
  1921.      (ClientData.FieldDefList.Count > 0) then
  1922.     ClientData.FieldDefList[CreateFieldList.ItemIndex].Size := StrToInt(CreateFieldSize.Text);
  1923. end;
  1924.  
  1925. procedure TDBClientTest.CreateDataSetDescKeyPress(Sender: TObject;
  1926.   var Key: Char);
  1927. begin
  1928.   with Sender as TComboBox do
  1929.     if Key = #13 then
  1930.     begin
  1931.        DroppedDown := False;
  1932.        OnClick(Sender);
  1933.        Key := #0;
  1934.     end;
  1935. end;
  1936.  
  1937. procedure TDBClientTest.CreateDataSetDescClick(Sender: TObject);
  1938. begin
  1939.   if not CreateDataSetDesc.DroppedDown then
  1940.     UpdateFieldList;
  1941. end;
  1942.  
  1943. procedure TDBClientTest.UpdateFieldList;
  1944. type
  1945.   TFieldTypes = array of TFieldType;
  1946.   TCreateOption = (coArrayOfADT, coADTWithArray, coNestedADT, coNestedDataSet);
  1947.   TCreateOptions = set of TCreateOption;
  1948.  
  1949. const
  1950.   ScalarTypes: array[0..11] of TFieldType = (ftSmallint, ftString,
  1951.     ftInteger, ftWord, ftBoolean, ftFloat, ftCurrency, ftBCD, ftLargeint,
  1952.     ftDate, ftTime, ftDateTime); { ftBytes, ftVarBytes, ftAutoInc }
  1953.  
  1954.   BlobTypes: array[0..1] of TFieldType = (ftMemo, ftGraphic);
  1955.   ObjectTypes: array[0..4] of TFieldType = (ftInteger, ftADT, ftArray,
  1956.     ftDataSet, ftString);
  1957.  
  1958.   ArrayDataSet: array[0..2] of TFieldType = (ftInteger, ftArray, ftInteger);
  1959.   ADTDataSet: array[0..2] of TFieldType = (ftInteger, ftADT, ftLargeInt);
  1960.  
  1961.   ADTWithScalar: array[0..1] of TFieldType = (ftString, ftWord);
  1962.   ADTWithArray: array[0..2] of TFieldType = (ftString, ftArray, ftWord);
  1963.   ADTWithADT: array[0..2] of TFieldType = (ftString, ftADT, ftDate);
  1964.  
  1965.   NestedDataSet: array[0..2] of TFieldType = (ftInteger, ftDataSet, ftString);
  1966.  
  1967.   ArrayOfScalar: array[0..0] of TFieldType = (ftFloat);
  1968.   ArrayOfADT: array[0..0] of TFieldType = (ftADT);
  1969.  
  1970.  
  1971.   procedure AddFieldTypes(FieldTypes: array of TFieldType;
  1972.     FieldDefs: TFieldDefs; CreateOptions: TCreateOptions);
  1973.   var
  1974.     I, BaseID: Integer;
  1975.     FT: TFieldType;
  1976.     ParentDef: TFieldDef;
  1977.     FN: string;
  1978.   begin
  1979.     BaseID := 0;
  1980.     ParentDef := FieldDefs.ParentDef;
  1981.     while ParentDef <> nil do
  1982.     begin
  1983.       Inc(BaseID, ParentDef.Index);
  1984.       ParentDef := ParentDef.ParentDef;
  1985.     end;
  1986.     for I := Low(FieldTypes) to High(FieldTypes) do
  1987.     begin
  1988.       FT := FieldTypes[I];
  1989.       with FieldDefs.AddFieldDef do
  1990.       begin
  1991.         FN := Format('%s%s%d', [FieldTypeNames[FT], 'Field', I+1+BaseID]);
  1992.         Name := FN;
  1993.         DataType := FT;
  1994.         case FT of
  1995.           ftADT, ftDataSet:
  1996.             if coADTWithArray in CreateOptions then
  1997.               AddFieldTypes(ADTWithArray, ChildDefs, [])
  1998.             else if coNestedADT in CreateOptions then
  1999.             begin
  2000.               if BaseID > 0 then CreateOptions := [];
  2001.               AddFieldTypes(ADTWithADT, ChildDefs, CreateOptions)
  2002.             end
  2003.             else if coNestedDataSet in CreateOptions then
  2004.             begin
  2005.               if BaseID > 0 then CreateOptions := [];
  2006.               AddFieldTypes(NestedDataSet, ChildDefs, CreateOptions)
  2007.             end
  2008.             else
  2009.               AddFieldTypes(ADTWithScalar, ChildDefs, []);
  2010.           ftArray:
  2011.             if coArrayOfADT in CreateOptions then
  2012.               AddFieldTypes(ArrayOfADT, ChildDefs, CreateOptions) else
  2013.               AddFieldTypes(ArrayOfScalar, ChildDefs, []);
  2014.         end;
  2015.       end;
  2016.     end;
  2017.   end;
  2018.  
  2019. begin
  2020.   ClientData.Close;
  2021.   ClientData.FieldDefs.Clear;
  2022.   case CreateDataSetDesc.ItemIndex of
  2023.     0: AddFieldTypes(ScalarTypes, ClientData.FieldDefs, []);
  2024.     1: AddFieldTypes(ObjectTypes, ClientData.FieldDefs, []);
  2025.     2: AddFieldTypes(ArrayDataSet, ClientData.FieldDefs, []);
  2026.     3: AddFieldTypes(ArrayDataSet, ClientData.FieldDefs, [coArrayOfADT]);
  2027.     4: AddFieldTypes(ArrayDataSet, ClientData.FieldDefs, [coArrayOfADT, coNestedADT]);
  2028.     5: AddFieldTypes(ADTDataSet, ClientData.FieldDefs, []);
  2029.     6: AddFieldTypes(ADTDataSet, ClientData.FieldDefs, [coADTWithArray]);
  2030.     7: AddFieldTypes(ADTDataSet, ClientData.FieldDefs, [coNestedADT]);
  2031.  
  2032.     8: AddFieldTypes(NestedDataSet, ClientData.FieldDefs, []);
  2033.     9: AddFieldTypes(NestedDataSet, ClientData.FieldDefs, [coNestedADT]);
  2034.     10: AddFieldTypes(NestedDataSet, ClientData.FieldDefs, [coNestedDataSet]);
  2035.   end;
  2036.   CreateFieldList.Items := ClientData.FieldDefList;
  2037.   if CreateFieldList.Items.Count > 0 then
  2038.   begin
  2039.     CreateFieldList.ItemIndex := 0;
  2040.     CreateFieldListClick(CreateFieldList);
  2041.   end;
  2042. end;
  2043.  
  2044. procedure TDBClientTest.CreateFieldListClick(Sender: TObject);
  2045. var
  2046.   FieldDef: TFieldDef;
  2047. begin
  2048.   if CreateFieldList.ItemIndex >= 0 then
  2049.   begin
  2050.     FieldDef := ClientData.FieldDefList[CreateFieldList.ItemIndex];
  2051.     CreateFieldType.Text := FieldTypeNames[FieldDef.DataType];
  2052.     CreateFieldSize.Text := IntToStr(FieldDef.Size);
  2053.     CreateFieldRequired.Checked := FieldDef.Required;
  2054.     if FieldDef.ParentDef <> nil then
  2055.       CreateFieldParent.Text := FieldDef.ParentDef.Name else
  2056.       CreateFieldParent.Text := '';
  2057.   end;
  2058. end;
  2059.  
  2060. procedure TDBClientTest.InsertData(DataSet: TDataSet; Rows, Start: Integer);
  2061.  
  2062.   procedure InsertValues(RowNum: Integer; Fields: TFields);
  2063.   const
  2064.     NumberType: array[0..2] of Integer = (1,-1,0);
  2065.   var
  2066.     I: Integer;
  2067.     F: TField;
  2068.     Value: Variant;
  2069.  
  2070.     function Mixer: Integer;
  2071.     begin
  2072.       if MixedData.Checked then
  2073.         Result := NumberType[(RowNum - F.FieldNo) mod 3] else
  2074.         Result := 1;
  2075.     end;
  2076.  
  2077.   begin
  2078.     Inc(RowNum, Start);
  2079.     for I := 0 to Fields.Count - 1 do
  2080.     begin
  2081.       F := Fields[I];
  2082.       Value := Null;
  2083.       case F.DataType of
  2084.         ftFloat, ftCurrency, ftBCD:
  2085.           Value := RowNum * (RowNum / 10) * Mixer;
  2086.         ftLargeInt:
  2087.           TLargeIntField(F).AsLargeInt := RowNum * Mixer;
  2088.         ftInteger, ftSmallint:
  2089.           Value := RowNum * Mixer;
  2090.         ftWord:
  2091.           Value := Word(RowNum * Abs(Mixer));
  2092.         ftBoolean:
  2093.           Value := Odd(RowNum + Mixer);
  2094.         ftDataSet, ftAutoInc: {NOP};
  2095.         ftDate, ftTime, ftDateTime:
  2096.           Value := (Now + RowNum + (RowNum / 1000));
  2097.         ftADT, ftArray:
  2098.           InsertValues(RowNum, TObjectField(F).Fields);
  2099.         else
  2100.           Value := RowNum * Mixer;
  2101.       end;
  2102.       if Value <> Null then
  2103.       begin
  2104.         if VarToStr(Value) = '0' then Value := Null;
  2105.         if F.DataType = ftLargeInt then
  2106.           TLargeIntField(F).AsLargeInt := Integer(Value) else
  2107.           F.Value := Value;
  2108.       end;
  2109.     end;
  2110.   end;
  2111.  
  2112.   function FindNestedDataSet(DataSet: TDataSet): TDataSet;
  2113.   var
  2114.     I: Integer;
  2115.   begin
  2116.     Result := nil;
  2117.     with DataSet do
  2118.       for I := 0 to FieldCount - 1 do
  2119.       begin
  2120.         if Fields[I] is TDataSetField then
  2121.         begin
  2122.           Result := TDataSetField(Fields[I]).NestedDataSet;
  2123.           Break;
  2124.         end;
  2125.       end;
  2126.   end;
  2127.  
  2128. var
  2129.   I: Integer;
  2130.   NestedDataSet: TDataSet;
  2131. begin
  2132.   with DataSet do
  2133.   begin
  2134.     DisableControls;
  2135.     try
  2136.       NestedDataSet := FindNestedDataSet(DataSet);
  2137.       for I := 1 to Rows do
  2138.       begin
  2139.         Append;
  2140.         InsertValues(I, Fields);
  2141.         Post;
  2142.         UpdateCursorPos;
  2143.         if NestedDataSet <> nil then
  2144.           InsertData(NestedDataSet, Rows, RecNo-1);
  2145.       end;
  2146.       First;
  2147.     finally
  2148.       EnableControls;
  2149.     end;
  2150.   end;
  2151. end;
  2152.  
  2153. procedure TDBClientTest.CreateClientData(Sender: TObject);
  2154. begin
  2155.   ClientData.Data := Null;
  2156.   ClientData.IndexDefs.Clear;
  2157.   ClientData.ProviderName := '';
  2158.   ClientData.CreateDataSet;
  2159.   ClientData.FieldDefs.Update;
  2160.   if DataRows.Text <> '' then
  2161.     InsertData(ClientData, StrToInt(DataRows.Text), 0);
  2162.   ActiveDataSet := ClientData;
  2163. end;
  2164.  
  2165. procedure TDBClientTest.AddFieldButtonClick(Sender: TObject);
  2166. begin
  2167.   ShowMessage('Not Implemented');
  2168. end;
  2169.  
  2170. procedure TDBClientTest.CreateFieldParentDropDown(Sender: TObject);
  2171. var
  2172.   I: Integer;
  2173. begin
  2174.   with CreateFieldParent.Items do
  2175.   begin
  2176.     Clear;
  2177.     Add('');
  2178.     for I := 0 to ClientData.FieldDefs.Count - 1 do
  2179.       AddObject(ClientData.FieldDefs[I].Name, ClientData.FieldDefs[I]);
  2180.   end;
  2181. end;
  2182.  
  2183. { Event Logging }
  2184.  
  2185. procedure TDBClientTest.LogEvent(const EventStr: string;
  2186.   Component: TComponent = nil);
  2187. var
  2188.   ItemCount: Integer;
  2189. begin
  2190.   if not Events.Visible then Exit;
  2191.   if (Component <> nil) and (Component.Name <> '') then
  2192.     Events.Items.Add(Format('%s(%s)', [EventStr, Component.Name])) else
  2193.     Events.Items.Add(EventStr);
  2194.   ItemCount := Events.Items.Count;
  2195.   Events.ItemIndex := ItemCount - 1;
  2196.   if ItemCount > (Events.ClientHeight div Events.ItemHeight) then
  2197.     Events.TopIndex := ItemCount - 1;
  2198. end;
  2199.  
  2200. procedure TDBClientTest.ClearEventLogExecute(Sender: TObject);
  2201. begin
  2202.   Events.Items.Clear;
  2203. end;
  2204.  
  2205. procedure TDBClientTest.ClearEventLogUpdate(Sender: TObject);
  2206. begin
  2207.   ClearEventLog.Enabled := Events.Visible and (Events.Items.Count > 0);
  2208. end;
  2209.  
  2210. procedure TDBClientTest.BDEProviderBeforeUpdateRecord(Sender: TObject;
  2211.   SourceDS: TDataSet; DeltaDS: TClientDataSet; UpdateKind: TUpdateKind;
  2212.   var Applied: Boolean);
  2213. begin
  2214.   LogEvent('BeforeUpdateRecord');
  2215. end;
  2216.  
  2217. procedure TDBClientTest.BDEProviderAfterUpdateRecord(Sender: TObject;
  2218.   SourceDS: TDataSet; DeltaDS: TClientDataSet; UpdateKind: TUpdateKind);
  2219. begin
  2220.   LogEvent('AfterUpdateRecord');
  2221. end;
  2222.  
  2223. function TDBClientTest.BDEProviderDataRequest(Sender: TObject;
  2224.   Input: OleVariant): OleVariant;
  2225. begin
  2226.   LogEvent('OnDataRequest');
  2227. end;
  2228.  
  2229. procedure TDBClientTest.BDEProviderGetData(Sender: TObject;
  2230.   DataSet: TClientDataSet);
  2231. begin
  2232.   LogEvent('OnGetData');
  2233. end;
  2234.  
  2235. procedure TDBClientTest.BDEProviderUpdateData(Sender: TObject;
  2236.   DataSet: TClientDataSet);
  2237. begin
  2238.   LogEvent('OnUpdate');
  2239. end;
  2240.  
  2241. procedure TDBClientTest.BDEProviderUpdateError(Sender: TObject;
  2242.   DataSet: TClientDataSet; E: EUpdateError; UpdateKind: TUpdateKind;
  2243.   var Response: TResolverResponse);
  2244. begin
  2245.   LogEvent('OnUpdateError');
  2246. end;
  2247.  
  2248. procedure TDBClientTest.BDEProviderGetDataSetProperties(Sender: TObject;
  2249.   DataSet: TDataSet; out Properties: OleVariant);
  2250. begin
  2251.   LogEvent('OnGetDataSetProperties');
  2252. end;
  2253.  
  2254. procedure TDBClientTest.ClientDataAfterScroll(DataSet: TDataSet);
  2255. begin
  2256.   LogEvent('AfterScroll', DataSet);
  2257. end;
  2258.  
  2259. procedure TDBClientTest.ClientDataBeforeCancel(DataSet: TDataSet);
  2260. begin
  2261.   LogEvent('BeforeCancel');
  2262. end;
  2263.  
  2264. procedure TDBClientTest.ClientDataBeforeDelete(DataSet: TDataSet);
  2265. begin
  2266.   LogEvent('BeforeDelete', DataSet);
  2267. end;
  2268.  
  2269. procedure TDBClientTest.ClientDataBeforeEdit(DataSet: TDataSet);
  2270. begin
  2271.   LogEvent('BeforeEdit', DataSet);
  2272. end;
  2273.  
  2274. procedure TDBClientTest.ClientDataBeforeInsert(DataSet: TDataSet);
  2275. begin
  2276.   LogEvent('BeforeInsert', DataSet);
  2277. end;
  2278.  
  2279. procedure TDBClientTest.ClientDataBeforePost(DataSet: TDataSet);
  2280. begin
  2281.   LogEvent('BeforePost', DataSet);
  2282. end;
  2283.  
  2284. procedure TDBClientTest.ClientDataBeforeScroll(DataSet: TDataSet);
  2285. begin
  2286.   LogEvent('BeforeScroll', DataSet);
  2287. end;
  2288.  
  2289. procedure TDBClientTest.ClientDataCalcFields(DataSet: TDataSet);
  2290. begin
  2291.   LogEvent('OnCalcFields', DataSet);
  2292. end;
  2293.  
  2294. procedure TDBClientTest.ClientDataDeleteError(DataSet: TDataSet;
  2295.   E: EDatabaseError; var Action: TDataAction);
  2296. begin
  2297.   LogEvent('OnDeleteError', DataSet);
  2298. end;
  2299.  
  2300. procedure TDBClientTest.ClientDataNewRecord(DataSet: TDataSet);
  2301. begin
  2302.   LogEvent('OnNewRecord', DataSet);
  2303. end;
  2304.  
  2305. procedure TDBClientTest.ClientDataAfterPost(DataSet: TDataSet);
  2306. begin
  2307.   LogEvent('AfterPost', DataSet);
  2308. end;
  2309.  
  2310. procedure TDBClientTest.ClientDataAfterInsert(DataSet: TDataSet);
  2311. begin
  2312.   LogEvent('AfterInsert', DataSet);
  2313. end;
  2314.  
  2315. procedure TDBClientTest.ClientDataAfterEdit(DataSet: TDataSet);
  2316. begin
  2317.   LogEvent('AfterEdit', DataSet);
  2318. end;
  2319.  
  2320. procedure TDBClientTest.ClientDataAfterDelete(DataSet: TDataSet);
  2321. begin
  2322.   LogEvent('AfterDelete', DataSet);
  2323. end;
  2324.  
  2325. procedure TDBClientTest.ClientDataAfterCancel(DataSet: TDataSet);
  2326. begin
  2327.   LogEvent('AfterCancel', DataSet);
  2328. end;
  2329.  
  2330. procedure TDBClientTest.DataSourceStateChange(Sender: TObject);
  2331. begin
  2332.   LogEvent('OnStateChange', Sender as TComponent);
  2333. end;
  2334.  
  2335. procedure TDBClientTest.DataSourceUpdateData(Sender: TObject);
  2336. begin
  2337.   LogEvent('OnUpdateData', Sender as TComponent);
  2338. end;
  2339.  
  2340. procedure TDBClientTest.MasterTableBeforeScroll(DataSet: TDataSet);
  2341. begin
  2342.   LogEvent('BeforeScroll', DataSet);
  2343. end;
  2344.  
  2345. procedure TDBClientTest.MasterTableAfterScroll(DataSet: TDataSet);
  2346. begin
  2347.   LogEvent('AfterScroll', DataSet);
  2348. end;
  2349.  
  2350. procedure TDBClientTest.TestButton1Click(Sender: TObject);
  2351. begin
  2352.   { Add your test code here }
  2353. end;
  2354.  
  2355.  
  2356. end.
  2357.