10.2. 统一SQL C 接口
10.2.1. 简介
统一SQL提供了 C API ,可供 C/C++ 程序直接调用;用户只需要正确地引用 unisql.h
与链接 libunisql.so
即可使用 C API。
10.2.2. 接口说明
接口签名:
extern int TransferSQL(
int sourceDbTypeCode,
int targetDbTypeCode,
const char* sourceSqlStr,
char* targetSqlStr,
int targetSqlMemoryLen,
const char* jsonParameter);
要使用 C 接口,您需要发布包中对应操作系统平台的 so 动态库,以及 unisql.h 头文件。
C 接口同样支持读取统一 SQL 配置文件,具体使用方法可参考 配置文件 。
10.2.3. 接口请求参数
C 接口的每一项参数说明如下:
参数名 |
类型 |
是否必须 |
说明 |
示例 |
---|---|---|---|---|
sourceDbTypeCode |
int |
是 |
源数据库方言编码,见发布包中 unisql.h 的 |
UNISQL_DBTYPE_ORACLE |
targetDbTypeCode |
int |
是 |
目标数据库方言编码,见发布包中 unisql.h 的 |
UNISQL_DBTYPE_GAUSSDB_ORACLE |
sourceSqlStr |
const char* |
是 |
源SQL语句 |
“select name, avg(score) from student_score group by name” |
targetSqlStr |
char* |
是 |
转换后的 SQL 内存空间,内存由调用方自行管理,推荐使用源 SQL 长度的 4 倍大小 |
buffer |
targetSqlMemoryLen |
int |
是 |
targetSqlStr 的内存大小,比如传入 101 则可以存储长度为 100 的字符 |
101 |
jsonParameter |
const char* |
否 |
转换配置选项,预留扩展字段,目前传 NULL 即可 |
NULL |
10.2.4. 接口枚举说明
统一 SQL 的 C API 方言编码枚举如下:
#define UNISQL_DBTYPE_LIGHTDB_MYSQL 1 // LIGHTDB MYSQL模式
#define UNISQL_DBTYPE_LIGHTDB_ORACLE 2 // LIGHTDB ORACLE模式
#define UNISQL_DBTYPE_LIGHTDB_POSTGRESQL 3 // LIGHTDB POSTGRESQL模式
#define UNISQL_DBTYPE_DM 4 // 达梦
#define UNISQL_DBTYPE_MYSQL 5 // MYSQL
#define UNISQL_DBTYPE_TDSQL_MYSQL 6 // TDSQL MYSQL模式
#define UNISQL_DBTYPE_MYSQL_80 7 // MYSQL8
#define UNISQL_DBTYPE_OCEAN_BASE_MYSQL 8 // OceanBase MYSQL模式
#define UNISQL_DBTYPE_OCEAN_BASE_ORACLE 9 // OceanBase ORACLE模式
#define UNISQL_DBTYPE_OPENGAUSS 10 // OPENGAUSS
#define UNISQL_DBTYPE_ORACLE 11 // ORACLE
#define UNISQL_DBTYPE_POSTGRESQL 12 // POSTGRESQL
#define UNISQL_DBTYPE_GOLDENDB_MYSQL 13 // GOLDENDB MYSQL模式
#define UNISQL_DBTYPE_GOLDENDB_ORACLE 14 // GOLDENDB ORACLE模式
#define UNISQL_DBTYPE_GAUSSDB_MYSQL 15 // 高斯 MYSQL模式
#define UNISQL_DBTYPE_GAUSSDB_ORACLE 16 // 高斯 ORACLE模式
#define UNISQL_DBTYPE_SQLSVR 17 // SQLSVR模式
#define UNISQL_DBTYPE_TDSQL_PG_ORACLE 18 // tdsql_pg oracle模式
#define UNISQL_DBTYPE_GAUSSDB500_ORACLE 19 // 高斯 ORACLE模式,(GaussDB Kernel V500R002C10 build f6002322)版本
10.2.5. 接口返回参数
返回类型是一个 int ,取值有 3 种情况:
返回 0: 代表转换成功
返回 -1: 代表转换异常,需要在统一 SQL 的日志中查看具体失败原因
返回大于 0 的数字:代表传入的 targetSqlMemoryLen 空间不足,返回值表示需要的空间
10.2.6. 调用示例
本例子假设统一 SQL 的发布包放在 /home/lightdb/LightDB1.0-unisql-V202403-00-000
下,示例步骤为:
设置环境变量,为了运行示例:
export LD_LIBRARY_PATH=/home/lightdb/LightDB1.0-unisql-V202403-00-000/c/x86_64/lib:$LD_LIBRARY_PATH
编写示例代码,命名为 test.c
编译示例代码:
gcc test.c -L /home/lightdb/LightDB1.0-unisql-V202403-00-000/c/x86_64/lib -I /home/lightdb/LightDB1.0-unisql-V202403-00-000/c/x86_64/include -lunisql -o test
执行示例代码查看效果
示例代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "unisql.h"
int main() {
// 数据库类型见unisql.h
// 原始SQL数据库类型
int sourceDbTypeCode=UNISQL_DBTYPE_ORACLE;
// 目标SQL数据库类型
int targetDbTypeCode=UNISQL_DBTYPE_GAUSSDB_ORACLE;
// 原始SQL
char* sourceSqlStr="SELECT o.order_id, o.order_date, c.customer_name, c.city, o.amount FROM unisql_orders o JOIN unisql_customers c ON o.customer_id = c.customer_id and c.customer_id=? and c.city=?;";
// 目标SQL
char* targetSqlStr=NULL;
// 转换配置选项,预留扩展字段,目前传 NULL 即可
char* jsonParameter = NULL;
// 转换结果 0表示成功,>0表示目标串长度不够,<0表示失败
int transRet=0;
// 预设目标SQL的长度为原始SQL的4倍
int targetSqlStrLen = strlen(sourceSqlStr)*4;
// 分配内存
targetSqlStr=(char*)malloc(targetSqlStrLen);
printf("Before transfer sql is:%s\n",sourceSqlStr);
// 调用TransferSQL转换函数
transRet = TransferSQL(sourceDbTypeCode, targetDbTypeCode, sourceSqlStr, targetSqlStr, targetSqlStrLen, jsonParameter);
if (transRet>0){
// 预设目标SQL的长度不够,重新分配内存
targetSqlStr=(char*) realloc (targetSqlStr, transRet) ;
transRet =TransferSQL (sourceDbTypeCode, targetDbTypeCode, sourceSqlStr, targetSqlStr, transRet, jsonParameter);
}
if(transRet == 0)
{
printf("After transfer sql is:%s\n",targetSqlStr);
}else if(transRet < 0)
{
printf("SQL Convert Failed:%d\n",transRet);
}
// 释放内存
free(targetSqlStr);
return 0;
}
示例执行结果:
Before transfer sql is:SELECT o.order_id, o.order_date, c.customer_name, c.city, o.amount FROM unisql_orders o JOIN unisql_customers c ON o.customer_id = c.customer_id and c.customer_id=? and c.city=?;
After transfer sql is:SELECT o.order_id,o.order_date,c.customer_name,c.city,o.amount FROM unisql_orders AS o JOIN unisql_customers AS c ON o.customer_id=c.customer_id AND c.customer_id=? AND c.city=?