虽然在ObConnector的帮助下,Oceanbase已经能够被psql等通用SQL客户端访问,但在一些特定场合(例如调试)可能还是需要对查询有更强的控制,这时候依然需要用户自己编写C/Java客户端,下面以一个例子简要说明C客户端的编写方法。
#include
#include
#include
#include "oceanbase.h"
/结果打印函数开始//
const int MAX_DISPLAY_ROW_KEY_LEN = 48;
char* get_display_row_key(const char* row_key, int64_t row_key_len)
{
const int aux_len = 2;
const int ending_len = 1;
static char dis_row_key[MAX_DISPLAY_ROW_KEY_LEN + aux_len + ending_len];
int64_t dis_row_key_len = row_key_len 0 && s[s_len - 1] == 'n')
{
s[s_len - 1] = '';
s_len--;
}
return s;
}
void pcell(OB_CELL* cell)
{
printf("%ld", cell->table_len);
printf("%.*st%s(%ld)t%.*st",
(int)cell->table_len, cell->table,
rowkey2hex(cell->row_key, cell->row_key_len), cell->row_key_len,
(int)cell->column_len, cell->column);
switch (cell->v.type)
{
case OB_INT_TYPE:
printf("%ld", cell->v.v.v_int);
break;
case OB_VARCHAR_TYPE:
printf("%.*s", cell->v.v.v_varchar.len, cell->v.v.v_varchar.p);
break;
case OB_DATETIME_TYPE:
printf("t%s(%d.%d)", trim_newline(ctime(&(cell->v.v.v_datetime.tv_sec))),
cell->v.v.v_datetime.tv_sec, cell->v.v.v_datetime.tv_usec);
break;
}
if (cell->is_null || cell->is_row_not_exist || cell->is_row_changed)
{
printf("(%s%s%s)n",
cell->is_null ? "NULL " : "",
cell->is_row_not_exist ? "ROW NOT EXIST " : "",
cell->is_row_changed ? "NEW ROW" : "");
}
else
{
printf("n");
}
}
void pcolumnname(OB_RES* res)
{
OB_CELL* cell = NULL;
cell = ob_fetch_cell(res);
if (NULL != cell)
{
printf("tt%.*s", cell->column_len, cell->column);
}
while ((cell = ob_fetch_cell(res)) != NULL && !cell->is_row_changed)
{
printf("t%.*s", cell->column_len, cell->column);
}
}
void pres(OB_RES* res)
{
pcolumnname(res);
printf("n");
ob_res_seek_to_begin_cell(res);
OB_ROW* row = NULL;
while ((row = ob_fetch_row(res)) != NULL)
{
int64_t i = 0;
printf("%s", get_display_row_key(row->cell[0].row_key, row->cell[0].row_key_len));
for (; i cell_num; i++)
{
switch (row->cell[i].v.type)
{
case OB_INT_TYPE:
printf("t%ld", row->cell[i].v.v.v_int);
break;
case OB_VARCHAR_TYPE:
printf("t%.*s", row->cell[i].v.v.v_varchar.len, row->cell[i].v.v.v_varchar.p);
break;
case OB_DATETIME_TYPE:
printf("t%s(%d.%d)", trim_newline(ctime(&(row->cell[i].v.v.v_datetime.tv_sec))),
row->cell[i].v.v.v_datetime.tv_sec, row->cell[i].v.v.v_datetime.tv_usec);
break;
}
}
printf("n");
}
}
/结果打印函数结束//
上面是结果输出部分,主要是处理一些字符串和格式化问题,稍微看看即可。重点请关注下面的核心逻辑
int main(int argc, char **argv)
{
/// select nick,auc_cnt_max_cnt,prov from test_seller_wm_4
/// where /*+ rowkey, issue_id:6,cat_id:8,selr_user_id:8 */ issue_id = '201145' and cat_id=16
/// and nick='lovinlovin3' and prov='shanghai3' limit 2 offset 0;
/*
char* table = "collect_item";
char* column1 = "item_collector_count";
char* column2 = "item_collect_count";
char* rowkey1 = "AAAAAAAAA";
char* rowkey2 = "AAAAAAAAF";
*/
char* table = "test_seller_wm_4";
char* column1 = "nick";
char* column2 = "prov";
char* column3 = "auc_cnt_max_cnt";
char rowkey1[44];
char rowkey2[44];
OB_ERR_CODE err = OB_ERR_SUCCESS;
memset(rowkey1, 0x00, 44);
memset(rowkey2, 0x00, 44);
memcpy(&rowkey1[0], "201145", 6);
rowkey1[8+6-1] = 16;
memcpy(&rowkey2[0], "201145", 6);
rowkey2[8+6-1] = 16;
memset(&rowkey2[14], 0xff, 8);
OB* ob = ob_api_init();
if (NULL == ob)
{
fprintf(stderr, "ob_init error: %sn", ob_error());
return 1;
}
ob_api_debug_log(ob, "DEBUG", NULL);
if (argc > 2)
{
fprintf(stderr, "connection param used: %s:%sn", argv[1], argv[2]);
char *rs_ip = argv[1];
int rs_port = atoi(argv[2]);
// 连接OceanBase
err = ob_connect(ob, rs_ip, rs_port, NULL, NULL);
}
else
{
// 连接OceanBase
err = ob_connect(ob, "172.24.131.234", 5433, NULL, NULL);
}
if (OB_ERR_SUCCESS != err)
{
fprintf(stderr, "ob_connect error: %sn", ob_error());
}
else
{
// 获得OB_SCAN结构体
OB_SCAN* scan_st = ob_acquire_scan_st(ob);
if (NULL == scan_st)
{
fprintf(stderr, "ob_acquire_scan_st error: %sn", ob_error());
}
else
{
memset(rowkey1, 0x00, 22);
memset(rowkey2, 0xff, 22);
ob_scan(scan_st, table, rowkey1, 22, 1, rowkey2, 22, 1);
ob_scan_column(scan_st, "nick", 1);
ob_scan_column(scan_st, "prov", 1);
//ob_scan_complex_column(scan_st, "1=1", "_expr0", 0);
//ob_scan_complex_column(scan_st, "2 3)
{
}
else
{
//ob_scan_set_where(scan_st, "`_expr0` = `_expr0` and `prov`='beijing'");
fprintf(stderr, "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++n");
//ob_scan_set_where(scan_st, "_expr2
执行方式:
./scan_client rs_ip rs_port
简要说明:
主要函数包括:
ob_api_init,ob_connect,ob_acquire_scan_st,ob_scan,ob_scan_column,ob_scan_complex_column,ob_scan_set_where,ob_scan_set_limit,ob_exec_scan,ob_fetch_cell,ob_release_scan_st,ob_api_destroy
其中ob_scan,ob_scan_column,ob_scan_complex_column,ob_scan_set_where,ob_scan_set_limit,ob_exec_scan这几个函数是与scan相关的(oceanbase还支持get,支持单个或者多个cell的获取,而不是scan这种按行获取)
Oceanbase C客户端 API手册下载:
http://ishare.iask.sina.com.cn/f/22948741.html