程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> MIDAS中動態強制約束編程

MIDAS中動態強制約束編程

編輯:Delphi
引言
  
  一個用來區分 MIDAS 與其他分布式數據庫解決方案的特征就是,MIDAS 支持動態數據約束(constraints
  
  )功能。這些動態約束可以控制由 APPServer 到瘦客戶端的分布式數據的外觀、業務確認規則、是否顯示等等
  
  功能。作者(John Kaster)認為這是分布式數據庫需具備的一個非常重要的特征。
  
  MIDAS 數據包(Data Packets)概述
  先介紹一下MIDAS 數據包(Data Packets)格式的詳細特征,MIDAS 數據包(Data Packets)是一個獨立
  
  於語言和中立傳輸(transport-neutral)的二進制流格式數據,他包括元數據(metadata), 約束(
  
  constraints), 數據(data), 和deltas。
  元數據是用來描述按照 APPSERVER 來分布的數據集。 MIDAS 2,3 支持嵌套數據集,因此單個數據包能夠
  
  包含一個乃至於多個數據集的信息。約束是用來校驗和顯示數據集中的每個欄位的相關業務規則。Data 是數據
  
  集的實際數據欄位和記錄數。Deltas 記錄客戶端的數據修改的 Log ,且是屬於自動維護和傳送到 APPServer
  
  中的。
  
  MIDAS 數據欄位約束
  
  數據欄位約束是在 APPServer 與客戶程序之間傳播,可以快速修改業務規則,非常簡便的發布新的客戶程
  
  序,基於服務器端的業務規則,可以自動強制應用於客戶程序,從而增強了分布式應用系統的生存周期以及系
  
  統的可維護性。
  如果沒有充分的理由,應在客戶端強迫執行基於服務器端的業務規則,這樣將會提供應用系統的可靠性和
  
  數據的准確性,因為有問題的數據包會立即被客戶程序檢測到,所以應該培養正確的使用數據值和減少無效數
  
  據的網絡回路的習慣。簡單一點說,數據約束能讓你快速構建分布式系統,及時響應相關修改要求和提高系統
  
  的可靠性
  MIDAS 2、3 數據包能夠自動的由 APPServer 到客戶端傳遞以下數據欄位屬性:
  Constraint Property Description
  ----------------------------------------------------------------------------------------------
  ConstraintErrorMessage Message to display if data for the fIEld if not valid.
  Example: CustNo cannot be blank
  CustomConstraint Constraints to place on the validation of the fIEld. Expressions
  can be used for this constraint.
  Example: CustNo IS NOT NULL
  DisplayFormat Controls formatting of the fIEld for display
  DisplayLabel Used as the data fIEld's default column heading.
  Example: Customer #
  EditMask Used for customizing data entry for the fIEld.
  Example: 0000
  MaxValue The maximum value of a numeric fIEld
  MinValue The minimum value of a numeric fIEld
  Visible A boolean value indicating whether the fIEld should be visible in
  a grid by default
  實現約束編輯服務器(Constraint Editor Server)
  
  只要客戶連接到 MIDAS Server ,相關RDM(remote data module)就會自動創建並提供給客戶來訪問Server
  約束編輯服務器(ConstraintSvr.exe)在第一次使用這些RDM時會去獲取 provider 的列表和包含在這些
  
  provider 中欄位約束。ConstraintSvr 也同樣為編輯每個provider中的欄位約束提供一個用戶接口和為每個應
  
  用實例保存更改結果。
  在更改結果保存後(在系統運行期),客戶程序只需要簡單的重新連接的 APPServer,獲取一個新的數據
  
  包,此包中包含新的業務約束。
  變量角色(A Cast of Variants)
  開始建立一個能夠提供運行期編輯數據約束的應用程序,只需要做一點點代碼定制。Screen 對象有一個屬
  
  性可以列出一個應用程序中的所有數據模塊(data modules),同樣我們能通過檢查此屬性來建立包含在數據
  
  模塊中的Provider 的列表。此 Provider 名列表是通過一個變量類型從數據模塊中輸出,同樣也需要通過適當
  
  的Delphi 類型來接收數據模塊的 Provider 命名。代碼如下:
  
  { Copyright (c) 1999 - 2000 by John Kaster, Dan Miser and Louis Kleiman }
  procedure GetProviderList( ProviderList : TStrings );
  var
  ProviderNames : OLEVariant;
  I : Integer;
  DataSet : TDataSet;
  GenObject : TComponent;
  begin
  if (Screen.DataModuleCount = 0) then
  Raise Exception.Create( 'No data modules are active.' );
  ProviderList.Clear;
  { Get the list of all providers for the first data module.
  All instances of the data module are probably the same. }
  ProviderNames := IConstraints(TConstraints(Screen.DataModules[0])).
  AS_GetProviderNames;
  for I := VarArrayLowBound(ProviderNames, 1) to
  VarArrayHighBound(ProviderNames, 1) do
  begin
  { RetrIEve the component matching the provider name }
  GenObject := Screen.DataModules[0].FindComponent(ProviderNames[I]);
  if (GenObject is TDataSetProvider) then
  DataSet := TDataSetProvider(Screen.DataModules[0].
  FindComponent(ProviderNames[I])).DataSet
  else if (GenObject is TDBDataSet) then
  DataSet := TDataSet(Screen.DataModules[0].
  FindComponent(ProviderNames[I]))
  else
  DataSet := nil;
  { Add it to the list of providers, attaching the Dataset if assigned }
  ProviderList.AddObject(ProviderNames[I], DataSet);
  end; { for }
  end; { GetProviderList() }
  
  接收約束內容
  
  現在從RDM的實例獲取 provider 列表,其他的都是一些傳統的 Delphi 代碼。通過一個列表框元件來顯示
  
  Provider ,通過另一個列表框元件來顯示每個提供者的欄位約束值。 Provider列表框元件命名為lbProviders
  
  。代碼如下:
  
  procedure TFormConstraintsEditor.lbProvidersClick(Sender: TObject);
  var
  DataSet : TDataSet;
  I : Integer;
  SaveActive : Boolean;
  begin
  lbFIElds.Clear;
  DataSet := TDataSet(lbProviders.Items.Objects[lbProviders.ItemIndex]);
  if Assigned(DataSet) then
  begin
  SaveActive := DataSet.Active;
  DataSet.Open;
  try
  for I := 0 to DataSet.FIEldCount - 1 do
  lbFields.Items.AddObject(DataSet.Fields[I].FIEldName,
  DataSet.FIElds[I]);
  finally
  DataSet.Active := SaveActive;
  end; { try...finally }
  end; { if }
  end;
  
  編輯約束內容值
  現在使用編輯元件來為所選的欄位賦值。拖放這些控件到表單上,然後在下面的click 事件中將相應的選
  
  取的欄位的約束屬性值賦值給編輯元件。 字段欄位列表框元件命名為lbFIElds 。代碼如下:
  
  procedure TFormConstraintsEditor.lbFIEldsClick(Sender: TObject);
  var
  Field : TFIEld;
  begin
  Field := TField(lbFields.Items.Objects[lbFIElds.ItemIndex]);
  if Assigned(FIEld) then
  begin
  edErrorMessage.Text := FIEld.ConstraintErrorMessage;
  edCustomConstraint.Text := FIEld.CustomConstraint;
  edDisplayLabel.Text := FIEld.DisplayLabel;
  edEditMask.Text := FIEld.EditMask;
  edDisplayFormat.Text := ';
  edMinValue.Text := ';
  edMaxValue.Text := ';
  cbVisible.Checked := FIEld.Visible;
  if Field is TNumericFIEld then
  begin
  with Field as TNumericFIEld do
  edDisplayFormat.Text := DisplayFormat;
  if Field is TFloatFIEld then
  with Field as TFloatFIEld do
  begin
  edMinValue.Text := FloatToStr( MinValue );
  edMaxValue.Text := FloatToStr( MaxValue );
  end
  else if Field is TBCDFIEld then
  with Field as TBCDFIEld do
  begin
  edMinValue.Text := FloatToStr( MinValue );
  edMaxValue.Text := FloatToStr( MaxValue );
  end
  else if Field is TIntegerFIEld then
  with Field as TIntegerFIEld do
  begin
  edMinValue.Text := IntToStr( MinValue );
  edMaxValue.Text := IntToStr( MaxValue );
  end
  else if Field is TLargeIntFIEld then
  with Field as TLargeIntFIEld do
  begin
  edMinValue.Text := IntToStr( MinValue );
  edMaxValue.Text := IntToStr( MaxValue );
  end;
  end
  else if Field is TDateTimeFIEld then
  with Field as TDateTimeFIEld do
  edDisplayFormat.Text := DisplayFormat;
  end; { if }
  end;
  
  提交已編輯的約束值
  
  在給字段欄位約束賦給了相應的值後,需提交應用這些約束值。代碼如下:
  
  procedure TFormConstraintsEditor.actApplyExecute(Sender: TObject);
  var
  Field : TFIEld;
  begin
  Field := TField(lbFields.Items.Objects[lbFIElds.ItemIndex]);
  if Assigned(FIEld) then
  begin
  FIEld.ConstraintErrorMessage := edErrorMessage.Text;
  FIEld.CustomConstraint := edCustomConstraint.Text;
  FIEld.DisplayLabel := edDisplayLabel.Text;
  FIEld.EditMask := edEditMask.Text;
  FIEld.Visible := cbVisible.Checked;
  if Field is TNumericFIEld then
  begin
  with Field as TNumericFIEld do
  DisplayFormat := edDisplayFormat.Text;
  if Field is TFloatFIEld then
  with Field as TFloatFIEld do
  begin
  MinValue := StrToInt( edMinValue.Text );
  MaxValue := StrToInt( edMaxValue.Text );
  end
  else if Field is TBCDFIEld then
  with Field as TBCDFIEld do
  begin
  MinValue := StrToInt( edMinValue.Text );
  MaxValue := StrToInt( edMaxValue.Text );
  end
  else if Field is TIntegerFIEld then
  with Field as TIntegerFIEld do
  begin
  MinValue := StrToInt( edMinValue.Text );
  MaxValue := StrToInt( edMaxValue.Text );
  end
  else if Field is TLargeIntFIEld then
  with Field as TLargeIntFIEld do
  begin
  MinValue := StrToInt( edMinValue.Text );
  MaxValue := StrToInt( edMaxValue.Text );
  end;
  end
  else if Field is TDateTimeFIEld then
  with Field as TDateTimeFIEld do
  DisplayFormat := edDisplayFormat.Text;
  end; { if }
  end;
  
  現已創建了 ConstraintSvr 的主要代碼,詳細代碼可以下載。
  
  
  創建強制約束的客戶程序
  
  客戶程序比創建服務器程序簡單多拉,因為他只需要簡單的接收一個修改後的數據包,而無須有編寫
  
  Server 的知識。這是一個非常完美和強勁的動態約束程序示例:我們只需要在服務器端修改相關業務而無須修
  
  改客戶程序,也無須發布新的客戶程序。
  通過以下步驟建立客戶端程序:
  拖一個 DCOMConnection 元件
  設置: RemoteServer=ConstraintSvr.Constraints
  拖一個 ClIEntDataset 元件
  設置: RemoteServer=DCOMConnection1
  設置: ProviderName=prvCustomer
  拖一個 DataSource
  設置: DataSet=ClIEntDataset1
  拖一個 DBNavigator
  設置: DataSource=DataSource1
  拖一個 Button
  設置: Name=btnOpen
  雙擊 button 建立 click 事件,btnOpenClick 事件代碼如下:
  procedure TFormConstraintClIEnt.BtnOpenClick(Sender: TObject);
  begin
  if ClIEntDataSet1.Active then
  ClIEntDataSet1.Close;
  ClIEntDataSet1.Open; { Refresh the dataset }
  BtnOpen.Caption := '&Reopen';
  end;
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved