|
@@ -22,7 +22,7 @@ uses
|
|
Classes, SysUtils, DB, SQLDB, httpdefs, httproute, fpjson, sqldbrestschema, sqldbrestio, sqldbrestdata, sqldbrestauth;
|
|
Classes, SysUtils, DB, SQLDB, httpdefs, httproute, fpjson, sqldbrestschema, sqldbrestio, sqldbrestdata, sqldbrestauth;
|
|
|
|
|
|
Type
|
|
Type
|
|
- TRestDispatcherOption = (rdoConnectionInURL,rdoExposeMetadata,rdoCustomView,rdoHandleCORS,rdoAccessCheckNeedsDB);
|
|
|
|
|
|
+ TRestDispatcherOption = (rdoConnectionInURL,rdoExposeMetadata,rdoCustomView,rdoHandleCORS,rdoAccessCheckNeedsDB,rdoConnectionResource);
|
|
TRestDispatcherOptions = set of TRestDispatcherOption;
|
|
TRestDispatcherOptions = set of TRestDispatcherOption;
|
|
|
|
|
|
Const
|
|
Const
|
|
@@ -45,6 +45,7 @@ Type
|
|
FPassword: UTF8String;
|
|
FPassword: UTF8String;
|
|
FPort: Word;
|
|
FPort: Word;
|
|
FRole: UTF8String;
|
|
FRole: UTF8String;
|
|
|
|
+ FSchemaName: UTF8String;
|
|
FUserName: UTF8String;
|
|
FUserName: UTF8String;
|
|
FNotifier : TComponent;
|
|
FNotifier : TComponent;
|
|
function GetName: UTF8String;
|
|
function GetName: UTF8String;
|
|
@@ -52,6 +53,8 @@ Type
|
|
procedure SetParams(AValue: TStrings);
|
|
procedure SetParams(AValue: TStrings);
|
|
Protected
|
|
Protected
|
|
Function GetDisplayName: string; override;
|
|
Function GetDisplayName: string; override;
|
|
|
|
+ // For use in the REST Connection resource
|
|
|
|
+ Property SchemaName : UTF8String Read FSchemaName Write FSchemaName;
|
|
Public
|
|
Public
|
|
constructor Create(ACollection: TCollection); override;
|
|
constructor Create(ACollection: TCollection); override;
|
|
Destructor Destroy; override;
|
|
Destructor Destroy; override;
|
|
@@ -92,9 +95,9 @@ Type
|
|
procedure SetConn(aIndex : integer; AValue: TSQLDBRestConnection);
|
|
procedure SetConn(aIndex : integer; AValue: TSQLDBRestConnection);
|
|
Public
|
|
Public
|
|
// Index of connection by name (case insensitive)
|
|
// Index of connection by name (case insensitive)
|
|
- Function IndexOfConnection(const aName : string) : Integer;
|
|
|
|
|
|
+ Function IndexOfConnection(const aName : UTF8string) : Integer;
|
|
// Find connection by name (case insensitive), nil if none found
|
|
// Find connection by name (case insensitive), nil if none found
|
|
- Function FindConnection(const aName : string) : TSQLDBRestConnection;
|
|
|
|
|
|
+ Function FindConnection(const aName : UTF8string) : TSQLDBRestConnection;
|
|
// Add new instance, setting basic properties. Return new instance
|
|
// Add new instance, setting basic properties. Return new instance
|
|
Function AddConnection(Const AType,aHostName,aDatabaseName,aUserName,aPassword : UTF8String) : TSQLDBRestConnection;
|
|
Function AddConnection(Const AType,aHostName,aDatabaseName,aUserName,aPassword : UTF8String) : TSQLDBRestConnection;
|
|
// Save connection definitions to JSON file.
|
|
// Save connection definitions to JSON file.
|
|
@@ -142,6 +145,7 @@ Type
|
|
procedure SetSchema(aIndex : Integer; AValue: TSQLDBRestSchemaRef);
|
|
procedure SetSchema(aIndex : Integer; AValue: TSQLDBRestSchemaRef);
|
|
Public
|
|
Public
|
|
Function AddSchema (aSchema : TSQLDBRestSchema) : TSQLDBRestSchemaRef;
|
|
Function AddSchema (aSchema : TSQLDBRestSchema) : TSQLDBRestSchemaRef;
|
|
|
|
+ Function IndexOfSchema(aSchemaName : String) : Integer;
|
|
Property Schemas[aIndex :Integer] : TSQLDBRestSchemaRef Read GetSchema Write SetSchema;default;
|
|
Property Schemas[aIndex :Integer] : TSQLDBRestSchemaRef Read GetSchema Write SetSchema;default;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -161,6 +165,7 @@ Type
|
|
Class Var FIOClass : TRestIOClass;
|
|
Class Var FIOClass : TRestIOClass;
|
|
Class Var FDBHandlerClass : TSQLDBRestDBHandlerClass;
|
|
Class Var FDBHandlerClass : TSQLDBRestDBHandlerClass;
|
|
private
|
|
private
|
|
|
|
+ FAdminUserIDs: TStrings;
|
|
FCORSAllowCredentials: Boolean;
|
|
FCORSAllowCredentials: Boolean;
|
|
FCORSAllowedOrigins: String;
|
|
FCORSAllowedOrigins: String;
|
|
FCORSMaxAge: Integer;
|
|
FCORSMaxAge: Integer;
|
|
@@ -169,6 +174,7 @@ Type
|
|
FCustomViewResource : TSQLDBRestResource;
|
|
FCustomViewResource : TSQLDBRestResource;
|
|
FMetadataResource : TSQLDBRestResource;
|
|
FMetadataResource : TSQLDBRestResource;
|
|
FMetadataDetailResource : TSQLDBRestResource;
|
|
FMetadataDetailResource : TSQLDBRestResource;
|
|
|
|
+ FConnectionResource : TSQLDBRestResource;
|
|
FActive: Boolean;
|
|
FActive: Boolean;
|
|
FAfterDelete: TRestOperationEvent;
|
|
FAfterDelete: TRestOperationEvent;
|
|
FAfterGet: TRestOperationEvent;
|
|
FAfterGet: TRestOperationEvent;
|
|
@@ -195,16 +201,23 @@ Type
|
|
FSchemas: TSQLDBRestSchemaList;
|
|
FSchemas: TSQLDBRestSchemaList;
|
|
FListRoute: THTTPRoute;
|
|
FListRoute: THTTPRoute;
|
|
FItemRoute: THTTPRoute;
|
|
FItemRoute: THTTPRoute;
|
|
|
|
+ FConnectionsRoute: THTTPRoute;
|
|
|
|
+ FConnectionItemRoute: THTTPRoute;
|
|
|
|
+ FMetadataRoute: THTTPRoute;
|
|
|
|
+ FMetadataItemRoute: THTTPRoute;
|
|
FStatus: TRestStatusConfig;
|
|
FStatus: TRestStatusConfig;
|
|
FStrings: TRestStringsConfig;
|
|
FStrings: TRestStringsConfig;
|
|
procedure SetActive(AValue: Boolean);
|
|
procedure SetActive(AValue: Boolean);
|
|
|
|
+ procedure SetAdminUserIDS(AValue: TStrings);
|
|
procedure SetAuthenticator(AValue: TRestAuthenticator);
|
|
procedure SetAuthenticator(AValue: TRestAuthenticator);
|
|
procedure SetConnections(AValue: TSQLDBRestConnectionList);
|
|
procedure SetConnections(AValue: TSQLDBRestConnectionList);
|
|
|
|
+ procedure SetDispatchOptions(AValue: TRestDispatcherOptions);
|
|
procedure SetSchemas(AValue: TSQLDBRestSchemaList);
|
|
procedure SetSchemas(AValue: TSQLDBRestSchemaList);
|
|
procedure SetStatus(AValue: TRestStatusConfig);
|
|
procedure SetStatus(AValue: TRestStatusConfig);
|
|
procedure SetStrings(AValue: TRestStringsConfig);
|
|
procedure SetStrings(AValue: TRestStringsConfig);
|
|
Protected
|
|
Protected
|
|
// Auxiliary methods.
|
|
// Auxiliary methods.
|
|
|
|
+ Procedure Loaded; override;
|
|
Procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
|
Procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
|
function FindConnection(IO: TRestIO): TSQLDBRestConnection;
|
|
function FindConnection(IO: TRestIO): TSQLDBRestConnection;
|
|
// Factory methods. Override these to customize various helper classes.
|
|
// Factory methods. Override these to customize various helper classes.
|
|
@@ -222,6 +235,13 @@ Type
|
|
function GetConnectionName(IO: TRestIO): UTF8String;
|
|
function GetConnectionName(IO: TRestIO): UTF8String;
|
|
function GetSQLConnection(aConnection: TSQLDBRestConnection; Out aTransaction : TSQLTransaction): TSQLConnection; virtual;
|
|
function GetSQLConnection(aConnection: TSQLDBRestConnection; Out aTransaction : TSQLTransaction): TSQLConnection; virtual;
|
|
procedure DoneSQLConnection(aConnection: TSQLDBRestConnection; AConn: TSQLConnection; aTransaction : TSQLTransaction); virtual;
|
|
procedure DoneSQLConnection(aConnection: TSQLDBRestConnection; AConn: TSQLConnection; aTransaction : TSQLTransaction); virtual;
|
|
|
|
+ // Connections dataset API
|
|
|
|
+ procedure ConnectionsToDataset(D: TDataset); virtual;
|
|
|
|
+ procedure DoConnectionDelete(DataSet: TDataSet); virtual;
|
|
|
|
+ procedure DoConnectionPost(DataSet: TDataSet);virtual;
|
|
|
|
+ procedure DatasetToConnection(D: TDataset; C: TSQLDBRestConnection); virtual;
|
|
|
|
+ procedure ConnectionToDataset(C: TSQLDBRestConnection; D: TDataset); virtual;
|
|
|
|
+ procedure DoConnectionResourceAllowed(aSender: TObject; aContext: TBaseRestContext; var allowResource: Boolean);
|
|
// Error handling
|
|
// Error handling
|
|
procedure CreateErrorContent(IO: TRestIO; aCode: Integer; AExtraMessage: UTF8String); virtual;
|
|
procedure CreateErrorContent(IO: TRestIO; aCode: Integer; AExtraMessage: UTF8String); virtual;
|
|
procedure HandleException(E: Exception; IO: TRestIO); virtual;
|
|
procedure HandleException(E: Exception; IO: TRestIO); virtual;
|
|
@@ -245,8 +265,10 @@ Type
|
|
// Special resources for Metadata handling
|
|
// Special resources for Metadata handling
|
|
function CreateMetadataDataset(IO: TRestIO; AOwner: TComponent): TDataset; virtual;
|
|
function CreateMetadataDataset(IO: TRestIO; AOwner: TComponent): TDataset; virtual;
|
|
function CreateMetadataDetailDataset(IO: TRestIO; Const aResourceName : String; AOwner: TComponent): TDataset; virtual;
|
|
function CreateMetadataDetailDataset(IO: TRestIO; Const aResourceName : String; AOwner: TComponent): TDataset; virtual;
|
|
|
|
+ function CreateConnectionDataset(IO: TRestIO; AOwner: TComponent): TDataset; virtual;
|
|
function CreateMetadataDetailResource: TSQLDBRestResource; virtual;
|
|
function CreateMetadataDetailResource: TSQLDBRestResource; virtual;
|
|
function CreateMetadataResource: TSQLDBRestResource; virtual;
|
|
function CreateMetadataResource: TSQLDBRestResource; virtual;
|
|
|
|
+ Function CreateConnectionResource : TSQLDBRestResource; virtual;
|
|
// Custom view handling
|
|
// Custom view handling
|
|
function CreateCustomViewResource: TSQLDBRestResource; virtual;
|
|
function CreateCustomViewResource: TSQLDBRestResource; virtual;
|
|
function CreateCustomViewDataset(IO: TRestIO; const aSQL: String; AOwner: TComponent): TDataset;
|
|
function CreateCustomViewDataset(IO: TRestIO; const aSQL: String; AOwner: TComponent): TDataset;
|
|
@@ -266,6 +288,8 @@ Type
|
|
Destructor Destroy; override;
|
|
Destructor Destroy; override;
|
|
procedure RegisterRoutes;
|
|
procedure RegisterRoutes;
|
|
procedure UnRegisterRoutes;
|
|
procedure UnRegisterRoutes;
|
|
|
|
+ procedure HandleMetadataRequest(aRequest : TRequest; aResponse : TResponse);
|
|
|
|
+ procedure HandleConnRequest(aRequest : TRequest; aResponse : TResponse);
|
|
procedure HandleRequest(aRequest : TRequest; aResponse : TResponse);
|
|
procedure HandleRequest(aRequest : TRequest; aResponse : TResponse);
|
|
Function ExposeDatabase(Const aType,aHostName,aDatabaseName,aUserName,aPassword : String; aTables : Array of String; aMinFieldOpts : TRestFieldOptions = []) : TSQLDBRestConnection;
|
|
Function ExposeDatabase(Const aType,aHostName,aDatabaseName,aUserName,aPassword : String; aTables : Array of String; aMinFieldOpts : TRestFieldOptions = []) : TSQLDBRestConnection;
|
|
Function ExposeDatabase(Const aType,aHostName,aDatabaseName,aUserName,aPassword : String; aTables : TStrings = nil; aMinFieldOpts : TRestFieldOptions = []) : TSQLDBRestConnection;
|
|
Function ExposeDatabase(Const aType,aHostName,aDatabaseName,aUserName,aPassword : String; aTables : TStrings = nil; aMinFieldOpts : TRestFieldOptions = []) : TSQLDBRestConnection;
|
|
@@ -281,6 +305,8 @@ Type
|
|
// Base URL
|
|
// Base URL
|
|
property BasePath : UTF8String Read FBaseURL Write FBaseURL;
|
|
property BasePath : UTF8String Read FBaseURL Write FBaseURL;
|
|
// Default connection to use if none is detected from request/schema
|
|
// Default connection to use if none is detected from request/schema
|
|
|
|
+ // This connection will also be used to authenticate the user for connection API,
|
|
|
|
+ // so it must be set if you use SQL to authenticate the user.
|
|
Property DefaultConnection : UTF8String Read FDefaultConnection Write FDefaultConnection;
|
|
Property DefaultConnection : UTF8String Read FDefaultConnection Write FDefaultConnection;
|
|
// Input/Output strings configuration
|
|
// Input/Output strings configuration
|
|
Property Strings : TRestStringsConfig Read FStrings Write SetStrings;
|
|
Property Strings : TRestStringsConfig Read FStrings Write SetStrings;
|
|
@@ -293,7 +319,7 @@ Type
|
|
// Set this to allow only this output format.
|
|
// Set this to allow only this output format.
|
|
Property OutputFormat : String Read FOutputFormat Write FOutputFormat;
|
|
Property OutputFormat : String Read FOutputFormat Write FOutputFormat;
|
|
// Dispatcher options
|
|
// Dispatcher options
|
|
- Property DispatchOptions : TRestDispatcherOptions Read FDispatchOptions Write FDispatchOptions default DefaultDispatcherOptions;
|
|
|
|
|
|
+ Property DispatchOptions : TRestDispatcherOptions Read FDispatchOptions Write SetDispatchOptions default DefaultDispatcherOptions;
|
|
// Authenticator for requests
|
|
// Authenticator for requests
|
|
Property Authenticator : TRestAuthenticator Read FAuthenticator Write SetAuthenticator;
|
|
Property Authenticator : TRestAuthenticator Read FAuthenticator Write SetAuthenticator;
|
|
// If >0, Enforce a limit on output results.
|
|
// If >0, Enforce a limit on output results.
|
|
@@ -304,6 +330,8 @@ Type
|
|
Property CORSMaxAge : Integer Read FCORSMaxAge Write FCORSMaxAge;
|
|
Property CORSMaxAge : Integer Read FCORSMaxAge Write FCORSMaxAge;
|
|
// Access-Control-Allow-Credentials header value. Set to zero not to send the header
|
|
// Access-Control-Allow-Credentials header value. Set to zero not to send the header
|
|
Property CORSAllowCredentials : Boolean Read FCORSAllowCredentials Write FCORSAllowCredentials;
|
|
Property CORSAllowCredentials : Boolean Read FCORSAllowCredentials Write FCORSAllowCredentials;
|
|
|
|
+ // UserIDs of the user(s) that are allowed to see and modify the connection resource.
|
|
|
|
+ Property AdminUserIDs : TStrings Read FAdminUserIDs Write SetAdminUserIDS;
|
|
// Called when Basic authentication is sufficient.
|
|
// Called when Basic authentication is sufficient.
|
|
Property OnBasicAuthentication : TBasicAuthenticationEvent Read FOnBasicAuthentication Write FOnBasicAuthentication;
|
|
Property OnBasicAuthentication : TBasicAuthenticationEvent Read FOnBasicAuthentication Write FOnBasicAuthentication;
|
|
// Allow a particular resource or not.
|
|
// Allow a particular resource or not.
|
|
@@ -406,6 +434,13 @@ begin
|
|
Result.Enabled:=True;
|
|
Result.Enabled:=True;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function TSQLDBRestSchemaList.IndexOfSchema(aSchemaName: String): Integer;
|
|
|
|
+begin
|
|
|
|
+ Result:=Count-1;
|
|
|
|
+ While (Result>=0) and Not (Assigned(GetSchema(Result).Schema) and SameText(GetSchema(Result).Schema.Name,aSchemaName)) do
|
|
|
|
+ Dec(Result);
|
|
|
|
+end;
|
|
|
|
+
|
|
{ TSQLDBRestDispatcher }
|
|
{ TSQLDBRestDispatcher }
|
|
|
|
|
|
procedure TSQLDBRestDispatcher.SetConnections(AValue: TSQLDBRestConnectionList);
|
|
procedure TSQLDBRestDispatcher.SetConnections(AValue: TSQLDBRestConnectionList);
|
|
@@ -414,15 +449,39 @@ begin
|
|
FConnections.Assign(AValue);
|
|
FConnections.Assign(AValue);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure TSQLDBRestDispatcher.SetDispatchOptions(AValue: TRestDispatcherOptions);
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ if (rdoConnectionResource in aValue) then
|
|
|
|
+ Include(aValue,rdoConnectionInURL);
|
|
|
|
+ if FDispatchOptions=AValue then Exit;
|
|
|
|
+ FDispatchOptions:=AValue;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TSQLDBRestDispatcher.DoConnectionResourceAllowed(aSender: TObject;
|
|
|
|
+ aContext: TBaseRestContext; var allowResource: Boolean);
|
|
|
|
+begin
|
|
|
|
+ AllowResource:=(AdminUserIDs.Count=0) or (AdminUserIDs.IndexOf(aContext.UserID)<>-1);
|
|
|
|
+end;
|
|
|
|
+
|
|
procedure TSQLDBRestDispatcher.SetActive(AValue: Boolean);
|
|
procedure TSQLDBRestDispatcher.SetActive(AValue: Boolean);
|
|
begin
|
|
begin
|
|
- if FActive=AValue then Exit;
|
|
|
|
- if AValue then
|
|
|
|
- DoRegisterRoutes
|
|
|
|
- else
|
|
|
|
- UnRegisterRoutes;
|
|
|
|
|
|
+ if FActive=AValue then
|
|
|
|
+ Exit;
|
|
|
|
+ if Not (csLoading in ComponentState) then
|
|
|
|
+ begin
|
|
|
|
+ if AValue then
|
|
|
|
+ DoRegisterRoutes
|
|
|
|
+ else
|
|
|
|
+ UnRegisterRoutes;
|
|
|
|
+ end;
|
|
FActive:=AValue;
|
|
FActive:=AValue;
|
|
|
|
+end;
|
|
|
|
|
|
|
|
+procedure TSQLDBRestDispatcher.SetAdminUserIDS(AValue: TStrings);
|
|
|
|
+begin
|
|
|
|
+ if FAdminUserIDs=AValue then Exit;
|
|
|
|
+ FAdminUserIDs.Assign(AValue);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TSQLDBRestDispatcher.SetAuthenticator(AValue: TRestAuthenticator);
|
|
procedure TSQLDBRestDispatcher.SetAuthenticator(AValue: TRestAuthenticator);
|
|
@@ -453,18 +512,51 @@ begin
|
|
FStrings.Assign(AValue);
|
|
FStrings.Assign(AValue);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure TSQLDBRestDispatcher.Loaded;
|
|
|
|
+begin
|
|
|
|
+ inherited Loaded;
|
|
|
|
+ if FActive then
|
|
|
|
+ RegisterRoutes;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TSQLDBRestDispatcher.HandleConnRequest(aRequest : TRequest; aResponse : TResponse);
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ aRequest.RouteParams['resource']:=Strings.ConnectionResourceName;
|
|
|
|
+ HandleRequest(aRequest,aResponse);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TSQLDBRestDispatcher.HandleMetadataRequest(aRequest: TRequest;
|
|
|
|
+ aResponse: TResponse);
|
|
|
|
+begin
|
|
|
|
+ aRequest.RouteParams['resource']:=Strings.MetadataResourceName;
|
|
|
|
+ HandleRequest(aRequest,aResponse);
|
|
|
|
+end;
|
|
|
|
+
|
|
procedure TSQLDBRestDispatcher.DoRegisterRoutes;
|
|
procedure TSQLDBRestDispatcher.DoRegisterRoutes;
|
|
|
|
|
|
Var
|
|
Var
|
|
- Res : String;
|
|
|
|
|
|
+ Res,C : UTF8String;
|
|
|
|
|
|
begin
|
|
begin
|
|
Res:=IncludeHTTPPathDelimiter(BasePath);
|
|
Res:=IncludeHTTPPathDelimiter(BasePath);
|
|
- if rdoConnectionInURL in DispatchOptions then
|
|
|
|
|
|
+ if (rdoConnectionResource in DispatchOptions) then
|
|
|
|
+ begin
|
|
|
|
+ C:=Strings.GetRestString(rpConnectionResourceName);
|
|
|
|
+ FConnectionsRoute:=HTTPRouter.RegisterRoute(res+C,@HandleConnRequest);
|
|
|
|
+ FConnectionItemRoute:=HTTPRouter.RegisterRoute(res+C+'/:id',@HandleConnRequest);
|
|
|
|
+ end;
|
|
|
|
+ if (rdoConnectionInURL in DispatchOptions) then
|
|
|
|
+ begin
|
|
|
|
+ C:=Strings.GetRestString(rpMetadataResourceName);
|
|
|
|
+ FMetadataRoute:=HTTPRouter.RegisterRoute(res+C,@HandleMetaDataRequest);
|
|
|
|
+ FMetadataItemRoute:=HTTPRouter.RegisterRoute(res+C+'/:id',@HandleMetaDataRequest);
|
|
Res:=Res+':connection/';
|
|
Res:=Res+':connection/';
|
|
|
|
+ end;
|
|
Res:=Res+':resource';
|
|
Res:=Res+':resource';
|
|
FListRoute:=HTTPRouter.RegisterRoute(res,@HandleRequest);
|
|
FListRoute:=HTTPRouter.RegisterRoute(res,@HandleRequest);
|
|
FItemRoute:=HTTPRouter.RegisterRoute(Res+'/:id',@HandleRequest);
|
|
FItemRoute:=HTTPRouter.RegisterRoute(Res+'/:id',@HandleRequest);
|
|
|
|
+
|
|
end;
|
|
end;
|
|
|
|
|
|
function TSQLDBRestDispatcher.GetInputFormat(IO : TRestIO) : String;
|
|
function TSQLDBRestDispatcher.GetInputFormat(IO : TRestIO) : String;
|
|
@@ -633,14 +725,17 @@ begin
|
|
FStatus:=CreateRestStatusConfig;
|
|
FStatus:=CreateRestStatusConfig;
|
|
FCORSMaxAge:=SecsPerDay;
|
|
FCORSMaxAge:=SecsPerDay;
|
|
FCORSAllowCredentials:=True;
|
|
FCORSAllowCredentials:=True;
|
|
|
|
+ FAdminUserIDs:=TStringList.Create;
|
|
end;
|
|
end;
|
|
|
|
|
|
destructor TSQLDBRestDispatcher.Destroy;
|
|
destructor TSQLDBRestDispatcher.Destroy;
|
|
begin
|
|
begin
|
|
Authenticator:=Nil;
|
|
Authenticator:=Nil;
|
|
|
|
+ FreeAndNil(FAdminUserIDs);
|
|
FreeAndNil(FCustomViewResource);
|
|
FreeAndNil(FCustomViewResource);
|
|
FreeAndNil(FMetadataResource);
|
|
FreeAndNil(FMetadataResource);
|
|
FreeAndNil(FMetadataDetailResource);
|
|
FreeAndNil(FMetadataDetailResource);
|
|
|
|
+ FreeAndNil(FConnectionResource);
|
|
FreeAndNil(FSchemas);
|
|
FreeAndNil(FSchemas);
|
|
FreeAndNil(FConnections);
|
|
FreeAndNil(FConnections);
|
|
FreeAndNil(FStrings);
|
|
FreeAndNil(FStrings);
|
|
@@ -692,13 +787,13 @@ Var
|
|
|
|
|
|
begin
|
|
begin
|
|
Result:=TSQLDBRestResource.Create(Nil);
|
|
Result:=TSQLDBRestResource.Create(Nil);
|
|
- Result.ResourceName:='metaData';
|
|
|
|
|
|
+ Result.ResourceName:=Strings.GetRestString(rpMetadataResourceName);
|
|
if rdoHandleCORS in DispatchOptions then
|
|
if rdoHandleCORS in DispatchOptions then
|
|
Result.AllowedOperations:=[roGet,roOptions,roHead]
|
|
Result.AllowedOperations:=[roGet,roOptions,roHead]
|
|
else
|
|
else
|
|
Result.AllowedOperations:=[roGet,roHead];
|
|
Result.AllowedOperations:=[roGet,roHead];
|
|
- Result.Fields.AddField('name',rftString,[foRequired]);
|
|
|
|
- Result.Fields.AddField('schemaName',rftString,[foRequired]);
|
|
|
|
|
|
+ Result.Fields.AddField('name',rftString,[foRequired]).MaxLen:=255;
|
|
|
|
+ Result.Fields.AddField('schemaName',rftString,[foRequired]).MaxLen:=255;
|
|
for O in TRestOperation do
|
|
for O in TRestOperation do
|
|
if O<>roUnknown then
|
|
if O<>roUnknown then
|
|
begin
|
|
begin
|
|
@@ -708,6 +803,34 @@ begin
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function TSQLDBRestDispatcher.CreateConnectionResource: TSQLDBRestResource;
|
|
|
|
+Var
|
|
|
|
+ O : TRestOperation;
|
|
|
|
+ S : String;
|
|
|
|
+ Def : TRestFieldOptions;
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ Def:=[foInInsert,foInUpdate,foFilter];
|
|
|
|
+ Result:=TSQLDBRestResource.Create(Nil);
|
|
|
|
+ Result.ResourceName:=Strings.GetRestString(rpConnectionResourceName);
|
|
|
|
+ Result.AllowedOperations:=[roGet,roPut,roPost,roDelete];
|
|
|
|
+ if rdoHandleCORS in DispatchOptions then
|
|
|
|
+ Result.AllowedOperations:=Result.AllowedOperations+[roOptions,roHead];
|
|
|
|
+ Result.Fields.AddField('name',rftString,Def+[foInKey,foRequired]);
|
|
|
|
+ Result.Fields.AddField('dbType',rftString,Def+[foRequired]);
|
|
|
|
+ Result.Fields.AddField('dbName',rftString,Def+[foRequired]);
|
|
|
|
+ Result.Fields.AddField('dbHostName',rftString,Def);
|
|
|
|
+ Result.Fields.AddField('dbUserName',rftString,Def);
|
|
|
|
+ Result.Fields.AddField('dbPassword',rftString,Def);
|
|
|
|
+ Result.Fields.AddField('dbCharSet',rftString,Def);
|
|
|
|
+ Result.Fields.AddField('dbRole',rftString,Def);
|
|
|
|
+ Result.Fields.AddField('dbPort',rftInteger,Def);
|
|
|
|
+ Result.Fields.AddField('enabled',rftBoolean,Def);
|
|
|
|
+ Result.Fields.AddField('expose',rftBoolean,Def);
|
|
|
|
+ Result.Fields.AddField('exposeSchemaName',rftString,Def);
|
|
|
|
+ Result.OnResourceAllowed:=@DoConnectionResourceAllowed;
|
|
|
|
+end;
|
|
|
|
+
|
|
function TSQLDBRestDispatcher.CreateMetadataDetailResource: TSQLDBRestResource;
|
|
function TSQLDBRestDispatcher.CreateMetadataDetailResource: TSQLDBRestResource;
|
|
|
|
|
|
Var
|
|
Var
|
|
@@ -721,10 +844,10 @@ begin
|
|
Result.AllowedOperations:=[roGet,roOptions,roHead]
|
|
Result.AllowedOperations:=[roGet,roOptions,roHead]
|
|
else
|
|
else
|
|
Result.AllowedOperations:=[roGet,roHead];
|
|
Result.AllowedOperations:=[roGet,roHead];
|
|
- Result.Fields.AddField('name',rftString,[]);
|
|
|
|
- Result.Fields.AddField('type',rftString,[]);
|
|
|
|
|
|
+ Result.Fields.AddField('name',rftString,[]).MaxLen:=255;
|
|
|
|
+ Result.Fields.AddField('type',rftString,[]).MaxLen:=20;
|
|
Result.Fields.AddField('maxlen',rftInteger,[]);
|
|
Result.Fields.AddField('maxlen',rftInteger,[]);
|
|
- Result.Fields.AddField('format',rftString,[]);
|
|
|
|
|
|
+ Result.Fields.AddField('format',rftString,[]).MaxLen:=50;
|
|
for O in TRestFieldOption do
|
|
for O in TRestFieldOption do
|
|
begin
|
|
begin
|
|
Str(O,S);
|
|
Str(O,S);
|
|
@@ -741,6 +864,7 @@ function TSQLDBRestDispatcher.FindSpecialResource(IO : TRestIO; aResource: UTF8S
|
|
Result:=(rdoCustomView in DispatchOptions)
|
|
Result:=(rdoCustomView in DispatchOptions)
|
|
and SameText(aResource,Strings.GetRestString(rpCustomViewResourceName));
|
|
and SameText(aResource,Strings.GetRestString(rpCustomViewResourceName));
|
|
end;
|
|
end;
|
|
|
|
+
|
|
Function IsMetadata : Boolean;inline;
|
|
Function IsMetadata : Boolean;inline;
|
|
|
|
|
|
begin
|
|
begin
|
|
@@ -748,6 +872,13 @@ function TSQLDBRestDispatcher.FindSpecialResource(IO : TRestIO; aResource: UTF8S
|
|
and SameText(aResource,Strings.GetRestString(rpMetaDataResourceName));
|
|
and SameText(aResource,Strings.GetRestString(rpMetaDataResourceName));
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+ Function IsConnection : Boolean;inline;
|
|
|
|
+
|
|
|
|
+ begin
|
|
|
|
+ Result:=(rdoConnectionResource in DispatchOptions)
|
|
|
|
+ and SameText(aResource,Strings.GetRestString(rpConnectionResourceName));
|
|
|
|
+ end;
|
|
|
|
+
|
|
Var
|
|
Var
|
|
N : UTF8String;
|
|
N : UTF8String;
|
|
|
|
|
|
@@ -759,6 +890,12 @@ begin
|
|
FCustomViewResource:=CreateCustomViewResource;
|
|
FCustomViewResource:=CreateCustomViewResource;
|
|
Result:=FCustomViewResource;
|
|
Result:=FCustomViewResource;
|
|
end
|
|
end
|
|
|
|
+ else if IsConnection then
|
|
|
|
+ begin
|
|
|
|
+ if FConnectionResource=Nil then
|
|
|
|
+ FConnectionResource:=CreateConnectionResource;
|
|
|
|
+ Result:=FConnectionResource;
|
|
|
|
+ end
|
|
else If isMetadata then
|
|
else If isMetadata then
|
|
if (IO.GetVariable('ID',N,[vsRoute,vsQuery])=vsNone) then
|
|
if (IO.GetVariable('ID',N,[vsRoute,vsQuery])=vsNone) then
|
|
begin
|
|
begin
|
|
@@ -775,7 +912,6 @@ begin
|
|
Result:=FMetadataDetailResource;
|
|
Result:=FMetadataDetailResource;
|
|
end;
|
|
end;
|
|
end
|
|
end
|
|
-
|
|
|
|
end;
|
|
end;
|
|
|
|
|
|
function TSQLDBRestDispatcher.FindRestResource(aResource: UTF8String): TSQLDBRestResource;
|
|
function TSQLDBRestDispatcher.FindRestResource(aResource: UTF8String): TSQLDBRestResource;
|
|
@@ -872,6 +1008,10 @@ function TSQLDBRestDispatcher.GetSQLConnection(
|
|
): TSQLConnection;
|
|
): TSQLConnection;
|
|
|
|
|
|
begin
|
|
begin
|
|
|
|
+ Result:=Nil;
|
|
|
|
+ aTransaction:=Nil;
|
|
|
|
+ if aConnection=Nil then
|
|
|
|
+ exit;
|
|
Result:=aConnection.SingleConnection;
|
|
Result:=aConnection.SingleConnection;
|
|
if (Result=Nil) then
|
|
if (Result=Nil) then
|
|
begin
|
|
begin
|
|
@@ -973,6 +1113,7 @@ begin
|
|
if not Result then exit;
|
|
if not Result then exit;
|
|
Result:=(aResource=FMetadataResource) or
|
|
Result:=(aResource=FMetadataResource) or
|
|
(aResource=FMetadataDetailResource) or
|
|
(aResource=FMetadataDetailResource) or
|
|
|
|
+ (aResource=FConnectionResource) or
|
|
(aResource=FCustomViewResource);
|
|
(aResource=FCustomViewResource);
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -1124,6 +1265,166 @@ begin
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure TSQLDBRestDispatcher.DatasetToConnection(D: TDataset; C : TSQLDBRestConnection);
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ C.Name:=UTF8Encode(D.FieldByName('name').AsWideString);
|
|
|
|
+ C.ConnectionType:=D.FieldByName('dbType').AsString;
|
|
|
|
+ C.DatabaseName:=UTF8Encode(D.FieldByName('dbName').AsWideString);
|
|
|
|
+ C.HostName:=D.FieldByName('dbHostName').AsString;
|
|
|
|
+ C.UserName:=UTF8Encode(D.FieldByName('dbUserName').AsWideString);
|
|
|
|
+ C.Password:=UTF8Encode(D.FieldByName('dbPassword').AsWideString);
|
|
|
|
+ C.CharSet:=D.FieldByName('dbCharSet').AsString;
|
|
|
|
+ C.Role:=D.FieldByName('dbRole').AsString;
|
|
|
|
+ C.Port:=D.FieldByName('dbPort').AsInteger;
|
|
|
|
+ C.Enabled:=D.FieldByName('enabled').AsBoolean;
|
|
|
|
+ if D.FieldByName('expose').AsBoolean then
|
|
|
|
+ C.SchemaName:=D.FieldByName('exposeSchemaName').AsString;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TSQLDBRestDispatcher.ConnectionToDataset(C : TSQLDBRestConnection;D: TDataset);
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ D.FieldByName('key').AsWideString:=UTF8Decode(C.Name);
|
|
|
|
+ D.FieldByName('name').AsWideString:=UTF8Decode(C.Name);
|
|
|
|
+ D.FieldByName('dbType').AsString:=C.ConnectionType;
|
|
|
|
+ D.FieldByName('dbName').AsWideString:=UTF8Decode(C.DatabaseName);
|
|
|
|
+ D.FieldByName('dbHostName').AsString:=C.HostName;
|
|
|
|
+ D.FieldByName('dbUserName').AsWideString:=UTF8Decode(C.UserName);
|
|
|
|
+ D.FieldByName('dbPassword').AsWideString:=UTF8Decode(C.Password);
|
|
|
|
+ D.FieldByName('dbCharSet').AsString:=C.CharSet;
|
|
|
|
+ D.FieldByName('dbRole').AsString:=C.Role;
|
|
|
|
+ D.FieldByName('dbPort').AsInteger:=C.Port;
|
|
|
|
+ D.FieldByName('enabled').AsBoolean:=C.Enabled;
|
|
|
|
+ D.FieldByName('expose').AsBoolean:=(C.SchemaName<>'');
|
|
|
|
+ D.FieldByName('exposeSchemaName').AsString:=C.SchemaName;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TSQLDBRestDispatcher.ConnectionsToDataset(D: TDataset);
|
|
|
|
+
|
|
|
|
+Var
|
|
|
|
+ C : TSQLDBRestConnection;
|
|
|
|
+ I : Integer;
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ For I:=0 to Connections.Count-1 do
|
|
|
|
+ begin
|
|
|
|
+ C:=Connections[i];
|
|
|
|
+ D.Append;
|
|
|
|
+ ConnectionToDataset(C,D);
|
|
|
|
+ D.Post;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TSQLDBRestDispatcher.DoConnectionDelete(DataSet: TDataSet);
|
|
|
|
+
|
|
|
|
+Var
|
|
|
|
+ I,J : Integer;
|
|
|
|
+ C : TSQLDBRestConnection;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ I:=Connections.IndexOfConnection(UTF8Encode(Dataset.FieldByName('name').AsWideString));
|
|
|
|
+ if I<>-1 then
|
|
|
|
+ begin
|
|
|
|
+ C:=Connections[i];
|
|
|
|
+ if C.SingleConnection<>Nil then
|
|
|
|
+ DoneSQLConnection(C,C.SingleConnection,Nil);
|
|
|
|
+ if C.SchemaName<>'' then
|
|
|
|
+ begin
|
|
|
|
+ J:=Schemas.IndexOfSchema(C.SchemaName);
|
|
|
|
+ if J<>-1 then
|
|
|
|
+ begin
|
|
|
|
+ Schemas[J].Schema.Free;
|
|
|
|
+ Schemas[J].Schema:=Nil;
|
|
|
|
+ end;
|
|
|
|
+ Schemas.Delete(J);
|
|
|
|
+ end;
|
|
|
|
+ Connections.Delete(I);
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ Raise ESQLDBRest.Create(404,'NOT FOUND');
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TSQLDBRestDispatcher.DoConnectionPost(DataSet: TDataSet);
|
|
|
|
+
|
|
|
|
+Var
|
|
|
|
+ isNew : Boolean;
|
|
|
|
+ C : TSQLDBRestConnection;
|
|
|
|
+ N : UTF8String;
|
|
|
|
+ UN : UnicodeString;
|
|
|
|
+ S : TSQLDBRestSchema;
|
|
|
|
+ Conn : TSQLConnection;
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ IsNew:=Dataset.State=dsInsert;
|
|
|
|
+ if IsNew then
|
|
|
|
+ C:=Connections.Add as TSQLDBRestConnection
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ UN:=Dataset.FieldByName('key').AsString;
|
|
|
|
+// C:=Connections[Dataset.RecNo-1];
|
|
|
|
+ C:=Connections.FindConnection(Utf8Encode(UN));
|
|
|
|
+ if (C=Nil) then
|
|
|
|
+ Raise ESQLDBRest.Create(404,'NOT FOUND');
|
|
|
|
+ end;
|
|
|
|
+ if Assigned(C.SingleConnection) then
|
|
|
|
+ DoneSQLConnection(C,C.SingleConnection,Nil);
|
|
|
|
+ DatasetToConnection(Dataset,C);
|
|
|
|
+ if (Dataset.FieldByName('expose').AsBoolean) and isNew then
|
|
|
|
+ begin
|
|
|
|
+ N:=C.SchemaName;
|
|
|
|
+ if N='' then
|
|
|
|
+ N:=C.Name+'schema';
|
|
|
|
+ if (Schemas.IndexOfSchema(N)<>-1) then
|
|
|
|
+ Raise ESQLDBRest.Create(400,'DUPLICATE SCHEMA');
|
|
|
|
+ try
|
|
|
|
+ S:=ExposeConnection(C,Nil);
|
|
|
|
+ except
|
|
|
|
+ if IsNew then
|
|
|
|
+ C.Free;
|
|
|
|
+ Raise;
|
|
|
|
+ end;
|
|
|
|
+ S.Name:=N;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TSQLDBRestDispatcher.CreateConnectionDataset(IO: TRestIO; AOwner: TComponent): TDataset;
|
|
|
|
+Var
|
|
|
|
+ BD : TRestBufDataset;
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ if IO=Nil then exit;
|
|
|
|
+ BD:=TRestBufDataset.Create(aOwner);
|
|
|
|
+ try
|
|
|
|
+ Result:=BD;
|
|
|
|
+ // Key field is not exposed
|
|
|
|
+ Result.FieldDefs.add('key',ftWidestring,255);
|
|
|
|
+ Result.FieldDefs.add('name',ftWidestring,255);
|
|
|
|
+ Result.FieldDefs.add('dbType',ftString,20);
|
|
|
|
+ Result.FieldDefs.add('dbName',ftWideString,255);
|
|
|
|
+ Result.FieldDefs.add('dbHostName',ftString,255);
|
|
|
|
+ Result.FieldDefs.add('dbUserName',ftWideString,255);
|
|
|
|
+ Result.FieldDefs.add('dbPassword',ftWideString,255);
|
|
|
|
+ Result.FieldDefs.add('dbCharSet',ftString,50);
|
|
|
|
+ Result.FieldDefs.add('dbRole',ftString,255);
|
|
|
|
+ Result.FieldDefs.add('dbPort',ftInteger,0);
|
|
|
|
+ Result.FieldDefs.add('enabled',ftBoolean,0);
|
|
|
|
+ Result.FieldDefs.add('expose',ftBoolean,0);
|
|
|
|
+ Result.FieldDefs.add('exposeSchemaName',ftWideString,255);
|
|
|
|
+ BD.CreateDataset;
|
|
|
|
+ ConnectionsToDataset(BD);
|
|
|
|
+ BD.IndexDefs.Add('uName','name',[ixUnique]);
|
|
|
|
+ BD.IndexName:='uName';
|
|
|
|
+ BD.First;
|
|
|
|
+ BD.BeforePost:=@DoConnectionPost;
|
|
|
|
+ BD.BeforeDelete:=@DoConnectionDelete;
|
|
|
|
+ except
|
|
|
|
+ BD.Free;
|
|
|
|
+ Raise;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
function TSQLDBRestDispatcher.CreateCustomViewDataset(IO: TRestIO;
|
|
function TSQLDBRestDispatcher.CreateCustomViewDataset(IO: TRestIO;
|
|
const aSQL: String; AOwner: TComponent): TDataset;
|
|
const aSQL: String; AOwner: TComponent): TDataset;
|
|
|
|
|
|
@@ -1159,6 +1460,8 @@ begin
|
|
Result:=Nil;
|
|
Result:=Nil;
|
|
if (IO.Resource=FMetadataResource) then
|
|
if (IO.Resource=FMetadataResource) then
|
|
Result:=CreateMetadataDataset(IO,AOwner)
|
|
Result:=CreateMetadataDataset(IO,AOwner)
|
|
|
|
+ else if (IO.Resource=FConnectionResource) then
|
|
|
|
+ Result:=CreateConnectionDataset(IO,AOwner)
|
|
else if (IO.Resource=FMetadataDetailResource) then
|
|
else if (IO.Resource=FMetadataDetailResource) then
|
|
begin
|
|
begin
|
|
if IO.GetVariable('ID',RN,[vsRoute,vsQuery])=vsNone then
|
|
if IO.GetVariable('ID',RN,[vsRoute,vsQuery])=vsNone then
|
|
@@ -1220,6 +1523,7 @@ Var
|
|
H : TSQLDBRestDBHandler;
|
|
H : TSQLDBRestDBHandler;
|
|
l,o : Int64;
|
|
l,o : Int64;
|
|
|
|
|
|
|
|
+
|
|
begin
|
|
begin
|
|
H:=Nil;
|
|
H:=Nil;
|
|
Conn:=GetSQLConnection(aConnection,Tr);
|
|
Conn:=GetSQLConnection(aConnection,Tr);
|
|
@@ -1243,7 +1547,8 @@ begin
|
|
end;
|
|
end;
|
|
H.ExecuteOperation;
|
|
H.ExecuteOperation;
|
|
DoHandleEvent(False,IO);
|
|
DoHandleEvent(False,IO);
|
|
- tr.Commit;
|
|
|
|
|
|
+ if Assigned(TR) then
|
|
|
|
+ TR.Commit;
|
|
SetDefaultResponseCode(IO);
|
|
SetDefaultResponseCode(IO);
|
|
except
|
|
except
|
|
TR.RollBack;
|
|
TR.RollBack;
|
|
@@ -1365,7 +1670,7 @@ begin
|
|
begin
|
|
begin
|
|
IO.SetResource(Resource);
|
|
IO.SetResource(Resource);
|
|
Connection:=FindConnection(IO);
|
|
Connection:=FindConnection(IO);
|
|
- if Connection=Nil then
|
|
|
|
|
|
+ if (Connection=Nil) and not IsSpecialResource(Resource) then
|
|
begin
|
|
begin
|
|
if (rdoConnectionInURL in DispatchOptions) then
|
|
if (rdoConnectionInURL in DispatchOptions) then
|
|
CreateErrorContent(IO,FStatus.GetStatusCode(rsNoConnectionSpecified),Format(SErrNoconnection,[GetConnectionName(IO)]))
|
|
CreateErrorContent(IO,FStatus.GetStatusCode(rsNoConnectionSpecified),Format(SErrNoconnection,[GetConnectionName(IO)]))
|
|
@@ -1396,8 +1701,13 @@ procedure TSQLDBRestDispatcher.UnRegisterRoutes;
|
|
begin
|
|
begin
|
|
Un(FListRoute);
|
|
Un(FListRoute);
|
|
Un(FItemRoute);
|
|
Un(FItemRoute);
|
|
|
|
+ Un(FConnectionItemRoute);
|
|
|
|
+ Un(FConnectionsRoute);
|
|
|
|
+ Un(FMetadataItemRoute);
|
|
|
|
+ Un(FMetadataRoute);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+
|
|
procedure TSQLDBRestDispatcher.RegisterRoutes;
|
|
procedure TSQLDBRestDispatcher.RegisterRoutes;
|
|
begin
|
|
begin
|
|
if (FListRoute<>Nil) then
|
|
if (FListRoute<>Nil) then
|
|
@@ -1651,7 +1961,7 @@ begin
|
|
Items[aIndex]:=aValue;
|
|
Items[aIndex]:=aValue;
|
|
end;
|
|
end;
|
|
|
|
|
|
-function TSQLDBRestConnectionList.IndexOfConnection(const aName: string
|
|
|
|
|
|
+function TSQLDBRestConnectionList.IndexOfConnection(const aName: UTF8string
|
|
): Integer;
|
|
): Integer;
|
|
begin
|
|
begin
|
|
Result:=Count-1;
|
|
Result:=Count-1;
|
|
@@ -1659,7 +1969,7 @@ begin
|
|
Dec(Result);
|
|
Dec(Result);
|
|
end;
|
|
end;
|
|
|
|
|
|
-function TSQLDBRestConnectionList.FindConnection(const aName: string): TSQLDBRestConnection;
|
|
|
|
|
|
+function TSQLDBRestConnectionList.FindConnection(const aName: UTF8string): TSQLDBRestConnection;
|
|
Var
|
|
Var
|
|
Idx : Integer;
|
|
Idx : Integer;
|
|
|
|
|
|
@@ -1849,6 +2159,8 @@ begin
|
|
Role:=C.Role;
|
|
Role:=C.Role;
|
|
DatabaseName:=C.DatabaseName;
|
|
DatabaseName:=C.DatabaseName;
|
|
ConnectionType:=C.ConnectionType;
|
|
ConnectionType:=C.ConnectionType;
|
|
|
|
+ Port:=C.Port;
|
|
|
|
+ SchemaName:=C.SchemaName;
|
|
Params.Assign(C.Params);
|
|
Params.Assign(C.Params);
|
|
end
|
|
end
|
|
else
|
|
else
|