如何通过C++代码访问RAD Server多租户emsserver.ib数据库数据?
问题描述
本人使用Embarcadero C++ Builder 11.2 Architect,尝试通过代码以编程方式访问RAD Server中的多租户信息。由于EMSInternalAPI未提供该访问能力,于是编写了如下配置与代码:
.dfm文件配置(localhost为运行IIS和RAD Server的远程服务器)
object TenantModuleResource: TTenantModuleResource Height = 258 Width = 441 object qryTenants: TFDQuery Connection = TenantConection Left = 72 Top = 40 end object FDStanStorageJSONLink: TFDStanStorageJSONLink Left = 272 Top = 128 end object FDPhysIBDriverLink: TFDPhysIBDriverLink Left = 272 Top = 48 end object TenantConection: TFDConnection Params.Strings = ( 'Server=localhost' 'User_Name=sysdba' 'Password=masterkey' 'Database=C:\Data\emsserver.ib' 'InstanceName=gds_db' 'Port=3050' 'DriverID=IB') Left = 72 Top = 128 end end
C++代码
void TTenantModuleResource::Get(TEndpointContext* AContext, TEndpointRequest* ARequest, TEndpointResponse* AResponse) { std::unique_ptr<TMemoryStream> oStr(new TMemoryStream()); qryTenants->Close(); qryTenants->SQL->Text = "SELECT tenantid, tenantname FROM tenants"; qryTenants->Open(); qryTenants->SaveToStream(oStr.get(), TFDStorageFormat::sfJSON); AResponse->Body->SetStream(oStr.release(), "application/json", true); } static void Register() { std::unique_ptr<TEMSResourceAttributes> attributes(new TEMSResourceAttributes()); attributes->ResourceName = "tenants"; RegisterResource(__typeinfo(TTenantModuleResource), attributes.release()); }
运行后出现日志错误“...Win32 error 10060”(超时),根据InterBase文档提示,该错误可能因无客户端许可证导致。本人拥有RAD Server站点许可证但无客户端许可证,希望无需使用Multi-Tenant Console应用即可通过代码操作租户记录,请问是否有可行的实现方法?
可行解决方案
1. 调用RAD Server自带的管理员REST API
RAD Server内置了完整的租户管理REST接口,无需直接连接底层InterBase数据库,完美规避客户端许可证问题。步骤如下:
- 获取管理员令牌:向
/rest/admin/login发送POST请求,携带管理员账号密码,返回的access_token作为后续请求的身份凭证。 - 操作租户:
- 获取所有租户:发送GET请求到
/rest/admin/tenants - 创建租户:发送POST请求到
/rest/admin/tenants,附带租户信息JSON - 修改租户:发送PUT请求到
/rest/admin/tenants/{tenantid} - 删除租户:发送DELETE请求到
/rest/admin/tenants/{tenantid}
- 获取所有租户:发送GET请求到
在C++ Builder中,直接用THTTPClient组件即可完成这些请求,配合TJSONObject处理JSON响应。
2. 通过RAD Server内部服务接口访问租户数据
如果要在自定义RAD Server资源中实现,可以直接获取RAD Server内置的租户服务实例,无需绕开EMS框架:
- 在资源方法中,通过上下文获取
ITenantService接口 - 调用接口提供的方法直接操作租户,比如
GetTenants()、CreateTenant()等
示例代码片段:
#include <EMS.Services.hpp> #include <API.Tenant.Service.hpp> void TTenantModuleResource::Get(TEndpointContext* AContext, TEndpointRequest* ARequest, TEndpointResponse* AResponse) { auto TenantService = AContext->GetService<ITenantService>(); TList<TTenant>* Tenants = TenantService->GetTenants(); try { // 将租户列表序列化为JSON std::unique_ptr<TMemoryStream> oStr(new TMemoryStream()); TJSONArray* JsonArr = new TJSONArray(); for (int i = 0; i < Tenants->Count; i++) { TTenant* Tenant = Tenants->Items[i]; TJSONObject* TenantObj = new TJSONObject(); TenantObj->AddPair("tenantid", Tenant->Id); TenantObj->AddPair("tenantname", Tenant->Name); JsonArr->AddElement(TenantObj); } JsonArr->ToJSONString()->SaveToStream(oStr.get()); delete JsonArr; AResponse->Body->SetStream(oStr.release(), "application/json", true); } __finally { Tenants->Free(); } }
3. 排查直接连接InterBase的潜在问题(不推荐,因许可证限制)
如果坚持直接连库,先排除连接层面的问题:
- 把
Server=localhost改成远程服务器的实际IP或主机名 - 检查远程服务器的3050端口是否开放,防火墙是否拦截
- 确认远程InterBase服务(gds_db)是否正常运行
但即使解决连接问题,没有客户端许可证后续操作仍会受限,因此优先推荐前两种方案。
内容的提问来源于stack exchange,提问作者pjackson
相关产品推荐
相关产品推荐

