SDK 准备
安装 C++ SDK
环境准备
- 运行环境。
- C++ SDK 使用 C++17 编写,编译时以
-std=c++17方式向使用方传递,因此需要支持 C++17 的编译器。 - 构建工具要求 CMake 3.2 及以上版本。
- C++ SDK 面向 Mochow 2.4 HTTP 协议实现。
- 可选依赖 libcurl:SDK 默认开启
MOCHOW_ENABLE_CURL,构建时能通过find_package(CURL)、curl-config或pkg-config找到 libcurl 即启用 HTTPS 传输;未找到 libcurl 时 SDK 仍可编译安装,但只支持http://端点,对https://端点发起请求会返回NotSupported。
源码下载
若您需要 C++ SDK 源码,可从 Mochow C++ SDK 代码仓库获取:
Shell1git clone $Mochow_C++_SDK_代码仓库地址
编译和安装
我们推荐通过仓库自带的构建脚本 scripts/build.sh 完成编译和安装,方法如下:
1# 默认使用 Release 构建,产出动态库和示例
2scripts/build.sh
3
4# 构建并运行单元测试
5scripts/build.sh --tests
6
7# 构建后安装到指定目录
8scripts/build.sh --install --install-prefix /path/to/mochow-cpp-sdk-install
9
10# 构建静态库、关闭示例,并校验安装包可被正常引用
11scripts/build.sh --static --no-examples --package-smoke
执行 scripts/build.sh --help 可以查看全部选项。仓库根目录的 Makefile 封装了常用入口:
1# 构建 Release 版本的 SDK 和示例
2make
3
4# 构建并运行单元测试
5make test
6
7# 构建覆盖率版本并运行测试
8make coverage
9
10# 构建后安装到指定目录
11make install CMAKE_INSTALL_PREFIX=/path/to/mochow-cpp-sdk-install
12
13# 校验安装包的 CMake 引用方式
14make package-smoke
也可以直接使用 CMake 命令完成编译和安装:
1mkdir -p build
2cd build
3
4cmake .. \
5 -DCMAKE_BUILD_TYPE=Release \
6 -DCMAKE_INSTALL_PREFIX=/path/to/mochow-cpp-sdk-install
7
8cmake --build . -- -j
9cmake --build . --target install
常用 CMake 选项如下:
| 选项 | 默认值 | 选项含义 |
|---|---|---|
| MOCHOW_BUILD_SHARED | ON | 构建动态库。取值:libmochow_cpp_sdk.so;libmochow_cpp_sdk.a。 |
| MOCHOW_BUILD_EXAMPLES | ON | 是否编译 examples 目录下的可运行示例。 |
| MOCHOW_BUILD_TESTS | OFF | 是否编译单元测试。 |
| MOCHOW_BUILD_PACKAGE_SMOKE_TESTS | OFF | 是否在安装包上执行 CMake 引用校验,开启时会同时打开 MOCHOW_BUILD_TESTS。 |
| MOCHOW_ENABLE_CURL | ON | 在构建环境存在 libcurl 时启用 libcurl 传输,用于访问 https:// 端点。 |
| MOCHOW_BUILD_DOCS | OFF | 是否生成 Doxygen API 文档。 |
| MOCHOW_ENABLE_ASAN | OFF | 是否启用 AddressSanitizer,不能与 MOCHOW_ENABLE_TSAN 同时开启。 |
| MOCHOW_ENABLE_TSAN | OFF | 是否启用 ThreadSanitizer,不能与 MOCHOW_ENABLE_ASAN 同时开启。 |
安装完成后,产物写入 CMAKE_INSTALL_PREFIX 指定的目录:
| 产物 | 安装路径 | 说明 |
|---|---|---|
| 库文件 | ${CMAKE_INSTALL_LIBDIR},通常为 lib 或 lib64 |
库名为 mochow_cpp_sdk,即 libmochow_cpp_sdk.so(动态库,VERSION 为 2.4.0、SOVERSION 为 0)或 libmochow_cpp_sdk.a(静态库)。 |
| 头文件 | ${CMAKE_INSTALL_INCLUDEDIR}/mochow |
包含 AdminClient.h、ClientOptions.h、Credentials.h、Database.h、Mochow.h、MochowClient.h、Result.h、Status.h、Table.h 以及 types/ 子目录下的 Field.h、Index.h、Row.h、Schema.h、Search.h。 |
| CMake package | ${CMAKE_INSTALL_LIBDIR}/cmake/MochowCppSDK |
包含 MochowCppSDKConfig.cmake、MochowCppSDKConfigVersion.cmake 和导出的 target 文件。 |
业务代码只需要包含统一入口头文件 mochow/Mochow.h,即可获得上述全部公开头文件。
在业务工程中集成
业务工程的 CMakeLists.txt 通过 find_package(MochowCppSDK REQUIRED) 引入 SDK,并链接 MochowCppSDK::mochow:
1cmake_minimum_required(VERSION 3.2)
2project(mochow_app CXX)
3
4set(CMAKE_CXX_STANDARD 17)
5set(CMAKE_CXX_STANDARD_REQUIRED ON)
6
7find_package(MochowCppSDK REQUIRED)
8
9add_executable(mochow_app main.cpp)
10target_link_libraries(mochow_app PRIVATE MochowCppSDK::mochow)
如果 SDK 安装在自定义目录,配置业务工程时需要指定 CMAKE_PREFIX_PATH:
1mkdir -p build
2cd build
3
4cmake .. -DCMAKE_PREFIX_PATH=/path/to/mochow-cpp-sdk-install
5
6cmake --build . -- -j
初始化客户端代码
在开始 SDK 使用之前,您可以预先查看创建实例快速入门,获取实例的 Endpoint 和 API Key。然后在 C++ 代码中填充 mochow::ClientOptions,通过 mochow::MochowClient::Create 创建出一个客户端对象,即可使用该对象提供的各类接口与后端数据库进行交互。代码示例如下:
1#include <iostream>
2#include <memory>
3#include <string>
4
5#include "mochow/Mochow.h"
6
7int main() {
8 const std::string account = "root";
9 const std::string api_key = "$您的账户API密钥";
10 const std::string endpoint = "$您的实例访问端点"; // 例如:http://127.0.0.1:5287
11
12 // 根据配置创建一个 MochowClient 对象
13 mochow::ClientOptions options;
14 options.endpoint = endpoint;
15 options.credentials.account = account;
16 options.credentials.api_key = api_key;
17
18 auto client_result = mochow::MochowClient::Create(options);
19 if (!client_result.IsOk()) {
20 std::cerr << "create client failed: "
21 << client_result.GetStatus().Message() << std::endl;
22 return 1;
23 }
24
25 std::shared_ptr<mochow::MochowClient> client = client_result.MoveValue();
26
27 // 此处可以继续调用建库、建表、写入和检索等接口。
28
29 mochow::Status status = client->Close();
30 if (!status.IsOk()) {
31 std::cerr << "close client failed: " << status.Message() << std::endl;
32 return 1;
33 }
34 return 0;
35}
mochow::ClientOptions 的字段说明如下:
| 参数 | 参数类型 | 是否必选 | 参数配置 |
|---|---|---|---|
| endpoint | std::string | 是 | 实例的访问端点,需要带协议前缀。取值:http://host:port:明文访问;https://host:port:加密访问,要求 SDK 构建时启用了 libcurl。 |
| credentials.account | std::string | 是 | 访问 Mochow 服务的账号,例如 root。 |
| credentials.api_key | std::string | 是 | 账号对应的 API 密钥。 |
| connect_timeout_ms | uint64_t | 否 | 建立连接的超时时间,单位为毫秒,默认值为 3000。 |
| request_timeout_ms | uint64_t | 否 | 单次请求的超时时间,单位为毫秒,默认值为 30000。 |
| retry | mochow::RetryOptions | 否 | 客户端级别的重试配置。 |
| user_agent_suffix | std::string | 否 | 追加到 User-Agent 的自定义后缀,便于在服务端日志中区分调用方。 |
| verify_ssl | bool | 否 | 访问 https:// 端点时是否校验服务端证书,默认值为 true。 |
本地调试、示例程序或 CI 场景也可以使用 mochow::ClientOptions::FromEnv() 从环境变量读取连接信息,该方法读取 MOCHOW_ENDPOINT、MOCHOW_ACCOUNT 和 MOCHOW_API_KEY,任意一项为空都会返回 InvalidArgument:
1auto options_result = mochow::ClientOptions::FromEnv();
2if (!options_result.IsOk()) {
3 std::cerr << options_result.GetStatus().Message() << std::endl;
4 return 1;
5}
6
7auto client_result = mochow::MochowClient::Create(options_result.MoveValue());
错误处理约定
C++ SDK 不使用异常传递错误,所有接口都通过返回值上报结果。这与 Python、Go 等其他语言 SDK 差异最大,接入时需要重点关注。约定如下:
- 只有输出结果的接口返回
mochow::Status,输出结果通过出参指针写回,例如MochowClient::ListDatabases(std::vector<DatabaseInfo>* databases)。 - 需要在构造阶段就可能失败的工厂方法返回
mochow::Result<T>,例如MochowClient::Create、ClientOptions::FromEnv和Schema::Builder::Build。 - 任何返回值都必须先判断是否成功,再读取结果;失败时出参内容和
Result<T>中的值都不可使用。
使用 Status 判断成功与获取错误信息
mochow::Status 通过 IsOk() 判断本次调用是否成功,失败时可以读取 SDK 侧错误码、错误信息,以及服务端返回的 HTTP 状态码、业务错误码、业务错误信息和 request id:
1mochow::Status status = client->CreateDatabase("db_test");
2if (!status.IsOk()) {
3 std::cerr << "create database failed"
4 << ", code=" << static_cast<int>(status.Code())
5 << ", message=" << status.Message()
6 << ", http_status=" << status.HttpStatus()
7 << ", server_code=" << status.ServerCode()
8 << ", server_message=" << status.ServerMessage()
9 << ", request_id=" << status.RequestId()
10 << std::endl;
11 return 1;
12}
mochow::Status 的成员方法如下:
| 方法 | 返回类型 | 方法含义 |
|---|---|---|
| IsOk() | bool | 本次调用是否成功。 |
| Code() | mochow::StatusCode | SDK 归一化后的错误码,成功时为 StatusCode::Ok。 |
| Message() | const std::string& | 错误描述。服务端返回了错误信息时与 ServerMessage() 一致,否则为 SDK 生成的描述。 |
| HttpStatus() | int | 服务端返回的 HTTP 状态码,未发出请求时为 0。 |
| ServerCode() | int | 服务端返回的业务错误码,无业务错误时为 0。 |
| ServerMessage() | const std::string& | 服务端返回的业务错误信息。 |
| RequestId() | const std::string& | 本次请求的 request id,用于和服务端日志关联。 |
mochow::StatusCode 的取值如下:
| 枚举值 | 错误含义 |
|---|---|
| StatusCode::Ok | 调用成功。 |
| StatusCode::InvalidArgument | 参数不合法。可能来自 SDK 的本地参数校验,也可能来自服务端返回的参数类错误码。 |
| StatusCode::NotConnected | 客户端不可用,例如已经调用过 MochowClient::Close()。 |
| StatusCode::HttpError | HTTP 层面的错误。 |
| StatusCode::Timeout | 请求超时,或服务端返回超时类错误码。 |
| StatusCode::AuthError | 认证或鉴权失败,例如 HTTP 401、403,或账号、API 密钥不正确。 |
| StatusCode::ServerError | 服务端返回的其他错误。 |
| StatusCode::JsonError | 请求体编码或响应体解析失败。 |
| StatusCode::RetryExhausted | 重试次数耗尽后仍未成功。 |
| StatusCode::NotSupported | 当前 SDK 或服务端不支持该能力,例如未启用 libcurl 时访问 https:// 端点。 |
| StatusCode::Cancelled | 请求被取消。 |
| StatusCode::Unknown | 未归类的错误。 |
使用 Result 获取返回值
mochow::Result<T> 把「状态」和「返回值」放在同一个返回对象里。判断成功后再取值,取值方式有两种:Value() 返回 const T&,适合只读访问;MoveValue() 以移动方式取出结果,只应调用一次。调用失败时通过 GetStatus() 拿到 mochow::Status,此时不要访问 Value() 或 MoveValue()。
1#include <iostream>
2#include <memory>
3
4#include "mochow/Mochow.h"
5
6int main() {
7 // ClientOptions::FromEnv() 返回 Result<ClientOptions>
8 auto options_result = mochow::ClientOptions::FromEnv();
9 if (!options_result.IsOk()) {
10 // 失败时只读取 Status,不要访问 Value()/MoveValue()
11 std::cerr << "load options failed: "
12 << options_result.GetStatus().Message() << std::endl;
13 return 1;
14 }
15
16 // 只读访问用 Value()
17 std::cout << "endpoint: " << options_result.Value().endpoint << std::endl;
18
19 // MochowClient::Create() 返回 Result<std::shared_ptr<MochowClient>>
20 // MoveValue() 以移动方式取出结果,只调用一次
21 auto client_result = mochow::MochowClient::Create(options_result.MoveValue());
22 if (!client_result.IsOk()) {
23 std::cerr << "create client failed: "
24 << client_result.GetStatus().Message() << std::endl;
25 return 1;
26 }
27
28 std::shared_ptr<mochow::MochowClient> client = client_result.MoveValue();
29 return client->Close().IsOk() ? 0 : 1;
30}
mochow::Result<T> 的成员方法如下:
| 方法 | 返回类型 | 方法含义 |
|---|---|---|
| IsOk() | bool | 本次调用是否成功。 |
| GetStatus() | const mochow::Status& | 本次调用的状态对象,失败时从这里读取错误码和错误信息。 |
| Value() | const T& | 以只读方式访问结果,仅在 IsOk() 为 true 时可用。 |
| MoveValue() | T&& | 以移动方式取出结果,仅在 IsOk() 为 true 时可用,且只应调用一次。 |
为单次调用设置 request id 与超时
库级接口以外的大多数接口都支持传入 mochow::RequestOptions,用于为单次调用指定 request id、超时时间、幂等键和重试策略。请求失败时可以从 Status::RequestId() 读取 request id,用于和服务端日志对齐:
1mochow::RequestOptions call_options;
2call_options.WithRequestId("order-service-req-001")
3 .WithRequestTimeoutMs(5000);
4
5mochow::Database database = client->GetDatabase("db_test");
6
7std::vector<mochow::TableInfo> tables;
8mochow::Status status = database.ListTables(&tables, call_options);
9if (!status.IsOk()) {
10 std::cerr << "list tables failed, request_id=" << status.RequestId()
11 << ", message=" << status.Message() << std::endl;
12 return 1;
13}
说明:
MochowClient::CreateDatabase、MochowClient::DropDatabase和MochowClient::ListDatabases这三个库级接口不接受RequestOptions参数,只能使用客户端级别的默认超时与重试配置。
评价此篇文章
