libcassandra开发示例

一、前言

libcassandra是Cassandra官方推出的C/C++ API库。与thrift接口(另一个API库)相比,其接口更丰富,对类型匹配更细致。

通过实践,私下也觉得libcassandra比thrift接口更好用。当然这只是个人观点。

有关libcassandra的特点、安装等,在另一篇随笔里已有介绍,本篇把相应代码示例补上。

二、环境

创建keyspace、table如下:

create keyspace hs WITH replication={‘class‘:‘SimpleStrategy‘, ‘replication_factor‘:2};

use hs;

create columnfamily SAMPLE(
  ID        int,
  GID       bigint,
  DATA      blob,
  PRIMARY KEY(ID)
);

三、示例代码

为简便起见,这里只写了Insert和select的示例,update和delete的示例与insert类似。

#include "cassandra.h"
#include <string.h>
#include <stdio.h>

class LibCassDemo
{
private:
     CassFuture     *m_pConnFuture;
     CassCluster    *m_pCluster;
     CassPrepared   *m_pInsertStmt = NULL;
     CassPrepared   *m_pSelectStmt = NULL;
public:
     CassSession    *m_pSession;  //其实该成员变量也应是私有的,为偷懒改成公共的了

public:
    LibCassDemo() {}
    ~LibCassDemo()
    {
        disconnect();
    }

    //连接Cassandra
    bool connect()
    {
       if (m_bConnect) return true;

       m_pCluster = cass_cluster_new();
       m_pSession = cass_session_new();
       cass_cluster_set_contact_points(m_pCluster, "localhost");
       cass_cluster_set_credentials(m_pCluster, "cassandra", "cassandra");
       m_pConnFuture = cass_session_connect(m_pSession, m_pCluster);
       if (cass_future_error_code(m_pConnFuture)!=CASS_OK)  //错误处理
       {
          const char* message;
          size_t message_length;
          cass_future_error_message(m_pConnFuture, &message, &message_length);
          fprintf(stderr, "Unable to connect: ‘%.*s‘\n", (int)message_length, message);
          return false;
       }
       printf("Connect Successful!\n");
       m_bConnect = true;
       return m_bConnect;
    }

    //断开Cassandra
    void disconnect()
    {
       if (!m_bConnect) return;
       //关闭session并释放局部变量
       CassFuture *pCloseFuture = cass_session_close(m_pSession);
       cass_future_wait(pCloseFuture);
       cass_future_free(pCloseFuture);
       //释放所有成员变量
       if (m_pInsertStmt) cass_prepared_free(m_pInsertStmt);
       if (m_pSelectStmt) cass_prepared_free(m_pSelectStmt);
       cass_future_free(m_pConnFuture);
       cass_cluster_free(m_pCluster);
       cass_session_free(m_pSession);
       m_bConnect = false;
       printf("Disonnect Successful!\n");
    }

    //相同的INSERT语句只须Prepare一次即可
    CassPrepared * buildInsertStmt()
    {
       string cql;
       if (m_pInsertStmt==NULL)
       {
          cql = "INSERT INTO SAMPLE (ID, GID, DATA) VALUES (?, ?, ?)";
          CassFuture *pPrepareFuture = cass_session_prepare(m_pSession, cql.c_str());
          if (cass_future_error_code(pPrepareFuture)!=CASS_OK)  //错误处理
          {
             const char* message;
             size_t message_length;
             cass_future_error_message(pPrepareFuture, &message, &message_length);
             fprintf(stderr, "Unable to prepare Insert Statement: ‘%.*s‘\n", (int)message_length, message);
          }
          else
             m_pInsertStmt = (CassPrepared*)cass_future_get_prepared(pPrepareFuture);
          cass_future_free(pPrepareFuture);
       }
       return m_pInsertStmt;
    }

    //同样的,相同的SELECT语句也只须Prepare一次
    CassPrepared * buildSelectStmt()
    {
       string cql;
       if (m_pSelectStmt==NULL)
       {
          cql = "SELECT ID, GID, DATA FROM SAMPLE WHERE ID=? ";

          CassFuture *pPrepareFuture = cass_session_prepare(m_pSession, cql.c_str());
          if (cass_future_error_code(pPrepareFuture)!=CASS_OK)  //错误处理
          {
             const char* message;
             size_t message_length;
             cass_future_error_message(pPrepareFuture, &message, &message_length);
             fprintf(stderr, "Unable to prepare Select Statement: ‘%.*s‘\n", (int)message_length, message);
          }
          else
             m_pSelectStmt = (CassPrepared*)cass_future_get_prepared(pPrepareFuture);
          cass_future_free(pPrepareFuture);
       }
       return m_pSelectStmt;
    }

   //获取int型数据
    int32_t getInt32FromRow(const CassRow *row, const uint16_t index)
    {
       int32_t i32;
       CassValue *value = (CassValue*)cass_row_get_column(row, index);
       cass_value_get_int32(value, &i32);
       return i32;
    }

    //获取bigint型数据
    int64_t getInt64FromRow(const CassRow* row, const uint16_t index)
    {
       int64_t i64;
       CassValue *value = (CassValue*)cass_row_get_column(row, index);
       cass_value_get_int64(value, &i64);
       return i64;
    }

    //获取blob型数据
    CassError getStringFromRow(const CassRow *row, const uint16_t index, UCHAR** data, int32_t &len)
    {
       const cass_byte_t* buf;
       size_t sz;
       CassValue *value = (CassValue*)cass_row_get_column(row, index);
       CassError cer = cass_value_get_bytes(value, &buf, &sz);
       if (cer==CASS_OK)
       {
          *data = (UCHAR *)malloc(sz +1);
          memcpy(*data, buf, sz);
          *(*data+sz+1)=‘\0‘;
          len = (int32_t)sz;
       }
       return cer;
   }

}

int main (int argc, char *argv[])
{
   //初始化
   LibCassDemo *cass = new LibCassDemo();
   cass->connect();
   UCHAR primData[128];
   //Init primData here ...

   //写入数据
   CassPrepared *prepared = cass->buildInsertStmt();
   CassBatch *batch = cass_batch_new(CASS_BATCH_TYPE_LOGGED);  //批量方式
   for (int i=0; i<10; i++)
   {
      CassStatement * stmt = cass_prepared_bind(prepared);
      cass_statement_set_consistency(stmt, CASS_CONSISTENCY_QUORUM);
      cass_statement_bind_int32(stmt, 0, i);  //第一个是0
      cass_statement_bind_int64(stmt, 1, (i<<8 + i));
      cass_statement_bind_bytes(stmt, 2, primData, 128);
      cass_batch_add_statement(batch, stmt);
      cass_statement_free(stmt);
   }
     CassFuture *batchFuture = cass_session_execute_batch(cass->m_pSession, batch);
     if (cass_future_error_code(batchFuture)!=CASS_OK)  //错误处理
     {
        const char* message;
        size_t message_length;
        cass_future_error_message(batchFuture, &message, &message_length);
        fprintf(stderr, "Unable to execute BATCH: ‘%.*s‘\n", (int)message_length, message);
     }
     cass_future_free(batchFuture);
     cass_batch_free(batch);

   //读取数据
   prepared = cass->buildSelectStmt();
   stmt = cass_prepared_bind(prepared);
   int id=7;
   cass_statement_bind_int32(stmt, 0, id);
   CassFuture *readFuture = cass_session_execute(cass->m_pSession, stmt);
   CassResult *result = (CassResult*)cass_future_get_result(readFuture);  //从CassFuture获取查询结果
   CassIterator *iter = cass_iterator_from_result(result);  //转换为CassIterator
   while(cass_iterator_next(iter))
   {
      CassRow *row = (CassRow*)cass_iterator_get_row(iter);  //CassRow和CassError对象无须释放
      printf("ID=%d, GID=%ld, ", cass->getInt32FromRow(row, 0), cass->getInt64FromRow(row, 1));
      UCHAR *pData = (UCHAR *)malloc(128);
      int len;
      cass->getStringFromRow(row, 2, &pData, len);
      printf("DATA is :%s\n", pData);
      free(pData);
   }
   cass_iterator_free(iter);
   cass_result_free(result);
   cass_future_free(readFuture);
   cass_statement_free(stmt);

   //释放资源
   delete cass;
}
 
时间: 07-22

libcassandra开发示例的相关文章

[转]Net Framework引路蜂地图开发示例

From:http://www.2cto.com/kf/201207/140421.html 引路蜂地图也提供对.Net Framework平台的支持,可以开发桌面地图应用,由于Mono C#的跨平台特性,使用Visual Studio 和Mono引路蜂地图开发包开发的地图应用可以运行于Windows ,Lunix,Unix,Mac OS等平台.开发桌面应用比开发移动应用要容易的多,屏幕,内存等方面都比移动平台要宽裕的多.下面使用一个简单的应用来介绍一下.Net Framework引路蜂地图开发

Spring+Mybatis开发示例

写下来留个纪念(^~^)大神可飘过 1,实现Spring+Mybatis+数据源的配置 2,实现枚举到数据库TINYINT类型的转换 3,slf4j日志配置方法 4,数据库增+删+改+查操作 5,实现效果界面+项目配置目录树       6,关键代码: a)控制器 package com.fresh.lyh.simple.controller; import com.fresh.lyh.simple.model.Simple; import com.fresh.lyh.simple.model.

SharePoint 2013 工作流之Visual Studio开发示例篇

原文:SharePoint 2013 工作流之Visual Studio开发示例篇 SharePoint 2013引用了WF4.0 Foundation,支持使用Designer和Visio进行设计,但是功能受限,而Visual Studio可以开发功能更加丰富的工作流,下面我们简单举个例子. 1.本例使用的是VS 2013版本,新建一个SharePoint空项目: 2.部署为服务器场解决方案,如下图: 3.添加新项,选择工作流模板,如下图: 4.本例选择列表工作流,当然你按照自己的需要选择:

NPAPI火狐插件VS2013开发示例

NPAPI火狐插件VS2013开发示例 下面是我根据网上开发示例自己做的一个demo,并提供代码下载. 开发环境 Windows 8.1 x64 Visual studio 2013 准备工作 首先需要从官网下载火狐源码(也可以下载其它版本),里面有开发插件所需要的头文件. 官网下载地址:,http://download.cdn.mozilla.net/pub/mozilla.org/firefox/releases/33.0/source/firefox-33.0.source.tar.bz2

pyqt开发教程-搭建环境和开发示例

搭建环境和开发示例 * 安装 安装包 要对应python的版本 32位安装包(我PC上) http://jaist.dl.sourceforge.net/project/pyqt/PyQt4/PyQt-4.11.2/PyQt4-4.11.2-gpl-Py2.7-Qt4.8.6-x32.exe 或 64位安装包 http://jaist.dl.sourceforge.net/project/pyqt/PyQt4/PyQt-4.11.2/PyQt4-4.11.2-gpl-Py2.7-Qt4.8.6-

iStylePDF c#集成开发示例

iStylePDF安装包自带了ActiveX控件,下载安装包安装之后就可以使用,如果没有安装包请到360软件管家或者腾讯软件管家搜索下载.C#的Form中集成ActiveX控件还是非常简单的,选择添加COM组件,查看iStylePDFclass控件.拖入到Form中即可. iStylePDF提供了丰富的接口来控制PDF的显示,接口的调用也是非常的简单,类似VBA模式,只需要点点点即可.比如隐藏菜单条.代码如下: 整体调用结果如下: 菜单栏和工具栏的控制代码如下: 如需要更多示例源代码,请咨询QQ

移动端报表JS开发示例--获取定位

上次分享了移动端报表JS开发的系统概念,后来我又回去摸索了一些案例.之前接触到的FineReport的APP客户端可以用来打卡签到,就好奇研究了以下,这次就来聊一聊报表移动端开发如何实现定位功能. 1. 解决思路 在用FineReport设计模板的时候添加一个按钮控件,点击该按钮的时候,获取当前地理位置,并将该位置信息复制给某个单元格,最后在客户端填报当前模板即可. 2. 示例 实现如下图所示效果,点击地理位置按钮获取当前位置与当前时间,并显示在下方对应的单元格中: 2.1 模板制作 打开设计器

Android cocos2dx游戏开发——示例程序HelloCpp源码分析

本文通过分析cocos2dx提供的示例程序HelloCpp来分析cocos2dx的启动过程. 我们从HelloCpp.java开始: [java] view plaincopyprint? package org.cocos2dx.hellocpp; import org.cocos2dx.lib.Cocos2dxActivity; import android.os.Bundle; public class HelloCpp extends Cocos2dxActivity{ protecte

SkylineGlobe MFC C++ 开发示例代码

SkylineGlobe的SDK底层是跨平台的C++内核,面向不同平台封装原生的API,具有很高的执行效率, 下面是C++二次开发时的示例代码: #import "D:\Program Files (x86)\Skyline\TerraExplorer Pro\TerraExplorerX.dll" no_namespace, named_guids void OnLoadFinished(); void OnFileClosing(); void OnFrame(); void On