增强Delphi.RemObject.DataAbstract的脚本功能:多数据库同时操作

    我们知道,通过Schema,一个DataAbstracService对应一个数据库;一个服务器可以包含多个DataAbstracService,从而实现对多个数据库的操作。通过事件处理我们可以在一个DataAbstracService中去调用另一个DataAbstracService,从而实现同时操作多个数据库。目前在版本7.0.65中通过在Schema中写脚本还不能做到这一点。本人少量的改写了DataAbstract后,做到了这一点。下面是要修改的两个类定义:

    1、修改uDAEcmaScriptWrappers单元文件中的TDAEcmaLDAWrapper类,添加两个方法:   

    function newLDA(serviceName: string): TDAEcmaLDAWrapper;
     function executeCommand(commandName: string; parameters: variant): Integer;
    改写下面的方法:
     function ExecuteMethod(aMethodName: string; aParams: Variant): Variant; override;
     procedure IntCreate;

具体实现:

function TDAEcmaLDAWrapper.newLDA(serviceName: string): TDAEcmaLDAWrapper;
var
  Adapter: TDALocalDataAdapter;
begin
  Adapter := TDALocalDataAdapter.Create(serviceName);
  Adapter.SessionID := fLDA.SessionID;
  Result := TDAEcmaLDAWrapperClass(ClassType).Create(Adapter);
end;

function TDAEcmaLDAWrapper.executeCommand(commandName: string; parameters: variant): Integer;
var
  lParams, lOutParams: DataParameterArray;
begin
  lParams := VariantToDataParameterArray(parameters);
  Result := fLDA.ServiceInstance.ExecuteCommandEx(commandName, lParams, lOutParams);
  lOutParams.Free;
end;

function TDAEcmaLDAWrapper.ExecuteMethod(aMethodName: string; aParams: Variant): Variant;
begin
  ......
   // ============================================添加的代码
   else  if aMethodName =  'newLDA' then begin
    CheckParams(aMethodName,aParams, 1);
    Result := newLDA(aParams[ 0]).AsVariant;
  end
   else  if aMethodName =  'executeCommand' then begin
    CheckParams(aMethodName,aParams, 2);
    Result := executeCommand(aParams[ 0], aParams[ 1]);
  end
   //==============================================
   else begin
    Result := inherited ExecuteMethod(aMethodName,aParams);
  end;
end;
procedure TDAEcmaLDAWrapper.IntCreate;
begin
  RegisterMethod( 'insert');
  RegisterMethod( 'update');
  RegisterMethod( 'remove');
  RegisterMethod( 'discardChanges');
  RegisterMethod( 'applyChanges');
  RegisterMethod( 'selectSQL');
  RegisterMethod( 'selectWhere');
   //====================================添加的代码
  RegisterMethod( 'newLDA'); 
  RegisterMethod( 'executeCommand');  
   //====================================
  fDeltas:= TList.Create;
  fDeltaList := TDAEcmaSchemaNamedListWrapper.Create(fDeltas, IntWrap, IntFind);
  fSelectResultList:= TObjectList.Create(True);
end;

     2、修改uDAScriptContext单元文件中的TDAScriptContext类

function TDAScriptContext.CreateLDA: TDALocalDataAdapter;
begin
  Result := TDALocalDataAdapter.Create(nil);
  Result.ServiceInstance := fOwner;
  Result.DynamicSelect := True;
   //====================================添加的代码
  Result.SessionID := fOwner.ClientID; 
   //====================================
end;

  OK,修改完成。


  下面来看一个实例:

// Called before each change is applied to the database
function beforeProcessDeltaChange(delta, change, wasRefreshed, canRemove)
{
    if (change.isInsert)
    {
        var da = lda.newLDA("MainService");  // 获取另外一个LocalDataAdapter
        da.insert("CategoryTable", {"ID"22"Name""名称"}); 
        da.applyChanges();
        log("级联插入类别信息成功");
    }
    if (change.isDelete)
    {
        var da = lda.newLDA("OtherService");  // 获取另外一个LocalDataAdapter
        if (da.executeCommand("Product_DELETE", {"ID"22}) == 0)
            fail("级联删除失败");
        log(" 级联删除产品信息成功");
    }
}

  使用上面的方法,有点像写触发器,但可以同时操作多个数据库,而且可以是不同类型的数据库。此方法可以用来做数据集成平台。

  上面的代码已通过测试,欢迎大家指正!

原文地址:https://www.cnblogs.com/riskyer/p/3257937.html