git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.RemObjects@46 b6239004-a887-0f4b-9937-50029ccdca16
1096 lines
42 KiB
ObjectPascal
1096 lines
42 KiB
ObjectPascal
unit DARemoteService_Impl {$IFNDEF FPC}deprecated{$ENDIF};
|
|
|
|
{----------------------------------------------------------------------------}
|
|
{ Data Abstract Library - Core Library }
|
|
{ }
|
|
{ compiler: Delphi 6 and up, Kylix 3 and up }
|
|
{ platform: Win32, Linux }
|
|
{ }
|
|
{ (c)opyright RemObjects Software. all rights reserved. }
|
|
{ }
|
|
{ Using this code requires a valid license of the Data Abstract }
|
|
{ which can be obtained at http://www.remobjects.com. }
|
|
{----------------------------------------------------------------------------}
|
|
|
|
{----------------------------------------------------------------------------}
|
|
{ LEGACY NOTE: }
|
|
{ As of v4.0, future development of this unit has been discontinued, and }
|
|
{ new featureswill be impleentd in DataAbstractService_Impl.pas, instead. }
|
|
{ }
|
|
{ When applying fixes to this unit, please propagate them to the new unit }
|
|
{ as well, where needed. }
|
|
{----------------------------------------------------------------------------}
|
|
|
|
{$I DataAbstract.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils,
|
|
{$IFDEF DELPHI5}Forms, {$ENDIF}
|
|
uRORemoteDataModule, uROClientIntf, uROSessions, uROClasses, uROTypes,
|
|
uDAClasses, uDAInterfaces, uDADataTable, uDABusinessProcessor, uDACache, uDADelta, uDADataStreamer,
|
|
uDADataTableReferenceCollection, DataAbstract3_Intf;
|
|
|
|
type
|
|
{ Types }
|
|
TDARemoteService = class;
|
|
|
|
{ Events }
|
|
TDAAcquireConnectionEvent = procedure(Sender: TDARemoteService; var ConnectionName: string) of object;
|
|
TDAConnectionAcquiredEvent = procedure(Sender: TDARemoteService; const ConnectionName: string; const AcquiredConnection: IDAConnection) of object;
|
|
TDAAcquireConnectionFailureEvent = procedure(Sender: TDARemoteService; const ConnectionName: string; Error: Exception) of object;
|
|
TDAGetDatasetSchemaEvent = procedure(const Dataset: IDADataset) of object;
|
|
TDAGetDatasetDataEvent = procedure(const Dataset: IDADataset; const IncludeSchema: Boolean; const MaxRecords: Integer) of object;
|
|
TDAOnBusinessProcessorAutoCreated = procedure(Sender : TRORemoteDataModule; BusinessProcessor : TDABusinessProcessor) of object;
|
|
TDABeforeExecuteCommandEvent = procedure(Sender : TDARemoteService; const aCommand : IDASQLCommand) of object;
|
|
TDAAfterExecuteCommandEvent = procedure(Sender : TDARemoteService; const aCommand : IDASQLCommand; RowsAffacted : integer) of object;
|
|
TDAConnectionReleasedEvent = procedure(Sender: TDARemoteService; const ConnectionName: string) of object;
|
|
TDAGetSchemaAsXMLEvent = procedure(Sender: TDARemoteService; var SchemaXML : AnsiString) of object;
|
|
|
|
TDAProcessDeltasEvent = procedure(Sender : TDARemoteService; DeltaStructs : TDADeltaStructList) of object;
|
|
TDAProcessDeltasErrorEvent = procedure(Sender : TDARemoteService; DeltaStructs : TDADeltaStructList; Error : Exception; var DoRaise : boolean) of object;
|
|
|
|
TDAOnGetCachedDataset = procedure(Sender : TDARemoteService; const aDatasetName : string; aDataStream : TStream) of object;
|
|
|
|
TDAGetDatasetDataValidationEvent = procedure(Sender: TDARemoteService;
|
|
const aConnection: IDAConnection;
|
|
const aDatasetName: string;
|
|
const aParamNames: array of string;
|
|
const aParamValues : array of variant;
|
|
aSchema: TDASchema;
|
|
var Allowed : boolean) of object;
|
|
|
|
TDAUpdateDataTransactionEvent = procedure(Sender: TDARemoteService; var UseDefaultTransactionLogic: Boolean) of object;
|
|
|
|
TDAAfterProcessTransactionAction = (pptaNone, pptaRollback, pptaCommit);
|
|
|
|
{ TDARemoteService }
|
|
TDARemoteServiceOption = (rsoProcessDeltasWithoutUpdateRules);
|
|
TDARemoteServiceOptions = set of TDARemoteServiceOption;
|
|
|
|
TDARemoteService = class(TRORemoteDataModule, IDARemoteService)
|
|
private
|
|
fServiceSchema: TDASchema;
|
|
|
|
fStreamedAcquireConnection,
|
|
fAcquireConnection: boolean;
|
|
fConnectionName: string;
|
|
fOnBeforeAcquireConnection: TDAAcquireConnectionEvent;
|
|
fOnAfterAcquireConnection: TDAConnectionAcquiredEvent;
|
|
fOnAfterReleaseConnection: TDAConnectionReleasedEvent;
|
|
fOnBeforeReleaseConnection: TDAConnectionAcquiredEvent;
|
|
fConnection: IDAConnection;
|
|
fServiceAdapter: TDADataStreamer;
|
|
fOnAcquireConnectionFailure: TDAAcquireConnectionFailureEvent;
|
|
|
|
fOnAfterGetDatasetData: TDAGetDatasetDataEvent;
|
|
fOnBeforeGetDatasetData: TDAGetDatasetDataEvent;
|
|
fOnAfterGetDatasetSchema: TDAGetDatasetSchemaEvent;
|
|
fOnBeforeGetDatasetSchema: TDAGetDatasetSchemaEvent;
|
|
fAutoCreateBusinessProcessors: boolean;
|
|
fAllowExecuteSQLCommand: boolean;
|
|
fAllowWhereSQL: boolean;
|
|
fOnBusinessProcessorAutoCreated: TDAOnBusinessProcessorAutoCreated;
|
|
fOnBeforeExecuteCommand: TDABeforeExecuteCommandEvent;
|
|
fOnAfterExecuteCommand: TDAAfterExecuteCommandEvent;
|
|
fOnGetSchemaAsXML: TDAGetSchemaAsXMLEvent;
|
|
|
|
fGetDatasetDataValidation: TDAGetDatasetDataValidationEvent;
|
|
|
|
fAfterProcessTransactionAction: TDAAfterProcessTransactionAction;
|
|
|
|
fOnUpdateDataBeginTransaction : TDAUpdateDataTransactionEvent;
|
|
fOnUpdateDataCommitTransaction : TDAUpdateDataTransactionEvent;
|
|
fOnUpdateDataRollBackTransaction : TDAUpdateDataTransactionEvent;
|
|
|
|
fOnBeforeProcessDeltas : TDAProcessDeltasEvent;
|
|
fOnAfterProcessDeltas: TDAProcessDeltasEvent;
|
|
fOnProcessDeltasError: TDAProcessDeltasErrorEvent;
|
|
fExportedDataTables: TDADataTableReferenceCollection;
|
|
fCache: TDACache;
|
|
fCacheElements: TDACacheElementCollection;
|
|
fOnGetCachedDataset: TDAOnGetCachedDataset;
|
|
fOptions: TDARemoteServiceOptions;
|
|
|
|
function TriggerTransactionEvent(aEvent: TDAUpdateDataTransactionEvent): Boolean;
|
|
procedure SetServiceSchema(const Value: TDASchema);
|
|
procedure SetAcquireConnection(const Value: boolean);
|
|
procedure SetConnectionName(const Value: string);
|
|
procedure SetServiceAdapter(const Value: TDADataAdapter);
|
|
function UnpackDeltas(const DeltaStream: Binary; DeltaStructList : TDADeltaStructList): integer;
|
|
procedure SetExportedDataTables(const Value: TDADataTableReferenceCollection);
|
|
procedure MergeDatatablesToSchema(aList : TList);
|
|
procedure SetCache(const Value: TDACache);
|
|
procedure SetCacheElements(const Value: TDACacheElementCollection);
|
|
procedure SetConnection(const aValue: IDAConnection);
|
|
|
|
protected
|
|
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
|
procedure Loaded; override;
|
|
|
|
procedure CheckObjects(const aConnection: IDAConnection;
|
|
aSchema: TDASchema; anAdapter: TDADataAdapter;
|
|
CheckConnection : boolean = TRUE;
|
|
CheckSchema : boolean = TRUE;
|
|
CheckAdapter : boolean = TRUE);
|
|
|
|
{ Internal }
|
|
procedure DoOnActivate(aClientID: TGUID; const aMessage: IROMessage); override;
|
|
procedure DoOnDeactivate(aClientID: TGUID); override;
|
|
|
|
function DoGetDatasetData(const Stream: TStream;
|
|
const aConnection: IDAConnection;
|
|
const aDatasetName: ansistring;
|
|
const aParamNames: array of string;
|
|
const aParamValues : array of variant;
|
|
const UserFilter : ansistring;
|
|
aSchema: TDASchema;
|
|
anAdapter: TDADataAdapter;
|
|
someOptions: TDAWriteOptions;
|
|
MaxRecords: integer): integer; virtual;
|
|
|
|
function CreateParamString(const ParamNames: array of string; const ParamValues: array of Variant): string;
|
|
|
|
function GetDatasetData(const DatasetName: ansistring;
|
|
const ParamNames: array of string;
|
|
const ParamValues: array of Variant;
|
|
const IncludeSchema: Boolean = FALSE;
|
|
const MaxRecords: Integer = -1): Binary; overload;
|
|
function GetDatasetData(const DatasetName: Ansistring;
|
|
const IncludeSchema: Boolean = FALSE;
|
|
const MaxRecords: Integer = -1): Binary; overload;
|
|
|
|
{ IDARemoteService }
|
|
function GetDatasetSchema(const aDatasetName: AnsiString): Binary; virtual;
|
|
function GetDatasetData(const DatasetName: AnsiString;
|
|
const Params: AnsiString;
|
|
const IncludeSchema: Boolean;
|
|
const MaxRecords: Integer): Binary; overload; virtual;
|
|
function UpdateData(const Delta: Binary): Binary; virtual;
|
|
function ExecuteSQLCommand(const SQL: AnsiString): Integer; virtual;
|
|
function GetSchemaAsXML: AnsiString; virtual;
|
|
function GetDatasetDataEx(const DatasetName: AnsiString;
|
|
const Params: TDADatasetParamArray;
|
|
const UserFilter: AnsiString;
|
|
const IncludeSchema: Boolean;
|
|
const MaxRecords: Integer): Binary;
|
|
function GetMultipleDatasets(const DatasetRequestInfoArray: TDADatasetRequestInfoArray): TROBinaryMemoryStream;
|
|
function GetDatasetScripts(const DatasetNames: AnsiString): AnsiString;
|
|
function ExecuteSQLCommandEx(const CommandName: AnsiString; const Params: TDADatasetParamArray): Integer;
|
|
|
|
public
|
|
constructor Create(aOwner : TComponent); override;
|
|
destructor Destroy; override;
|
|
|
|
property Connection: IDAConnection read fConnection write SetConnection;
|
|
|
|
published
|
|
property AcquireConnection: boolean read fAcquireConnection write SetAcquireConnection default false;
|
|
property ConnectionName: string read fConnectionName write SetConnectionName;
|
|
|
|
property ServiceSchema: TDASchema read fServiceSchema write SetServiceSchema;
|
|
property ServiceAdapter: TDADataAdapter read fServiceAdapter write SetServiceAdapter;
|
|
|
|
property AutoCreateBusinessProcessors : boolean read fAutoCreateBusinessProcessors write fAutoCreateBusinessProcessors default true;
|
|
property AllowExecuteSQLCommand: boolean read fAllowExecuteSQLCommand write fAllowExecuteSQLCommand default false;
|
|
property AllowWhereSQL: boolean read fAllowWhereSQL write fAllowWhereSQL default true;
|
|
|
|
property OnAfterProcessTransactionAction: TDAAfterProcessTransactionAction read fAfterProcessTransactionAction write fAfterProcessTransactionAction default pptaCommit;
|
|
|
|
property OnBeforeAcquireConnection: TDAAcquireConnectionEvent read fOnBeforeAcquireConnection write fOnBeforeAcquireConnection;
|
|
property OnAfterAcquireConnection: TDAConnectionAcquiredEvent read fOnAfterAcquireConnection write fOnAfterAcquireConnection;
|
|
property OnBeforeReleaseConnection: TDAConnectionAcquiredEvent read fOnBeforeReleaseConnection write fOnBeforeReleaseConnection;
|
|
property OnAfterReleaseConnection: TDAConnectionReleasedEvent read fOnAfterReleaseConnection write fOnAfterReleaseConnection;
|
|
property OnAcquireConnectionFailure: TDAAcquireConnectionFailureEvent read fOnAcquireConnectionFailure write fOnAcquireConnectionFailure;
|
|
|
|
property OnBeforeProcessDeltas : TDAProcessDeltasEvent read fOnBeforeProcessDeltas write fOnBeforeProcessDeltas;
|
|
property OnAfterProcessDeltas: TDAProcessDeltasEvent read fOnAfterProcessDeltas write fOnAfterProcessDeltas;
|
|
property OnProcessDeltasError: TDAProcessDeltasErrorEvent read fOnProcessDeltasError write fOnProcessDeltasError;
|
|
|
|
property OnBeforeGetDatasetSchema: TDAGetDatasetSchemaEvent read fOnBeforeGetDatasetSchema write fOnBeforeGetDatasetSchema;
|
|
property OnBeforeGetDatasetData: TDAGetDatasetDataEvent read fOnBeforeGetDatasetData write fOnBeforeGetDatasetData;
|
|
property OnAfterGetDatasetSchema: TDAGetDatasetSchemaEvent read fOnAfterGetDatasetSchema write fOnAfterGetDatasetSchema;
|
|
property OnAfterGetDatasetData: TDAGetDatasetDataEvent read fOnAfterGetDatasetData write fOnAfterGetDatasetData;
|
|
property OnBusinessProcessorAutoCreated: TDAOnBusinessProcessorAutoCreated read fOnBusinessProcessorAutoCreated write fOnBusinessProcessorAutoCreated;
|
|
property OnBeforeExecuteCommand: TDABeforeExecuteCommandEvent read fOnBeforeExecuteCommand write fOnBeforeExecuteCommand;
|
|
property OnAfterExecuteCommand: TDAAfterExecuteCommandEvent read fOnAfterExecuteCommand write fOnAfterExecuteCommand;
|
|
property OnGetSchemaAsXMLEvent: TDAGetSchemaAsXMLEvent read fOnGetSchemaAsXML write fOnGetSchemaAsXML;
|
|
property GetDatasetDataValidation: TDAGetDatasetDataValidationEvent read fGetDatasetDataValidation write fGetDatasetDataValidation;
|
|
|
|
property OnUpdateDataBeginTransaction : TDAUpdateDataTransactionEvent read fOnUpdateDataBeginTransaction write fOnUpdateDataBeginTransaction;
|
|
property OnUpdateDataCommitTransaction : TDAUpdateDataTransactionEvent read fOnUpdateDataCommitTransaction write fOnUpdateDataCommitTransaction;
|
|
property OnUpdateDataRollBackTransaction : TDAUpdateDataTransactionEvent read fOnUpdateDataRollBackTransaction write fOnUpdateDataRollBackTransaction;
|
|
|
|
property ExportedDataTables : TDADataTableReferenceCollection read fExportedDataTables write SetExportedDataTables;
|
|
property Cache : TDACache read fCache write SetCache;
|
|
property CacheElements : TDACacheElementCollection read fCacheElements write SetCacheElements;
|
|
property OnGetCachedDataset : TDAOnGetCachedDataset read fOnGetCachedDataset write fOnGetCachedDataset;
|
|
|
|
property Options : TDARemoteServiceOptions read fOptions write fOptions;
|
|
end deprecated;
|
|
|
|
implementation
|
|
|
|
uses
|
|
Contnrs, Variants, TypInfo,
|
|
uROClient,
|
|
uDARes, uDAExceptions;
|
|
|
|
{ TDARemoteService }
|
|
|
|
constructor TDARemoteService.Create(aOwner: TComponent);
|
|
begin
|
|
fExportedDataTables := TDADataTableReferenceCollection.Create(Self);
|
|
fCacheElements := TDACacheElementCollection.Create();
|
|
fOptions := [rsoProcessDeltasWithoutUpdateRules];
|
|
fAllowWhereSQL := true;
|
|
|
|
inherited;
|
|
|
|
fAutoCreateBusinessProcessors := TRUE;
|
|
end;
|
|
|
|
destructor TDARemoteService.Destroy;
|
|
begin
|
|
inherited;
|
|
|
|
FreeAndNIL(fExportedDataTables);
|
|
FreeAndNIL(fCacheElements);
|
|
end;
|
|
|
|
procedure TDARemoteService.DoOnActivate(aClientID: TGUID; const aMessage: IROMessage);
|
|
var
|
|
connname: string;
|
|
begin
|
|
inherited;
|
|
|
|
if (csDesigning in ComponentState) then Exit;
|
|
|
|
if AcquireConnection then try
|
|
// Acquires a DA connection automatically
|
|
if (fServiceSchema = nil) or (fServiceSchema.ConnectionManager = nil) then RaiseError(err_DARDMInvalidSchema);
|
|
|
|
connname := fConnectionName;
|
|
if Assigned(fOnBeforeAcquireConnection) then fOnBeforeAcquireConnection(Self, connname);
|
|
|
|
fConnection := ServiceSchema.ConnectionManager.NewConnection(connname);
|
|
if Supports(fConnection, IDAHETConnection) then
|
|
raise Exception.Create(err_HETConnectionNotSupportedInV3);
|
|
|
|
if Assigned(fOnAfterAcquireConnection) then fOnAfterAcquireConnection(Self, connname, fConnection);
|
|
except
|
|
on E: Exception do begin
|
|
if Assigned(fOnAcquireConnectionFailure) then fOnAcquireConnectionFailure(Self, connname, E);
|
|
raise;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TDARemoteService.DoOnDeactivate(aClientID: TGUID);
|
|
var connname : string;
|
|
begin
|
|
inherited;
|
|
|
|
if (csDesigning in ComponentState) then Exit;
|
|
|
|
if assigned(fConnection) then begin
|
|
connname := fConnection.Name;
|
|
|
|
if Assigned(fOnBeforeReleaseConnection)
|
|
then fOnBeforeReleaseConnection(Self, connname, fConnection);
|
|
|
|
fConnection := nil;
|
|
|
|
if Assigned(fOnAfterReleaseConnection)
|
|
then fOnAfterReleaseConnection(Self, connname);
|
|
end;
|
|
end;
|
|
|
|
procedure TDARemoteService.Loaded;
|
|
begin
|
|
inherited;
|
|
|
|
AcquireConnection := fStreamedAcquireConnection;
|
|
end;
|
|
|
|
procedure TDARemoteService.CheckObjects(const aConnection: IDAConnection;
|
|
aSchema: TDASchema; anAdapter: TDADataAdapter;
|
|
CheckConnection : boolean = TRUE;
|
|
CheckSchema : boolean = TRUE;
|
|
CheckAdapter : boolean = TRUE);
|
|
begin
|
|
if CheckConnection and not Assigned(aConnection) then RaiseError(err_DARDMConnectionIsNotAssigned);
|
|
if CheckSchema and not Assigned(aSchema) then RaiseError(err_DARDMInvalidSchema);
|
|
if CheckAdapter and not Assigned(anAdapter) then RaiseError(err_DARDMUnassignedAdapter);
|
|
end;
|
|
|
|
procedure TDARemoteService.Notification(AComponent: TComponent;
|
|
Operation: TOperation);
|
|
var ref : TDADataTableReference;
|
|
begin
|
|
inherited;
|
|
|
|
if (Operation = opRemove) then begin
|
|
if (aComponent = fServiceSchema) then ServiceSchema := nil
|
|
else if (AComponent=fCache) then fCache := NIL
|
|
else if (aComponent = fServiceAdapter) then ServiceAdapter := nil
|
|
else if (AComponent is TDADataTable) and (fExportedDataTables<>NIL) then begin
|
|
ref := fExportedDataTables.FindByDataTable(TDADataTable(aComponent));
|
|
if (ref<>NIL) then ref.DataTable := NIL;
|
|
end;
|
|
end
|
|
|
|
else if (Operation = opInsert) then begin
|
|
if not (csLoading in ComponentState) and (AComponent is TDASchema) and (fServiceSchema = nil) and (AComponent.Owner = Self) then ServiceSchema := TDASchema(aComponent);
|
|
end;
|
|
end;
|
|
|
|
procedure TDARemoteService.SetAcquireConnection(const Value: boolean);
|
|
begin
|
|
if (csLoading in ComponentState) then
|
|
fStreamedAcquireConnection := Value
|
|
else begin
|
|
if Value then begin
|
|
if (fServiceSchema = nil) then raise Exception.Create(err_DARDMInvalidSchema);
|
|
end;
|
|
|
|
fAcquireConnection := Value;
|
|
end;
|
|
end;
|
|
|
|
procedure TDARemoteService.SetConnection(const aValue: IDAConnection);
|
|
begin
|
|
if assigned(fConnection) and Supports(fConnection, IDAHETConnection) then
|
|
raise Exception.Create(err_HETConnectionNotSupportedInV3);
|
|
fConnection := aValue;
|
|
end;
|
|
|
|
procedure TDARemoteService.SetConnectionName(const Value: string);
|
|
begin
|
|
fConnectionName := Trim(Value);
|
|
if (fConnectionName = '') then fAcquireConnection := FALSE;
|
|
end;
|
|
|
|
procedure TDARemoteService.SetServiceSchema(const Value: TDASchema);
|
|
begin
|
|
fServiceSchema := Value;
|
|
|
|
if (fServiceSchema <> nil) then
|
|
fServiceSchema.FreeNotification(Self)
|
|
else
|
|
fAcquireConnection := FALSE;
|
|
end;
|
|
|
|
procedure TDARemoteService.SetServiceAdapter(const Value: TDADataAdapter);
|
|
begin
|
|
fServiceAdapter := Value;
|
|
if (fServiceAdapter <> nil) then fServiceAdapter.FreeNotification(Self);
|
|
end;
|
|
|
|
function TDARemoteService.TriggerTransactionEvent(aEvent: TDAUpdateDataTransactionEvent): Boolean;
|
|
begin
|
|
result := true;
|
|
if assigned(aEvent) then aEvent(self, result);
|
|
end;
|
|
|
|
function TDARemoteService.DoGetDatasetData(
|
|
const Stream: TStream;
|
|
const aConnection: IDAConnection;
|
|
const aDatasetName: ansistring;
|
|
const aParamNames: array of string;
|
|
const aParamValues : array of variant;
|
|
const UserFilter : ansistring;
|
|
aSchema: TDASchema;
|
|
anAdapter: TDADataAdapter;
|
|
someOptions: TDAWriteOptions;
|
|
MaxRecords: integer): integer;
|
|
|
|
var
|
|
ds: IDADataset;
|
|
i, cnt: integer;
|
|
paramname: string;
|
|
paramvalue: variant;
|
|
inclrows,
|
|
inclschema: boolean;
|
|
allow : boolean;
|
|
ref : TDADataTableReference;
|
|
cachedentry : IDACacheEntry;
|
|
cacheelement : TDACacheElement;
|
|
lDatasetName: string;
|
|
lUserFilter: string;
|
|
begin
|
|
// Misc
|
|
lDatasetName:= Utf8ToString(aDatasetName);
|
|
luserFilter := Utf8ToString(UserFilter);
|
|
cachedentry := NIL;
|
|
|
|
inclschema := (woSchema in someOptions);
|
|
inclrows := (woRows in someOptions);
|
|
ref := NIL;
|
|
|
|
if (fCache<>NIL) then begin
|
|
// If the service is connected to a cache, then it searches the cache for this dataset
|
|
cachedentry := fCache.Get(Self.Name+'.'+lDatasetName);
|
|
end;
|
|
|
|
if (cachedentry=NIL) then begin
|
|
// New: searches for a datatable reference that matches the request, if any are present
|
|
// This allows the user to return in memory datasets or other custom data
|
|
if (fExportedDataTables.Count>0) then begin
|
|
ref := fExportedDataTables.FindByName(lDatasetName); // Already checks the datatable is not NIL
|
|
if (ref<>NIL) then begin
|
|
ds := ref.Dataset;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
// Checks for connection, schema and adapter to be assigned since it will need to query the DB in this case
|
|
if (ref=NIL) and (cachedentry=NIL)
|
|
then CheckObjects(aConnection, aSchema, anAdapter);
|
|
|
|
// Security check, common to every case
|
|
allow := TRUE;
|
|
if Assigned(fGetDatasetDataValidation)
|
|
then fGetDatasetDataValidation(Self, aConnection, lDatasetName, aParamNames, aParamValues, aSchema, allow);
|
|
|
|
if not allow
|
|
then raise EDADatasetNotAccessible.CreateFmt(err_DatasetNotAccessible, [aDatasetName]);
|
|
|
|
// Returns the actual data. Cached and non-cached data follow two different paths (some events are not triggered in the
|
|
// case of cached data, since we don't have an actual IDADataset to reference)
|
|
|
|
if (cachedentry<>NIL) then begin
|
|
if Assigned(fOnGetCachedDataset) then fOnGetCachedDataset(Self, lDatasetName, cachedentry.Data);
|
|
|
|
result := cachedentry.RecordCount;
|
|
Stream.CopyFrom(cachedentry.Data, 0);
|
|
end
|
|
else begin
|
|
|
|
if TriggerTransactionEvent(fOnUpdateDataBeginTransaction) then Connection.BeginTransaction;
|
|
try
|
|
|
|
// Gets a reference to the dataset if it couldn't find a datatable to match the request...
|
|
if (ref=NIL) then
|
|
ds := aSchema.NewDataset(aConnection, lDatasetName);
|
|
|
|
// Fills the parameters (if any are specified)
|
|
cnt := Length(aParamNames);
|
|
if (cnt>0) then begin
|
|
for i := 0 to (cnt-1) do begin
|
|
paramname := aParamNames[i];
|
|
paramvalue := aParamValues[i];
|
|
|
|
ds.ParamByName(paramname).Value := paramvalue;
|
|
end;
|
|
end;
|
|
|
|
// Applies the UserFilter, if any specified
|
|
if (Trim(lUserFilter)<>'') then begin
|
|
if not AllowWhereSQL then
|
|
raise Exception.Create('Passing of clear text WHERE clauses has been disabled (GetData)');
|
|
ds.Where.AddText(lUserFilter);
|
|
end;
|
|
|
|
// ...and writes the data fireing the right events
|
|
if inclschema and Assigned(fOnBeforeGetDatasetSchema) then fOnBeforeGetDatasetSchema(ds);
|
|
if inclrows and Assigned(fOnBeforeGetDatasetData) then fOnBeforeGetDatasetData(ds, inclschema, MaxRecords);
|
|
|
|
result := anAdapter.WriteDataset(stream, ds, someOptions, MaxRecords);
|
|
|
|
if inclschema and Assigned(fOnAfterGetDatasetSchema) then fOnAfterGetDatasetSchema(ds);
|
|
if inclrows and Assigned(fOnAfterGetDatasetData) then fOnAfterGetDatasetData(ds, inclschema, MaxRecords);
|
|
|
|
if Connection.InTransaction and TriggerTransactionEvent(fOnUpdateDataCommitTransaction) then Connection.CommitTransaction;
|
|
except
|
|
if Connection.InTransaction and TriggerTransactionEvent(fOnUpdateDataRollBackTransaction) then Connection.RollbackTransaction;
|
|
raise;
|
|
end;
|
|
|
|
// Checks if it needs to stored it in the cache
|
|
if (fCache<>NIL) then begin
|
|
cacheelement := fCacheElements.FindByDatasetName(lDatasetName);
|
|
if (cacheelement=NIL) or not cacheelement.Enabled then Exit;
|
|
|
|
fCache.Store(Self.Name+'.'+lDatasetName, stream, TRUE, result, cacheelement.MaxReads, cacheelement.Duration);
|
|
end;
|
|
|
|
end;
|
|
end;
|
|
|
|
function TDARemoteService.GetDatasetSchema(
|
|
const aDatasetName: AnsiString): Binary;
|
|
var tempds : IDADataset;
|
|
schemads : TDADataset;
|
|
dummyrefs : TObjectList;
|
|
lDatasetName: string;
|
|
begin
|
|
dummyrefs := NIL;
|
|
|
|
CheckObjects(Connection, ServiceSchema, ServiceAdapter);
|
|
|
|
result := Binary.Create;
|
|
try
|
|
try
|
|
// New: merges the data tables references by the service
|
|
if (fExportedDataTables.Count>0) then begin
|
|
dummyrefs := TObjectList.Create;
|
|
MergeDatatablesToSchema(dummyrefs);
|
|
end;
|
|
|
|
lDatasetName := Utf8ToString(aDatasetName);
|
|
// Improved this method: now it is not necessary to have statements associated to a dataset
|
|
// thus allowing for the definition of in memory datasets inside a schema
|
|
schemads := ServiceSchema.Datasets.DatasetByName(lDatasetName);
|
|
tempds := Connection.NewDataset('', lDatasetName);
|
|
|
|
// Copies the schema
|
|
tempds.Fields.AssignFieldCollection(schemads.Fields);
|
|
tempds.Params.AssignParamCollection(schemads.Params);
|
|
|
|
ServiceAdapter.WriteDataset(result, tempds, [woSchema], 0);
|
|
except
|
|
FreeAndNIL(result);
|
|
raise;
|
|
end;
|
|
finally
|
|
dummyrefs.Free;
|
|
end;
|
|
end;
|
|
|
|
type
|
|
TBizProcessorReference = class(TObject)
|
|
private
|
|
end;
|
|
|
|
function TDARemoteService.UnpackDeltas(const DeltaStream: Binary;
|
|
DeltaStructList : TDADeltaStructList): integer;
|
|
var x, i: integer;
|
|
deltaname: string;
|
|
bizproc: TDABusinessProcessor;
|
|
details : TDADatasetRelationshipList;
|
|
found: boolean;
|
|
struct : TDADeltaStruct;
|
|
begin
|
|
result := 0;
|
|
with ServiceAdapter do begin
|
|
|
|
// Reads the deltas.
|
|
Initialize(DeltaStream, aiReadFromBeginning);
|
|
try
|
|
if (DeltaCount = 0) then Exit;
|
|
|
|
for i := 0 to (DeltaCount - 1) do begin
|
|
deltaname := DeltaNames[i];
|
|
found := FALSE;
|
|
|
|
{ Tries to locate a user-defined business processor }
|
|
for x := 0 to (Self.ComponentCount - 1) do
|
|
if (Self.Components[x] is TDABusinessProcessor) then begin
|
|
bizproc := TDABusinessProcessor(Self.Components[x]);
|
|
if SameText(bizproc.ReferencedDataset, deltaname) then begin
|
|
struct := DeltaStructList.Add(NewDelta(deltaname), bizproc);
|
|
ReadDelta(deltaname, struct.Delta);
|
|
|
|
found := TRUE;
|
|
Break;
|
|
end;
|
|
end;
|
|
|
|
{ Either creates one or aborts raising an exception }
|
|
if not found then begin
|
|
if not AutoCreateBusinessProcessors then RaiseError(err_DARDMCannotFindProxessorForDelta, [deltaname]);
|
|
|
|
bizproc := TDABusinessProcessor.Create(Self);
|
|
bizproc.ReferencedDataset := deltaname;
|
|
bizproc.Schema := ServiceSchema;
|
|
|
|
struct := DeltaStructList.Add(NewDelta(deltaname), bizproc);
|
|
ReadDelta(deltaname, struct.Delta);
|
|
|
|
if Assigned(fOnBusinessProcessorAutoCreated)
|
|
then fOnBusinessProcessorAutoCreated(Self, bizproc);
|
|
end;
|
|
|
|
Inc(result);
|
|
end;
|
|
|
|
if (result=0) then Exit; // Cannot process anything!
|
|
|
|
{ Sets the master/detail relationships }
|
|
with ServiceSchema do
|
|
if (RelationShips.Count>0) then begin
|
|
details := TDADatasetRelationshipList.Create;
|
|
try
|
|
|
|
for i := 0 to DeltaStructList.Count-1 do begin
|
|
RelationShips.GetDetails(DeltaStructList[i].BusinessProcessor.ReferencedDataset, details);
|
|
if (details.Count=0) then Continue;
|
|
|
|
{ Prepares an array with the references to the detail deltas that will be used later on to adjust
|
|
autoincs, etc. }
|
|
for x := 0 to details.Count-1 do begin
|
|
struct := DeltaStructList.FindStruct(details[x].DetailDatasetName);
|
|
if (struct<>NIL) then begin
|
|
DeltaStructList[i].DetailDeltas.Add(struct.Delta);
|
|
DeltaStructList[i].RelationShips.Add(details[x]);
|
|
end;
|
|
end;
|
|
end;
|
|
finally
|
|
details.Free;
|
|
end;
|
|
|
|
end;
|
|
finally
|
|
Finalize;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TDARemoteService.UpdateData(const Delta: Binary): Binary;
|
|
var
|
|
deltastructs : TDADeltaStructList;
|
|
struct : TDADeltaStruct;
|
|
k, i: integer;
|
|
doraise : boolean;
|
|
processeddeltas : TStringList;
|
|
|
|
function ProceedDefaultTransactionLogic(aEvent: TDAUpdateDataTransactionEvent): Boolean;
|
|
begin
|
|
Result := True;
|
|
if Assigned(aEvent)
|
|
then aEvent(Self, Result);
|
|
end;
|
|
|
|
procedure FlushCache(const aDatasetName : string);
|
|
var element : TDACacheElement;
|
|
begin
|
|
if (fCache=NIL) or (fCacheElements.Count=0) then Exit;
|
|
|
|
element := fCacheElements.FindByDatasetName(aDatasetName);
|
|
if (element=NIL) then Exit;
|
|
|
|
if (ceoFlushOnUpdate in element.Options)
|
|
then fCache.Flush(Self.Name+'.'+aDatasetName);
|
|
end;
|
|
|
|
begin
|
|
result := NIL;
|
|
processeddeltas := NIL;
|
|
|
|
CheckObjects(Connection, ServiceSchema, ServiceAdapter);
|
|
|
|
deltastructs := TDADeltaStructList.Create;
|
|
|
|
with ServiceAdapter do try
|
|
try
|
|
// Reads the deltas. The order in which the are put in the stream indicates
|
|
// the order in which updates are being made
|
|
if not (UnpackDeltas(Delta, deltastructs)>0) then Exit;
|
|
|
|
// Applies the updates
|
|
if ProceedDefaultTransactionLogic(fOnUpdateDataBeginTransaction)
|
|
then Connection.BeginTransaction;
|
|
|
|
if Assigned(fOnBeforeProcessDeltas) then fOnBeforeProcessDeltas(Self, deltastructs);
|
|
|
|
if (ServiceSchema.UpdateRules.Count=0) and (rsoProcessDeltasWithoutUpdateRules in Options) then begin
|
|
// Processes them in order, from first to last delta sent
|
|
for i := 0 to deltastructs.Count-1 do begin
|
|
// Flushes the cache for the given dataset
|
|
FlushCache(deltastructs[i].Delta.LogicalName);
|
|
|
|
deltastructs[i].BusinessProcessor.ProcessDelta(Connection, deltastructs[i].Delta, AllChanges);
|
|
end;
|
|
end
|
|
else try
|
|
processeddeltas := TStringList.Create;
|
|
|
|
for i := 0 to (ServiceSchema.UpdateRules.Count-1) do begin
|
|
// Processes them in the order defined in the schema
|
|
struct := deltastructs.FindStruct(ServiceSchema.UpdateRules[i].DatasetName);
|
|
if (struct<>NIL) then begin
|
|
// Adds the dataset name to the list of processed deltas. Those that don't have update rules will be processed later
|
|
processeddeltas.Add(struct.Delta.LogicalName);
|
|
|
|
// Flushes the cache for the given dataset
|
|
FlushCache(struct.Delta.LogicalName);
|
|
|
|
// Processes the delta
|
|
struct.BusinessProcessor.ProcessDelta(Connection, struct.Delta, ServiceSchema.UpdateRules[i].ChangeTypes);
|
|
|
|
|
|
if (ctInsert in ServiceSchema.UpdateRules[i].ChangeTypes) then begin
|
|
for k := 0 to (struct.DetailDeltas.Count-1) do
|
|
struct.BusinessProcessor.SynchronizeAutoIncs(struct.Delta, struct.DetailDeltas[k], struct.RelationShips[k]);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
// Processes the deltas for which update rules were not defined
|
|
if (rsoProcessDeltasWithoutUpdateRules in Options) then begin
|
|
for i := 0 to deltastructs.Count-1 do begin
|
|
// Skips if already processed
|
|
if (processeddeltas.IndexOf(deltastructs[i].Delta.LogicalName)>=0) then Continue;
|
|
|
|
// Flushes the cache for the given dataset
|
|
FlushCache(deltastructs[i].Delta.LogicalName);
|
|
|
|
deltastructs[i].BusinessProcessor.ProcessDelta(Connection, deltastructs[i].Delta, AllChanges);
|
|
end;
|
|
end;
|
|
|
|
finally
|
|
processeddeltas.Free;
|
|
end;
|
|
|
|
if Assigned(fOnAfterProcessDeltas) then fOnAfterProcessDeltas(Self, deltastructs);
|
|
|
|
if Connection.InTransaction and ProceedDefaultTransactionLogic(fOnUpdateDataCommitTransaction)
|
|
then Connection.CommitTransaction;
|
|
|
|
// Prepares the response
|
|
result := Binary.Create;
|
|
ServiceAdapter.Initialize(result, aiWrite);
|
|
try
|
|
for i := 0 to deltastructs.Count-1 do
|
|
WriteDelta(deltastructs[i].Delta);
|
|
finally
|
|
ServiceAdapter.Finalize;
|
|
end;
|
|
|
|
except
|
|
on E:Exception do begin
|
|
doraise := TRUE;
|
|
try
|
|
if Assigned(fOnProcessDeltasError)
|
|
then fOnProcessDeltasError(Self, deltastructs, E, doraise);
|
|
finally
|
|
if Connection.InTransaction and ProceedDefaultTransactionLogic(fOnUpdateDataRollBackTransaction)
|
|
then Connection.RollbackTransaction;
|
|
end;
|
|
if doraise then raise;
|
|
end;
|
|
end;
|
|
finally
|
|
deltastructs.Free;
|
|
end;
|
|
end;
|
|
|
|
function TDARemoteService.ExecuteSQLCommand(const SQL: AnsiString): Integer;
|
|
begin
|
|
if not AllowExecuteSQLCommand then
|
|
RaiseError(err_ExecuteSQLCommandNotAllowed);
|
|
|
|
CheckObjects(Connection, ServiceSchema, NIL, TRUE, TRUE, FALSE);
|
|
|
|
if TriggerTransactionEvent(fOnUpdateDataBeginTransaction) then Connection.BeginTransaction;
|
|
try
|
|
result := Connection.NewCommand(Utf8ToString(SQL), stSQL).Execute;
|
|
if Connection.InTransaction and TriggerTransactionEvent(fOnUpdateDataCommitTransaction) then Connection.CommitTransaction;
|
|
except
|
|
if Connection.InTransaction and TriggerTransactionEvent(fOnUpdateDataRollBackTransaction) then Connection.RollbackTransaction;
|
|
raise;
|
|
end;
|
|
end;
|
|
|
|
function TDARemoteService.GetDatasetData(const DatasetName: AnsiString; const Params: AnsiString;
|
|
const IncludeSchema: Boolean; const MaxRecords: Integer): Binary;
|
|
var
|
|
parnames: array of string;
|
|
parvalues: array of Variant;
|
|
options: TDAWriteOptions;
|
|
pars: TStringList;
|
|
i : integer;
|
|
begin
|
|
pars := TStringList.Create;
|
|
result := Binary.Create;
|
|
try
|
|
try
|
|
pars.Text := Utf8ToString(Params);
|
|
SetLength(parnames, pars.Count);
|
|
SetLength(parvalues, pars.Count);
|
|
for i := 0 to (pars.Count-1) do begin
|
|
parnames[i] := pars.Names[i];
|
|
parvalues[i] := pars.Values[pars.Names[i]];
|
|
end;
|
|
|
|
if IncludeSchema
|
|
then options := [woSchema, woRows]
|
|
else options := [woRows];
|
|
|
|
DoGetDatasetData(result, Connection, DatasetName, parnames, parvalues, '', ServiceSchema, ServiceAdapter, options, MaxRecords);
|
|
except
|
|
FreeAndNIL(result);
|
|
raise;
|
|
end;
|
|
finally
|
|
pars.Free;
|
|
end;
|
|
end;
|
|
|
|
function TDARemoteService.CreateParamString(
|
|
const ParamNames: array of string;
|
|
const ParamValues: array of Variant): string;
|
|
var
|
|
i: integer;
|
|
begin
|
|
result := '';
|
|
|
|
for i := 0 to High(ParamNames) do
|
|
result := result + ParamNames[i] + '=' + VarToStr(ParamValues[i]) + #13;
|
|
end;
|
|
|
|
function TDARemoteService.GetDatasetData(const DatasetName: ansistring;
|
|
const ParamNames: array of string; const ParamValues: array of Variant;
|
|
const IncludeSchema: Boolean; const MaxRecords: Integer): Binary;
|
|
var
|
|
options: TDAWriteOptions;
|
|
begin
|
|
{result := GetDatasetData(DatasetName, CreateParamString(ParamNames, ParamValues), IncludeSchema, MaxRecords);}
|
|
result := Binary.Create;
|
|
try
|
|
if IncludeSchema
|
|
then options := [woSchema, woRows]
|
|
else options := [woRows];
|
|
DoGetDatasetData(result, Connection, DatasetName, ParamNames, ParamValues, '', ServiceSchema, ServiceAdapter, options, MaxRecords);
|
|
except
|
|
FreeAndNIL(result);
|
|
raise;
|
|
end;
|
|
end;
|
|
|
|
function TDARemoteService.GetDatasetData(const DatasetName: ansistring;
|
|
const IncludeSchema: Boolean = FALSE;
|
|
const MaxRecords: Integer = -1): Binary;
|
|
begin
|
|
result := GetDatasetData(DatasetName, '', IncludeSchema, MaxRecords);
|
|
end;
|
|
|
|
procedure TDARemoteService.MergeDatatablesToSchema(aList : TList);
|
|
var i : integer;
|
|
ref : TDADataset;
|
|
dt : IDADataset;
|
|
begin
|
|
if (fExportedDataTables.Count>0) then begin
|
|
for i := 0 to fExportedDataTables.Count-1 do
|
|
if fExportedDataTables[i].IsValidReference {and fExportedDataTables[i].ExportAsPartOfSchema} then begin
|
|
dt := fExportedDataTables[i].Dataset;
|
|
|
|
ref := ServiceSchema.Datasets.Add;
|
|
ref.Name := dt.LogicalName;
|
|
ref.Fields.AssignFieldCollection(dt.Fields);
|
|
ref.Params.AssignParamCollection(dt.Params);
|
|
|
|
aList.Add(ref);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TDARemoteService.GetSchemaAsXML: AnsiString;
|
|
var xml : TStringStream;
|
|
dummyrefs : TObjectList;
|
|
begin
|
|
result := '';
|
|
dummyrefs := NIL;
|
|
|
|
if not Assigned(ServiceSchema) then Exit;
|
|
|
|
try
|
|
// New: merges the data tables references by the service
|
|
if (fExportedDataTables.Count>0) then begin
|
|
dummyrefs := TObjectList.Create;
|
|
MergeDatatablesToSchema(dummyrefs);
|
|
end;
|
|
|
|
// Returns the schema
|
|
xml := TStringStream.Create('');
|
|
try
|
|
ServiceSchema.SaveToStream(xml);
|
|
|
|
result := UTF8Encode(xml.DataString);
|
|
|
|
if Assigned(fOnGetSchemaAsXML)
|
|
then fOnGetSchemaAsXML(Self, result);
|
|
finally
|
|
xml.Free;
|
|
end;
|
|
|
|
finally
|
|
dummyrefs.Free; // automatically removes the datatables from the schema again
|
|
end;
|
|
end;
|
|
|
|
function TDARemoteService.GetDatasetDataEx(const DatasetName: AnsiString;
|
|
const Params: TDADatasetParamArray;
|
|
const UserFilter: AnsiString;
|
|
const IncludeSchema: Boolean;
|
|
const MaxRecords: Integer): Binary;
|
|
var parnames : array of string;
|
|
parvalues : array of variant;
|
|
i : integer;
|
|
options : TDAWriteOptions;
|
|
begin
|
|
result := Binary.Create;
|
|
try
|
|
{ Prepares the parameter arrays}
|
|
if (Params<>NIL) then begin
|
|
SetLength(parnames, Params.Count);
|
|
SetLength(parvalues, Params.Count);
|
|
for i := 0 to (Params.Count-1) do begin
|
|
parnames[i] := Utf8ToString(Params[i].Name);
|
|
parvalues[i] := Params[i].Value;
|
|
end;
|
|
end
|
|
else begin
|
|
SetLength(parnames, 0);
|
|
SetLength(parvalues, 0);
|
|
end;
|
|
|
|
{ Other options }
|
|
if IncludeSchema
|
|
then options := [woSchema, woRows]
|
|
else options := [woRows];
|
|
|
|
{ Reads the data }
|
|
DoGetDatasetData(result, Connection, DatasetName, parnames, parvalues, UserFilter, ServiceSchema, ServiceAdapter, options, MaxRecords);
|
|
except
|
|
FreeAndNIL(result);
|
|
raise;
|
|
end;
|
|
end;
|
|
|
|
function TDARemoteService.GetMultipleDatasets(const DatasetRequestInfoArray: TDADatasetRequestInfoArray): TROBinaryMemoryStream;
|
|
var i : integer;
|
|
ds : IDADataset;
|
|
parnames : array of string;
|
|
parvalues : array of variant;
|
|
x : integer;
|
|
opt : TDAWriteOptions;
|
|
allow : boolean;
|
|
lDatasetName: string;
|
|
begin
|
|
result := NIL;
|
|
if (DatasetRequestInfoArray=NIL) or (DatasetRequestInfoArray.Count=0) then exit;
|
|
result := Binary.Create;
|
|
try
|
|
ServiceAdapter.Initialize(result, aiWrite);
|
|
try
|
|
|
|
for i := 0 to (DatasetRequestInfoArray.Count-1) do begin
|
|
with DatasetRequestInfoArray[i] do begin
|
|
SetLength(parnames, Params.Count);
|
|
SetLength(parvalues, Params.Count);
|
|
for x := 0 to (Params.Count-1) do begin
|
|
parnames[x] := Utf8ToString(Params[x].Name);
|
|
parvalues[x] := Params[x].Value;
|
|
end;
|
|
lDatasetName := Utf8ToString(DatasetName);
|
|
opt := [woRows];
|
|
if DatasetRequestInfoArray[i].IncludeSchema then opt := opt+[woSchema];
|
|
|
|
// Security check
|
|
allow := TRUE;
|
|
if Assigned(fGetDatasetDataValidation)
|
|
then fGetDatasetDataValidation(Self, Connection, lDatasetName, parnames, parvalues, ServiceSchema, allow);
|
|
|
|
if not allow
|
|
then raise EDADatasetNotAccessible.CreateFmt(err_DatasetNotAccessible, [lDatasetName]);
|
|
|
|
// Proceeds
|
|
ds := ServiceSchema.NewDataset(Connection, lDatasetName, parnames, parvalues, TRUE);
|
|
|
|
ServiceAdapter.WriteDataset(ds, opt, MaxRecords);
|
|
end;
|
|
end;
|
|
finally
|
|
ServiceAdapter.Finalize();
|
|
end;
|
|
except
|
|
FreeAndNIL(result);
|
|
raise
|
|
end;
|
|
end;
|
|
|
|
function TDARemoteService.GetDatasetScripts(const DatasetNames: AnsiString): AnsiString;
|
|
var names : TStringList;
|
|
i : integer;
|
|
ds : TDADataset;
|
|
begin
|
|
result := '';
|
|
names := TStringList.Create;
|
|
try
|
|
CheckObjects(NIL, fServiceSchema, NIL, FALSE, TRUE, FALSE);
|
|
names.CommaText := Utf8ToString(DatasetNames);
|
|
|
|
result := '<Scripts>';
|
|
|
|
for i := 0 to (names.Count-1) do begin
|
|
ds := fServiceSchema.Datasets.DatasetByName(names[i]);
|
|
|
|
result := result+ {$IFDEF UNICODE}UTF8Encode{$ENDIF}(
|
|
Format('<%s Language="%s"><![CDATA[%s]]></%s>', [
|
|
names[i],
|
|
GetEnumName(TypeInfo(TROSEScriptLanguage), Ord(ds.BusinessRulesClient.ScriptLanguage)),
|
|
{$IFNDEF UNICODE}UTF8Encode{$ENDIF}(ds.BusinessRulesClient.Script),
|
|
names[i]]));
|
|
end;
|
|
|
|
result := result+AnsiString('</Scripts>');
|
|
finally
|
|
FreeAndNIL(names);
|
|
end;
|
|
end;
|
|
|
|
function TDARemoteService.ExecuteSQLCommandEx(const CommandName: AnsiString;
|
|
const Params: TDADatasetParamArray): Integer;
|
|
var cmd : IDASQLCommand;
|
|
i : integer;
|
|
begin
|
|
if not AllowExecuteSQLCommand then
|
|
RaiseError(err_ExecuteSQLCommandNotAllowed);
|
|
|
|
CheckObjects(Connection, ServiceSchema, NIL, TRUE, TRUE, FALSE);
|
|
|
|
cmd := ServiceSchema.NewCommand(Connection, Utf8ToString(CommandName));
|
|
for i := 0 to (Params.Count-1) do
|
|
cmd.ParamByName(Utf8ToString(Params[i].Name)).Value := Params[i].Value;
|
|
|
|
if Assigned(fOnBeforeExecuteCommand)
|
|
then fOnBeforeExecuteCommand(Self, cmd);
|
|
|
|
if TriggerTransactionEvent(fOnUpdateDataBeginTransaction) then Connection.BeginTransaction;
|
|
try
|
|
result := cmd.Execute;
|
|
if Connection.InTransaction and TriggerTransactionEvent(fOnUpdateDataCommitTransaction) then Connection.CommitTransaction;
|
|
except
|
|
if Connection.InTransaction and TriggerTransactionEvent(fOnUpdateDataRollBackTransaction) then Connection.RollbackTransaction;
|
|
raise;
|
|
end;
|
|
|
|
if Assigned(fOnAfterExecuteCommand)
|
|
then fOnAfterExecuteCommand(Self, cmd, result);
|
|
end;
|
|
|
|
procedure TDARemoteService.SetExportedDataTables(const Value: TDADataTableReferenceCollection);
|
|
begin
|
|
fExportedDataTables.Assign(Value);
|
|
end;
|
|
|
|
procedure TDARemoteService.SetCache(const Value: TDACache);
|
|
begin
|
|
fCache := Value;
|
|
if (fCache<>NIL)
|
|
then fCache.FreeNotification(Self);
|
|
end;
|
|
|
|
procedure TDARemoteService.SetCacheElements(
|
|
const Value: TDACacheElementCollection);
|
|
begin
|
|
fCacheElements.Assign(Value);
|
|
end;
|
|
|
|
end.
|