datasnap サーバーとクライアントの間でデータベース接続を共有することはできますか?
クライアントで動的SQLを実行し、結果を受け取りたいです。
クライアント側で動的SQLを実行する2つの方法を見つけました
1) DbxConnection (dbExpress) の使用
// Server code
function TServerMethods1.GetConnection: TDbxConnection;
begin
Result := DBConnection.DBXConnection;
end;
//Client code
dbxConnection := ServerMethods.GetConnection;
command := dbxConnection.CreateCommand;
command.Text := 'SELECT COUNT(1) FROM clients WHERE name LIKE :name';
param := com.CreateParameter;
param.Name := 'name';
param.DataType := TDBXDataTypes.WideStringType;
param.Value.SetString('%name%');
command.Parameters.AddParameter(param);
reader := command.ExecuteQuery;
reader.Next; // to Fetch row
ShowMessage(reader.Value[0].AsString);
2) DataSet の子孫を使用する
サーバー側のコンポーネント
ServerMethods クラスは TDSServerModule の子孫でなければなりません
クライアント側のコンポーネント
クエリを実行するコード
CDS.Close; // TClientDataSet
CDS.CommandText := 'SELECT COUNT(*) FROM clients WHERE name LIKE :name';
CDS.Params.ParamByName('name').AsString := '%name%';
CDS.Open;
ShowMessage(CDS.Fields[0].AsString);
サーバー側のコード:
MainMethods.pas
TMainMethods = class(TDSServerModule)
PgQuery: TPgQuery;
PgQueryProvider: TDataSetProvider;
PgConnection: TPgConnection;
end;
MainMethods.dfm
object MainMethods: TMainMethods
Height = 248
Width = 440
object PgConnection: TPgConnection
Left = 200
Top = 32
...
end
object PgQuery: TPgQuery
Connection: PgConnection
Left = 32
Top = 24
end
object PgQueryProvider: TDataSetProvider
DataSet = PgQuery
Options = [poAllowCommandText, poUseQuoteChar]
Left = 120
Top = 24
end
end
クライアント側のコード:
client.pas
TVerusClient = class(TDataModule)
dbxVerusConnection: TSQLConnection;
dbxSqlConnectionProvider: TDSProviderConnection;
cdsSqlDataSet: TClientDataSet;
end;
client.dfm
object VerusClient: TVerusClient
Height = 271
Width = 415
object dbxVerusConnection: TSQLConnection
DriverName = 'DataSnap'
LoginPrompt = False
...
end
object dbxSqlConnectionProvider: TDSProviderConnection
ServerClassName = 'TMainMethods'
SQLConnection = dbxVerusConnection
Left = 176
Top = 32
end
object cdsSqlDataSet: TClientDataSet
ProviderName = 'PgQueryProvider'
RemoteServer = dbxSqlConnectionProvider
Left = 176
Top = 104
end
end
DataSnap(Multi-Tier) アプリケーションの主な目標はセキュリティです。オブジェクト (接続、リソース) をリモート モードで直接 (ネイティブ) 共有することはできませんが、セッションでデータセットの SQL を変更することはできます。しかし、安全ではありません。
// Server Code
procedure TMyServerMethod.ChangeSQL(ASQL:string); // insecure
begin
AdoQuery1.Active:=false;
AdoQuery1.SQL.Text:=ASQL; // AdoQuery,DbxExpress,UniDAC,AnyDac,...
AdoQuery1.Active:=true;
end;
クライアント側にプロキシの生成を使用する
// Client Code
procedure TForm1.Button1Click(Sender:TObject);
begin
Proxy.ChangeSQL('select * from custom_table');// but it is insecure
// loading remote datasets
end;