DA18 –说明MiniWH范例

 
DA18 – 说明 MiniWH 范例
导论
MiniWH (WareHouse) 范例在 Data Abstract 3.0 中引入 , 展示了多层应用程序中的完成通常需求任务的例子 .
包含的主题 :
  • MiniWH 功能
  • 如果安装并开始
  • 登陆
  • 运行业务帮助类
  • 自动处理
  • 过滤和良好设计
  • 跨数据的元素
  • MSSQLIB SQL的差异
  • SQL
  • 服务文件综述
  • 客户端文件综述
  • 总结
注意 : 图片被压缩了 , 如果看不清请点击放大 .
 
其他 :
[ 讨论了新的 TDADesigntimeCall 组件 . 这个组件可以在设计时拖放到窗体后设置其远程查询并运行 ; 主要用于测试服务 ]
 
MiniWH 功能
 
如何安装和启动
MiniWH 范例是 Data Abstract 3.0 自带的 , 存放于 /Samples/MiniWH 目录 , 启动项目组 (MiniWH.bpg).
Data Abstract 的一个最重要的特性就是可以透明的处理多种数据库 . MiniWh 配置了四个数据库连接 : ADO, IBX, IBO SDAC. 然而 , 很多人不会使用后两个 , 它们被禁用或启用非常简单 . 查看支持文件 MiniWH.inc:
{.$DEFINE SDAC}
{.$DEFINE IBO}
要启用其中的一个或两个 , 只需要适当的删除 '.'.
接下来 , 我们要确信连接可用并使用了正确的连接路径等 . 有两种方式 : 使用 ConnectionManager 组件或通过 Schema( 其中提供了连接字符串向导 ).
使用 ConnectionManager ( fServerDataModule ) 你只需要打开其连接集合并使用标准的连接编辑方式生成连接字符串 .
双击 Schema( 如在 LoginService_Impl 中的 LoginSchema ) 调用 Schema Modeler 你可能会发现使用连接字符串向导很简单 :
DA18 –说明MiniWH范例_第1张图片
点击上面指向的按钮 :
DA18 –说明MiniWH范例_第2张图片
登陆
这个主题讨论如何使用新的 DALoginService 服务对象创建一个登陆服务 .
当你运行 MiniWH 客户端 , 登陆界面如图 :
DA18 –说明MiniWH范例_第3张图片
如果你输入匹配的用户名和密码 , 客户端创建将显示出来 . 输入三次错误密码客户端将退出 . 如何实现的呢 ?
首先 , 禁用主窗体自动显示特性 : 在项目源文件 (MiniWHClient.dpr) 中设置 Application.ShowMainForm FALSE:
begin
  Application.Initialize;
   Application.ShowMainForm := FALSE;
 Application.Title := 'MiniWH Client' ;
 Application.CreateForm(TClientDataModule, ClientDataModule);
 Application.CreateForm(TClientForm, ClientForm);
 Application.Run;
end .
fClientForm.FormCreate 事件中显示登陆窗体 :
procedure TClientForm.FormCreate(Sender: TObject);
begin
  Caption := Application.Title;
 Application.OnHint := DisplayHint;
 actLogin.Execute;
end ;
你将会注意到调用了 actLogin.Execute, 而且其也设置菜单和工具栏按钮 , 允许你不用退出客户端就可以切换用户 :
procedure TClientForm.actLoginExecute(Sender: TObject);
begin
  Visible := FALSE;
 if Login then begin
    Visible := TRUE;
    ApplySecurity;
 end
 else Application.Terminate;
end ;
Login 过程包含在 fLoginForm 之中 , 我们首先看一下 ApplySecurity 方法 :
procedure TClientForm.ApplySecurity;
begin
 with ClientDataModule do begin
    StatusBar.Panels[ 0 ].Text := 'Logged in as '
                    + UpperCase(ClientDataModule.LoginInfo.UserID)
                    + ', ' +UserRoleNames[UserRole];
 
    actUsers.Enabled := (UserRole=rAdmin);
    actStatistics.Enabled := (UserRole in [rAdmin, rPowerUser]);
 end;
end ;
这里简单的向用户显示信息 . 很快就可以看到如何设置 Login.UserID UserRole. 正如你想象的这是一个强大的集中存取控制方法 .
现在我们查看 fLoginForm 中的 Login 方法 :
function Login : boolean;
begin
 with TLoginForm.Create(NIL) do try
    result := (ShowModal=mrOK)
 finally
    Free;
 end;
end ;
 
procedure TLoginForm.bbOKClick(Sender: TObject);
begin
 if ClientDataModule.Login(eUserID.Text, ePassword.Text) then
    ModalResult := mrOK
 else begin
    MessageDlg( 'Invalid login' , mtWarning, [mbOK], 0 );
    Dec(fTries);
    if (fTries<= 0 ) then ModalResult := mrCancel;
 end;
end ;
 
procedure TLoginForm.FormCreate(Sender: TObject);
begin
  fTries := 3 ;
end ;
这个 Login 方法很普通 , 我们感兴趣的代码是 ClientDataModule.Login:
function TClientDataModule.Login(const aUserID,
 aPassword: string): boolean;
var i : integer;
    attrname, attrvalue : string;
begin
  result := (svcLoginService as ILoginService).Login(
              aUserID, aPassword, fLoginInfo);
 
 if result then with fLoginInfo do begin
    for i := 0 to (Attributes.Count- 1 ) do begin
      attrname:=Copy(Attributes[i], 1 ,Pos( '=' ,Attributes[i])- 1 );
      attrvalue:=Copy(Attributes[i],Pos( '=' ,Attributes[i])+ 1 ,MaxInt);
 
     if SameText(attrname, fld_GetUserInfoUserIdx)
        then fUserIdx := StrToInt(attrvalue)
 
      else if SameText(attrname, fld_GetUserInfoUserRole)
        then fUserRole := StrToUserRole(attrvalue);
    end;
 
    LoadLookupData;
 
 end;
end ;
这里实际上调用了 DALOginService 服务 . svcLoginService 是一个 dmClientDataModule 中的 TRORemoteService 组件 :
DA18 –说明MiniWH范例_第4张图片
切换到服务端项目查看 Service Builder ( 通过 RemObjects | Edit Service Library) 我们将看到 :
DA18 –说明MiniWH范例_第5张图片
注意 LoginService 继承自新的 DALoginService, 这里不需要做任何变动 . 当然也可以在这里按需增加一些方法和参数 . DALoginService 定义如下 :
DA18 –说明MiniWH范例_第6张图片
查看参数列表 , 你将看到一个声明为 Out TDALoginInfo 类型的 LoginInfo 参数 . 记得客户端调用的 svcLoginService 服务吗 ? 那里有一个声明为 TDALoginInfo 类型的 fLoginInfo 参数 , 客户端从服务端接收的 LoginInfo 就是这里声明的 . TDALoginInfo 定义如下 :
DA18 –说明MiniWH范例_第7张图片
LoginInfo DALoginService.Login 处理 ( DA3 源码目录的 DALoginService_Impl ), 实际上调用了 DoLogin 方法 :
function TDALoginService.DoLogin(
       const UserID: String; const Password: String;
       out LoginInfo: TDALoginInfo): boolean;
var ds : IDADataset;
    i : integer;
begin
  result := FALSE;
 LoginInfo := NIL;
 
 ds := ServiceSchema.NewDataset(
                Connection, LoginDataset,
                [ParamNameUserID, ParamNamePassword],
                [UserID, Password]);
 if ds.EOF then Exit;
 
 LoginInfo := TDALoginInfo.Create;
 LoginInfo.UserID := UserID;
 LoginInfo.SessionID := GUIDToString(Session.SessionID);
 
 for i := 0 to (ds.FieldCount- 1 ) do begin
    Session[ds.Fields[i].Name] := ds.Fields[i].Value;
    LoginInfo.Attributes.Add(
      ds.Fields[i].Name+ '=' +ds.Fields[i].AsString);
 end;
 
 result := TRUE;
end ;
注意是如何处理 UserID, SessionID 字段属性的 . 你可以重写 DoLogin 方法提供自己的处理 Privileges 和数据字段的方法 . 服务也提供了一些事件 :
DA18 –说明MiniWH范例_第8张图片
OnLogin 包含 :
procedure TLoginService.DALoginServiceLogin(Sender: TDALoginService;
 var aUserID, aPassword: String);
begin
  aPassword := EncryptPassword(aPassword);
   {
    The select statement that returns the user record should not be
    case sensitive in respect of the UserID. Different databases handle
    case sensitivity in different ways.
    For instance, SQL Server would return "John" even if your WHERE
    statement said "WHERE Name='JoHn'".
    Interbase, however, wouldn't return any rows.
 
    In order to handle database differences, make use of DA's Macros
    (such as "UpperCase" - check it out using the Schema Modeler).
    The SQL is converted into the appropriate dialect at runtime.
 }
  aUserID := UpperCase(aUserID);
end ;
从而总结了 DALOginService 处理常用需求以及提供的自定义控制 .
 
运行业务帮助类
自动处理 autoinc
[DA3 新特性 ]
筛选和良好的设计
[ 本范例涉及很多常见问题 ]
跨数据库要素
[ 集中于跨数据库要素以及如何无代码实现 ]
MSSQL IB SQL 差异
 
SQL
[ 讨论 ]
 
服务端文件综述
DA18 –说明MiniWH范例_第9张图片
截图中高亮文件也用于客户端项目 . 注意如何将这些业务文件 ( 可能要在其中编码的 ) 放置在不同的目录 .
 
AdminService_Impl
同所有的 '..._Impl' 文件一样 , 这个单元在读取项目相关的 RODL 文件后由 RemObjects SDK 自动生成 , 并在这里编写实现代码 .
其中包含 ChangePassword 逻辑 .
BaseMiniWHService_Impl
这是除了 LoginService 外都要继承的基础服务 . 父类与使用什么连接什么时候调用方法等具体逻辑隔离开 . 查看 TBaseMiniWHService.DoOnActivate 的说明 .
此外 , BINAdapter 连接到数据模块中的 SessionManage.
fServerDataModule
这个单元包含所有以单例模式实例化组件并在程序运行中维护其生命周期 ..
HTTPServer BINMessage 负责接收通过 HTTP 及具体方法调用传递的远程消息 . 客户端第一个要调用的方法是 LoginService Login 方法 .
DriverManager, ADODriver IBXDriver 与数据库连接的组件 . 将他们作为拖放后就遗忘的组件 . 从来不会在代码中直接存取他们 , 他们基本上就是在 Data Abstract 单元中加一个引用指示连接到 ADOExpress, Interbase Express Data Abstract 引擎单元 .
我们要将所有的数据库连接放置于 ConnectionManager 组件中 . 点击这个组件查看其 Connections 属性 , 将看到当前定义的连接 . 这些默认配置可以在运行时通过修改 DBConnections.xml 文件而做出调整 .
点击 TServerDataModule.DataModuleCreate 查看这里的特殊实现代码 .
这时服务端可以使用 ADO 连接到 MSSQL 数据库或 SDAC( 假设你在 MiniWH.inc 中激活了 SDAC 定义 ) 通过 Interbase Express/ IBObjects 连接到 Interbase( 这些也是在 MiniWH.inc 中控制 ). 以后将向这个范例加入 Oracle, Sybase 等数据库支持 .
SessionManager 组件将维护一个内存的用户 Session 列表 , 我们可以从中存取如用户 ID, 角色等信息 . TLoginService DALoginServiceLoginSuccess 方法中可以查看我们能在 Session 存储什么信息 .
最后 DataDictionary 组件包含一下可夸 Schema 使用的字段属性 ( 例如 , Address1, Zip City). 每个服务的 Schema 都指向这个主要的数据字典 . 当我们使用数据字典条目的时候可在 Schema 中检查各种字段 .
fServerForm
这个主服务窗口在服务启动是显示 . 其中包含了一个 ComboBox 组件允许你在运行时修改连接 .
LoginSchemaClient_Intf
这个自动生成的单元包含客户端服务端都使用的常量信息 . 你可以修改这些值为 DataTable 的规则 ID 指定一个更可读的值 , 但是必须保证在你的应用程序中唯一 .
LoginSchemaServer_Intf
这个生成的单元包含服务端使用的常量 . 可以修改这些值为 Delta 规则 ID 指定更可读的值 , 但是必须保证在你的应用程序中唯一 .
LoginService_Impl
这个单元中包含了继承自 Data Abstract 基础类 TDALoginService LoginService 的实现 .
TDALoginService 提供了一个包含 Login Logout 方法的简单接口 . 更多信息见这个单元的注释 .
MiniWHLibrary_Intf
这个单元是自动生成的 , 你不需要修改它 .
MiniWHLibrary_Invk
这个单元是自动生成的 , 你不需要修改它 .
ProductsSchemaClient_Intf
这个生成的单元中包含用于服务端和客户端的常量信息 . 你可以在这里为 DataTable 的规则 ID 修改为一个更可读的值 , 但是必须保证在你的应用程序中唯一 .
ProductsSchemaServer_Intf
这个生成的单元包含服务端使用的常量信息 . 你可以在这里为 DataTable 的规则 ID 修改为一个更可读的值 , 但是必须保证在你的应用程序中唯一 .
ProductsService_Impl
在这个服务中检查 Schema 中声明的 UpdateRules . 这里不需要一行代码就能实现原来的 BasicDADemo 范例的功能 !
uBizLogin.pas
这里包含登陆处理相关的业务逻辑 . 定义了两个方法 : EncryptPassword StrToUserRole. 注意 : 为了范例便于理解这里也很简单 .
 
客户端文件综述
DA18 –说明MiniWH范例_第10张图片
上面截图中高亮文件也用于服务端项目 .
 
AdminSchemaClient_Intf
 
Summary
 

你可能感兴趣的:(Data,Abstract文档翻译)