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_ 的定义

UNISQL_DBTYPE_ORACLE

targetDbTypeCode

int

目标数据库方言编码,见发布包中 unisql.h 的 UNISQL_DBTYPE_ 的定义

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 下,示例步骤为:

  1. 设置环境变量,为了运行示例: export LD_LIBRARY_PATH=/home/lightdb/LightDB1.0-unisql-V202403-00-000/c/x86_64/lib:$LD_LIBRARY_PATH

  2. 编写示例代码,命名为 test.c

  3. 编译示例代码: 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

  4. 执行示例代码查看效果

示例代码:

#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=?