home *** CD-ROM | disk | FTP | other *** search
/ Delphi Anthology / aDELPHI.iso / Runimage / Delphi50 / Source / Vcl / databkr.pas < prev    next >
Pascal/Delphi Source File  |  1999-08-11  |  10KB  |  319 lines

  1.  
  2. {*******************************************************}
  3. {                                                       }
  4. {       Borland Delphi Visual Component Library         }
  5. {       Remote Data Module support                      }
  6. {                                                       }
  7. {       Copyright (c) 1997,99 Inprise Corporation       }
  8. {                                                       }
  9. {*******************************************************}
  10.  
  11. unit DataBkr;
  12.  
  13. {$T-,H+,X+}
  14.  
  15. interface
  16.  
  17. uses Windows, ActiveX, Classes, Midas, Forms, Provider, SysUtils;
  18.  
  19. type
  20.   { TRemoteDataModule }
  21.  
  22.   TRemoteDataModule = class(TDataModule, IAppServer)
  23.   private
  24.     FProviders: TList;
  25.     FLock: TRTLCriticalSection;
  26.   protected
  27.     function GetProvider(const ProviderName: string): TCustomProvider; virtual;
  28.     class procedure UpdateRegistry(Register: Boolean; const ClassID, ProgID: string); override;
  29.     { IAppServer }
  30.     function AS_GetProviderNames: OleVariant; safecall;
  31.     function AS_ApplyUpdates(const ProviderName: WideString; Delta: OleVariant;
  32.       MaxErrors: Integer; out ErrorCount: Integer;
  33.       var OwnerData: OleVariant): OleVariant; safecall;
  34.     function AS_GetRecords(const ProviderName: WideString; Count: Integer;
  35.       out RecsOut: Integer; Options: Integer; const CommandText: WideString;
  36.       var Params, OwnerData: OleVariant): OleVariant; safecall;
  37.     function AS_DataRequest(const ProviderName: WideString;
  38.       Data: OleVariant): OleVariant; safecall;
  39.     function AS_GetParams(const ProviderName: WideString; var OwnerData: OleVariant): OleVariant; safecall;
  40.     function AS_RowRequest(const ProviderName: WideString; Row: OleVariant;
  41.       RequestType: Integer; var OwnerData: OleVariant): OleVariant; safecall;
  42.     procedure AS_Execute(const ProviderName: WideString;
  43.       const CommandText: WideString; var Params, OwnerData: OleVariant); safecall;
  44.   public
  45.     constructor Create(AOwner: TComponent); override;
  46.     destructor Destroy; override;
  47.     procedure RegisterProvider(Value: TCustomProvider); virtual;
  48.     procedure UnRegisterProvider(Value: TCustomProvider); virtual;
  49.     procedure Lock; virtual;
  50.     procedure Unlock; virtual;
  51.     property Providers[const ProviderName: string]: TCustomProvider read GetProvider;
  52.   end;
  53.  
  54. procedure RegisterPooled(const ClassID: string; Max, Timeout: Integer; Singleton: Boolean = False);
  55. procedure UnregisterPooled(const ClassID: string);
  56. procedure EnableSocketTransport(const ClassID: string);
  57. procedure DisableSocketTransport(const ClassID: string);
  58. procedure EnableWebTransport(const ClassID: string);
  59. procedure DisableWebTransport(const ClassID: string);
  60.  
  61. implementation
  62.  
  63. uses ComObj, MidConst;
  64.  
  65. { Utility routines }
  66.  
  67. procedure RegisterPooled(const ClassID: string; Max, Timeout: Integer;
  68.   Singleton: Boolean = False);
  69. begin
  70. { Do not localize }
  71.   CreateRegKey(SClsid + ClassID, SPooled, SFlagOn);
  72.   CreateRegKey(SClsid + ClassID, SMaxObjects, IntToStr(Max));
  73.   CreateRegKey(SClsid + ClassID, STimeout, IntToStr(Timeout));
  74.   if Singleton then
  75.     CreateRegKey(SClsid + ClassID, SSingleton, SFlagOn) else
  76.     CreateRegKey(SClsid + ClassID, SSingleton, SFlagOff);
  77. end;
  78.  
  79. procedure DeleteRegValue(const Key, ValueName: string);
  80. var
  81.   Handle: HKey;
  82.   Status: Integer;
  83. begin
  84.   Status := RegOpenKey(HKEY_CLASSES_ROOT, PChar(Key), Handle);
  85.   if Status = 0 then
  86.     RegDeleteValue(Handle, PChar(ValueName));
  87. end;
  88.  
  89. procedure UnregisterPooled(const ClassID: string);
  90. begin
  91.   DeleteRegValue(SClsid + ClassID, SPooled);
  92.   DeleteRegValue(SClsid + ClassID, SMaxObjects);
  93.   DeleteRegValue(SClsid + ClassID, STimeout);
  94.   DeleteRegValue(SClsid + ClassID, SSingleton);
  95. end;
  96.  
  97. procedure EnableSocketTransport(const ClassID: string);
  98. begin
  99.   CreateRegKey(SClsid + ClassID, SSockets, SFlagOn);
  100. end;
  101.  
  102. procedure DisableSocketTransport(const ClassID: string);
  103. begin
  104.   DeleteRegValue(SClsid + ClassID, SSockets);
  105. end;
  106.  
  107. procedure EnableWebTransport(const ClassID: string);
  108. begin
  109.   CreateRegKey(SClsid + ClassID, SWeb, SFlagOn);
  110. end;
  111.  
  112. procedure DisableWebTransport(const ClassID: string);
  113. begin
  114.   DeleteRegValue(SClsid + ClassID, SWeb);
  115. end;
  116.  
  117. function VarArrayFromStrings(Strings: TStrings): Variant;
  118. var
  119.   I: Integer;
  120. begin
  121.   Result := Null;
  122.   if Strings.Count > 0 then
  123.   begin
  124.     Result := VarArrayCreate([0, Strings.Count - 1], varOleStr);
  125.     for I := 0 to Strings.Count - 1 do Result[I] := WideString(Strings[I]);
  126.   end;
  127. end;
  128.  
  129. { TRemoteDataModule }
  130.  
  131. constructor TRemoteDataModule.Create(AOwner: TComponent);
  132. begin
  133.   InitializeCriticalSection(FLock);
  134.   FProviders := TList.Create;
  135.   inherited Create(AOwner);
  136. end;
  137.  
  138. destructor TRemoteDataModule.Destroy;
  139. begin
  140.   inherited Destroy;
  141.   FProviders.Free;
  142.   DeleteCriticalSection(FLock);
  143. end;
  144.  
  145. procedure TRemoteDataModule.Lock;
  146. begin
  147.   EnterCriticalSection(FLock);
  148. end;
  149.  
  150. procedure TRemoteDataModule.Unlock;
  151. begin
  152.   LeaveCriticalSection(FLock);
  153. end;
  154.  
  155. procedure TRemoteDataModule.RegisterProvider(Value: TCustomProvider);
  156. begin
  157.   FProviders.Add(Value);
  158. end;
  159.  
  160. procedure TRemoteDataModule.UnRegisterProvider(Value: TCustomProvider);
  161. begin
  162.   FProviders.Remove(Value);
  163. end;
  164.  
  165. function TRemoteDataModule.GetProvider(const ProviderName: string): TCustomProvider;
  166. var
  167.   i: Integer;
  168. begin
  169.   Result := nil;
  170.   for i := 0 to FProviders.Count - 1 do
  171.     if AnsiCompareStr(TCustomProvider(FProviders[i]).Name, ProviderName) = 0 then
  172.     begin
  173.       Result := TCustomProvider(FProviders[i]);
  174.       if not Result.Exported then
  175.         Result := nil;
  176.       Exit;
  177.     end;
  178.   if not Assigned(Result) then
  179.     raise Exception.CreateResFmt(@SProviderNotExported, [ProviderName]);
  180. end;
  181.  
  182. function TRemoteDataModule.AS_GetProviderNames: OleVariant;
  183. var
  184.   List: TStringList;
  185.   i: Integer;
  186. begin
  187.   Lock;
  188.   try
  189.     List := TStringList.Create;
  190.     try
  191.       for i := 0 to FProviders.Count - 1 do
  192.         if TCustomProvider(FProviders[i]).Exported then
  193.           List.Add(TCustomProvider(FProviders[i]).Name);
  194.       List.Sort;
  195.       Result := VarArrayFromStrings(List);
  196.     finally
  197.       List.Free;
  198.     end;
  199.   finally
  200.     UnLock;
  201.   end;
  202. end;
  203.  
  204. function TRemoteDataModule.AS_ApplyUpdates(const ProviderName: WideString;
  205.   Delta: OleVariant; MaxErrors: Integer; out ErrorCount: Integer;
  206.   var OwnerData: OleVariant): OleVariant;
  207. begin
  208.   Lock;
  209.   try
  210.     Result := Providers[ProviderName].ApplyUpdates(Delta, MaxErrors, ErrorCount, OwnerData);
  211.   finally
  212.     UnLock;
  213.   end;
  214. end;
  215.  
  216. function TRemoteDataModule.AS_GetRecords(const ProviderName: WideString; Count: Integer;
  217.   out RecsOut: Integer; Options: Integer; const CommandText: WideString;
  218.   var Params, OwnerData: OleVariant): OleVariant;
  219. begin
  220.   Lock;
  221.   try
  222.     Result := Providers[ProviderName].GetRecords(Count, RecsOut, Options,
  223.       CommandText, Params, OwnerData);
  224.   finally
  225.     UnLock;
  226.   end;
  227. end;
  228.  
  229. function TRemoteDataModule.AS_RowRequest(const ProviderName: WideString;
  230.   Row: OleVariant; RequestType: Integer; var OwnerData: OleVariant): OleVariant;
  231. begin
  232.   Lock;
  233.   try
  234.     Result := Providers[ProviderName].RowRequest(Row, RequestType, OwnerData);
  235.   finally
  236.     UnLock;
  237.   end;
  238. end;
  239.  
  240. function TRemoteDataModule.AS_DataRequest(const ProviderName: WideString;
  241.   Data: OleVariant): OleVariant; safecall;
  242. begin
  243.   Lock;
  244.   try
  245.     Result := Providers[ProviderName].DataRequest(Data);
  246.   finally
  247.     UnLock;
  248.   end;
  249. end;
  250.  
  251. function TRemoteDataModule.AS_GetParams(const ProviderName: WideString; var OwnerData: OleVariant): OleVariant;
  252. begin
  253.   Lock;
  254.   try
  255.     Result := Providers[ProviderName].GetParams(OwnerData);
  256.   finally
  257.     UnLock;
  258.   end;
  259. end;
  260.  
  261. procedure TRemoteDataModule.AS_Execute(const ProviderName: WideString;
  262.   const CommandText: WideString; var Params, OwnerData: OleVariant);
  263. begin
  264.   Lock;
  265.   try
  266.     Providers[ProviderName].Execute(CommandText, Params, OwnerData);
  267.   finally
  268.     UnLock;
  269.   end;
  270. end;
  271.  
  272. class procedure TRemoteDataModule.UpdateRegistry(Register: Boolean;
  273.   const ClassID, ProgID: string);
  274. var
  275.   CatReg: ICatRegister;
  276.   Rslt: HResult;
  277.   CatInfo: TCATEGORYINFO;
  278.   Description: string;
  279. begin
  280.   Rslt := CoCreateInstance(CLSID_StdComponentCategoryMgr, nil,
  281.     CLSCTX_INPROC_SERVER, ICatRegister, CatReg);
  282.   if Succeeded(Rslt) then
  283.   begin
  284.     if Register then
  285.     begin
  286.       CatInfo.catid := CATID_MIDASAppServer;
  287.       CatInfo.lcid := $0409;
  288.       StringToWideChar(MIDAS_CatDesc, CatInfo.szDescription,
  289.         Length(MIDAS_CatDesc) + 1);
  290.       OleCheck(CatReg.RegisterCategories(1, @CatInfo));
  291.       OleCheck(CatReg.RegisterClassImplCategories(StringToGUID(ClassID), 1, @CATID_MIDASAppServer));
  292.     end else
  293.     begin
  294.       OleCheck(CatReg.UnRegisterClassImplCategories(StringToGUID(ClassID), 1, @CATID_MIDASAppServer));
  295.       DeleteRegKey(Format(SCatImplBaseKey, [ClassID]));
  296.     end;
  297.   end else
  298.   begin
  299.     if Register then
  300.     begin
  301.       CreateRegKey('Component Categories\' + GUIDToString(CATID_MIDASAppServer), '409', MIDAS_CatDesc);
  302.       CreateRegKey(Format(SCatImplKey, [ClassID, GUIDToString(CATID_MIDASAppServer)]), '', '');
  303.     end else
  304.     begin
  305.       DeleteRegKey(Format(SCatImplKey, [ClassID, GUIDToString(CATID_MIDASAppServer)]));
  306.       DeleteRegKey(Format(SCatImplBaseKey, [ClassID]));
  307.     end;
  308.   end;
  309.   if Register then
  310.   begin
  311.     Description := GetRegStringValue('CLSID\' + ClassID, '');
  312.     CreateRegKey('AppID\' + ClassID, '', Description);
  313.     CreateRegKey('CLSID\' + ClassID, 'AppID', ClassID);
  314.   end else
  315.     DeleteRegKey('AppID\' + ClassID);
  316. end;
  317.  
  318. end.
  319.