You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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}

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 11:31:01