LCOV - code coverage report
Current view: top level - root/contrail/src/contrail-common/database/cassandra/cql - cql_if.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 1087 2094 51.9 %
Date: 2026-11-09 02:10:49 Functions: 137 260 52.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //
       2             : // Copyright (c) 2015 Juniper Networks, Inc. All rights reserved.
       3             : // Copyright Contributors to the OpenSDN project
       4             : //
       5             : 
       6             : #include <assert.h>
       7             : #include <fstream>
       8             : 
       9             : #include <boost/foreach.hpp>
      10             : #include <boost/algorithm/string.hpp>
      11             : #include <boost/algorithm/string/join.hpp>
      12             : #include <boost/unordered_map.hpp>
      13             : #include <boost/system/error_code.hpp>
      14             : 
      15             : #include <linux/version.h>
      16             : #if defined(RHEL_MAJOR) && (RHEL_MAJOR >= 9)
      17             : #include <cassandra/cassandra.h>
      18             : #else
      19             : #include <cassandra.h>
      20             : #endif
      21             : 
      22             : #include <base/logging.h>
      23             : #include <base/misc_utils.h>
      24             : #include <base/task.h>
      25             : #include <base/timer.h>
      26             : #include <base/string_util.h>
      27             : #include <base/address_util.h>
      28             : #include <io/event_manager.h>
      29             : #include <database/gendb_if.h>
      30             : #include <database/gendb_constants.h>
      31             : #include <database/cassandra/cql/cql_if.h>
      32             : #include <database/cassandra/cql/cql_if_impl.h>
      33             : #include <database/cassandra/cql/cql_lib_if.h>
      34             : 
      35             : using namespace boost::system;
      36             : 
      37             : #define CQLIF_DEBUG "CqlTraceBufDebug"
      38             : #define CQLIF_INFO "CqlTraceBufInfo"
      39             : #define CQLIF_ERR  "CqlTraceBufErr"
      40             : 
      41             : SandeshTraceBufferPtr CqlTraceDebugBuf(SandeshTraceBufferCreate(
      42             :      CQLIF_DEBUG, 10000));
      43             : SandeshTraceBufferPtr CqlTraceInfoBuf(SandeshTraceBufferCreate(
      44             :      CQLIF_INFO, 10000));
      45             : SandeshTraceBufferPtr CqlTraceErrBuf(SandeshTraceBufferCreate(
      46             :      CQLIF_ERR, 20000));
      47             : 
      48             : #define CQLIF_DEBUG_TRACE(_Msg)                                           \
      49             :     do {                                                                  \
      50             :         std::stringstream _ss;                                            \
      51             :         _ss << __func__ << ":" << __FILE__ << ":" <<                      \
      52             :             __LINE__ << ": " << _Msg;                                     \
      53             :         CQL_TRACE_TRACE(CqlTraceDebugBuf, _ss.str());                     \
      54             :        } while (false)                                                    \
      55             : 
      56             : #define CQLIF_INFO_TRACE(_Msg)                                            \
      57             :     do {                                                                  \
      58             :         std::stringstream _ss;                                            \
      59             :         _ss << __func__ << ":" << __FILE__ << ":" <<                      \
      60             :             __LINE__ << ": " << _Msg;                                     \
      61             :         CQL_TRACE_TRACE(CqlTraceInfoBuf, _ss.str());                      \
      62             :        } while (false)                                                    \
      63             : 
      64             : #define CQLIF_ERR_TRACE(_Msg)                                             \
      65             :     do {                                                                  \
      66             :         std::stringstream _ss;                                            \
      67             :         _ss << __func__ << ":" << __FILE__ << ":" <<                      \
      68             :             __LINE__ << ": " << _Msg;                                     \
      69             :         CQL_TRACE_TRACE(CqlTraceErrBuf, _ss.str());                       \
      70             :        } while (false)                                                    \
      71             : 
      72             : #define CASS_LIB_TRACE(_Level, _Msg)                                      \
      73             :     do {                                                                  \
      74             :         if (_Level == log4cplus::ERROR_LOG_LEVEL) {                       \
      75             :             CQL_TRACE_TRACE(CqlTraceErrBuf, _Msg);                        \
      76             :         } else if (_Level == log4cplus::DEBUG_LOG_LEVEL) {                \
      77             :             CQL_TRACE_TRACE(CqlTraceDebugBuf, _Msg);                      \
      78             :         } else {                                                          \
      79             :             CQL_TRACE_TRACE(CqlTraceInfoBuf, _Msg);                       \
      80             :         }                                                                 \
      81             :     } while (false)                                                       \
      82             : 
      83             : #define CQLIF_LOG(_Level, _Msg)                                           \
      84             :     do {                                                                  \
      85             :         if (LoggingDisabled()) break;                                     \
      86             :         log4cplus::Logger logger = log4cplus::Logger::getRoot();          \
      87             :         LOG4CPLUS_##_Level(logger, __func__ << ":" << __FILE__ << ":" <<  \
      88             :             __LINE__ << ": " << _Msg);                                    \
      89             :     } while (false)
      90             : 
      91             : #define CQLIF_LOG_ERR(_Msg)                                               \
      92             :     do {                                                                  \
      93             :         LOG(ERROR, __func__ << ":" << __FILE__ << ":" << __LINE__ << ": " \
      94             :             << _Msg);                                                     \
      95             :     } while (false)
      96             : 
      97             : namespace cass {
      98             : namespace cql {
      99             : namespace impl {
     100             : 
     101             : // CassString convenience structure
     102             : struct CassString {
     103       41774 :     CassString() :
     104       41774 :         data(NULL),
     105       41774 :         length(0) {
     106       41774 :     }
     107             : 
     108             :     CassString(const char *data) :
     109             :         data(data),
     110             :         length(strlen(data)) {
     111             :     }
     112             : 
     113             :     CassString(const char* data, size_t length) :
     114             :         data(data),
     115             :         length(length) {
     116             :     }
     117             : 
     118             :     const char* data;
     119             :     size_t length;
     120             : };
     121             : 
     122             : // CassUuid encode and decode
     123        4571 : static inline void encode_uuid(char* output, const CassUuid &uuid) {
     124        4571 :     uint64_t time_and_version = uuid.time_and_version;
     125        4571 :     output[3] = static_cast<char>(time_and_version & 0x00000000000000FFLL);
     126        4571 :     time_and_version >>= 8;
     127        4571 :     output[2] = static_cast<char>(time_and_version & 0x00000000000000FFLL);
     128        4571 :     time_and_version >>= 8;
     129        4571 :     output[1] = static_cast<char>(time_and_version & 0x00000000000000FFLL);
     130        4571 :     time_and_version >>= 8;
     131        4571 :     output[0] = static_cast<char>(time_and_version & 0x00000000000000FFLL);
     132        4571 :     time_and_version >>= 8;
     133             : 
     134        4571 :     output[5] = static_cast<char>(time_and_version & 0x00000000000000FFLL);
     135        4571 :     time_and_version >>= 8;
     136        4571 :     output[4] = static_cast<char>(time_and_version & 0x00000000000000FFLL);
     137        4571 :     time_and_version >>= 8;
     138             : 
     139        4571 :     output[7] = static_cast<char>(time_and_version & 0x00000000000000FFLL);
     140        4571 :     time_and_version >>= 8;
     141        4571 :     output[6] = static_cast<char>(time_and_version & 0x000000000000000FFLL);
     142             : 
     143        4571 :     uint64_t clock_seq_and_node = uuid.clock_seq_and_node;
     144       41139 :     for (size_t i = 0; i < 8; ++i) {
     145       36568 :         output[15 - i] = static_cast<char>(clock_seq_and_node & 0x00000000000000FFL);
     146       36568 :         clock_seq_and_node >>= 8;
     147             :     }
     148        4571 : }
     149             : 
     150           0 : static inline char* decode_uuid(char* input, CassUuid* output) {
     151           0 :   output->time_and_version  = static_cast<uint64_t>(static_cast<uint8_t>(input[3]));
     152           0 :   output->time_and_version |= static_cast<uint64_t>(static_cast<uint8_t>(input[2])) << 8;
     153           0 :   output->time_and_version |= static_cast<uint64_t>(static_cast<uint8_t>(input[1])) << 16;
     154           0 :   output->time_and_version |= static_cast<uint64_t>(static_cast<uint8_t>(input[0])) << 24;
     155             : 
     156           0 :   output->time_and_version |= static_cast<uint64_t>(static_cast<uint8_t>(input[5])) << 32;
     157           0 :   output->time_and_version |= static_cast<uint64_t>(static_cast<uint8_t>(input[4])) << 40;
     158             : 
     159           0 :   output->time_and_version |= static_cast<uint64_t>(static_cast<uint8_t>(input[7])) << 48;
     160           0 :   output->time_and_version |= static_cast<uint64_t>(static_cast<uint8_t>(input[6])) << 56;
     161             : 
     162           0 :   output->clock_seq_and_node = 0;
     163           0 :   for (size_t i = 0; i < 8; ++i) {
     164           0 :     output->clock_seq_and_node |= static_cast<uint64_t>(static_cast<uint8_t>(input[15 - i])) << (8 * i);
     165             :   }
     166           0 :   return input + 16;
     167             : }
     168             : 
     169          78 : static const char * DbDataType2CassType(
     170             :     const GenDb::DbDataType::type &db_type) {
     171          78 :     switch (db_type) {
     172           6 :       case GenDb::DbDataType::AsciiType:
     173           6 :         return "ascii";
     174           8 :       case GenDb::DbDataType::LexicalUUIDType:
     175           8 :         return "uuid";
     176           6 :       case GenDb::DbDataType::TimeUUIDType:
     177           6 :         return "timeuuid";
     178          20 :       case GenDb::DbDataType::Unsigned8Type:
     179             :       case GenDb::DbDataType::Unsigned16Type:
     180             :       case GenDb::DbDataType::Unsigned32Type:
     181          20 :         return "int";
     182           6 :       case GenDb::DbDataType::Unsigned64Type:
     183           6 :         return "bigint";
     184           6 :       case GenDb::DbDataType::DoubleType:
     185           6 :         return "double";
     186           8 :       case GenDb::DbDataType::UTF8Type:
     187           8 :         return "text";
     188           6 :       case GenDb::DbDataType::InetType:
     189           6 :         return "inet";
     190           6 :       case GenDb::DbDataType::IntegerType:
     191           6 :         return "varint";
     192           6 :       case GenDb::DbDataType::BlobType:
     193           6 :         return "blob";
     194           0 :       default:
     195           0 :         assert(false && "Invalid data type");
     196             :         return "";
     197             :     }
     198             : }
     199             : 
     200           3 : static std::string DbDataTypes2CassTypes(
     201             :     const GenDb::DbDataTypeVec &v_db_types) {
     202           3 :     assert(!v_db_types.empty());
     203           3 :     return std::string(DbDataType2CassType(v_db_types[0]));
     204             : }
     205             : 
     206      108036 : static CassConsistency Db2CassConsistency(
     207             :     GenDb::DbConsistency::type dconsistency) {
     208      108036 :     switch (dconsistency) {
     209           0 :       case GenDb::DbConsistency::ANY:
     210           0 :         return CASS_CONSISTENCY_ANY;
     211           0 :       case GenDb::DbConsistency::ONE:
     212           0 :         return CASS_CONSISTENCY_ONE;
     213           0 :       case GenDb::DbConsistency::TWO:
     214           0 :         return CASS_CONSISTENCY_TWO;
     215           0 :       case GenDb::DbConsistency::THREE:
     216           0 :         return CASS_CONSISTENCY_THREE;
     217           0 :       case GenDb::DbConsistency::QUORUM:
     218           0 :         return CASS_CONSISTENCY_QUORUM;
     219           0 :       case GenDb::DbConsistency::ALL:
     220           0 :         return CASS_CONSISTENCY_ALL;
     221           0 :       case GenDb::DbConsistency::LOCAL_QUORUM:
     222           0 :         return CASS_CONSISTENCY_LOCAL_QUORUM;
     223           0 :       case GenDb::DbConsistency::EACH_QUORUM:
     224           0 :         return CASS_CONSISTENCY_EACH_QUORUM;
     225           0 :       case GenDb::DbConsistency::SERIAL:
     226           0 :         return CASS_CONSISTENCY_SERIAL;
     227           0 :       case GenDb::DbConsistency::LOCAL_SERIAL:
     228           0 :         return CASS_CONSISTENCY_LOCAL_SERIAL;
     229      108061 :       case GenDb::DbConsistency::LOCAL_ONE:
     230      108061 :         return CASS_CONSISTENCY_LOCAL_ONE;
     231           0 :       case GenDb::DbConsistency::UNKNOWN:
     232             :       default:
     233           0 :         return CASS_CONSISTENCY_UNKNOWN;
     234             :     }
     235             : }
     236             : 
     237             : // Cass Query Printer
     238             : class CassQueryPrinter : public boost::static_visitor<> {
     239             :  public:
     240           1 :     CassQueryPrinter(std::ostream &os, bool quote_strings) :
     241           1 :         os_(os),
     242           1 :         quote_strings_(quote_strings) {
     243           1 :     }
     244      411798 :     CassQueryPrinter(std::ostream &os) :
     245      411798 :         os_(os),
     246      411798 :         quote_strings_(true) {
     247      411798 :     }
     248             :     template<typename T>
     249       10612 :     void operator()(const T &t) const {
     250       10612 :         os_ << t;
     251       10629 :     }
     252          25 :     void operator()(const boost::uuids::uuid &tuuid) const {
     253          25 :         os_ << to_string(tuuid);
     254          25 :     }
     255             :     // uint8_t must be handled specially because ostream sees
     256             :     // uint8_t as a text type instead of an integer type
     257      114844 :     void operator()(const uint8_t &tu8) const {
     258      114844 :         os_ << (uint16_t)tu8;
     259      114916 :     }
     260      113155 :     void operator()(const std::string &tstring) const {
     261      113155 :         if (quote_strings_) {
     262      113148 :             os_ << "'" << tstring << "'";
     263             :         } else {
     264           8 :             os_ << tstring;
     265             :         }
     266      113275 :     }
     267             :     // CQL int is 32 bit signed integer
     268      300154 :     void operator()(const uint32_t &tu32) const {
     269      300154 :         os_ << (int32_t)tu32;
     270      300846 :     }
     271             :     // CQL bigint is 64 bit signed long
     272          25 :     void operator()(const uint64_t &tu64) const {
     273          25 :         os_ << (int64_t)tu64;
     274          25 :     }
     275           0 :     void operator()(const IpAddress &tipaddr) const {
     276           0 :         os_ << "'" << tipaddr << "'";
     277           0 :     }
     278             :     std::ostream &os_;
     279             :     bool quote_strings_;
     280             : };
     281             : 
     282             : //
     283             : // CassStatement bind
     284             : //
     285             : class CassStatementIndexBinder : public boost::static_visitor<> {
     286             :  public:
     287           0 :     CassStatementIndexBinder(interface::CassLibrary *cci,
     288           0 :         CassStatement *statement) :
     289           0 :         cci_(cci),
     290           0 :         statement_(statement) {
     291           0 :     }
     292           0 :     void operator()(const boost::blank &tblank, size_t index) const {
     293           0 :         assert(false && "CassStatement bind to boost::blank not supported");
     294             :     }
     295           0 :     void operator()(const std::string &tstring, size_t index) const {
     296           0 :         CassError rc(cci_->CassStatementBindStringN(statement_, index,
     297             :             tstring.c_str(), tstring.length()));
     298           0 :         assert(rc == CASS_OK);
     299           0 :     }
     300           0 :     void operator()(const boost::uuids::uuid &tuuid, size_t index) const {
     301             :         CassUuid cuuid;
     302           0 :         decode_uuid((char *)&tuuid, &cuuid);
     303           0 :         CassError rc(cci_->CassStatementBindUuid(statement_, index, cuuid));
     304           0 :         assert(rc == CASS_OK);
     305           0 :     }
     306           0 :     void operator()(const uint8_t &tu8, size_t index) const {
     307           0 :         CassError rc(cci_->CassStatementBindInt32(statement_, index, tu8));
     308           0 :         assert(rc == CASS_OK);
     309           0 :     }
     310           0 :     void operator()(const uint16_t &tu16, size_t index) const {
     311           0 :         CassError rc(cci_->CassStatementBindInt32(statement_, index, tu16));
     312           0 :         assert(rc == CASS_OK);
     313           0 :     }
     314           0 :     void operator()(const uint32_t &tu32, size_t index) const {
     315           0 :         assert(tu32 <= (uint32_t)std::numeric_limits<int32_t>::max());
     316           0 :         CassError rc(cci_->CassStatementBindInt32(statement_, index,
     317           0 :             (cass_int32_t)tu32));
     318           0 :         assert(rc == CASS_OK);
     319           0 :     }
     320           0 :     void operator()(const uint64_t &tu64, size_t index) const {
     321           0 :         assert(tu64 <= (uint64_t)std::numeric_limits<int64_t>::max());
     322           0 :         CassError rc(cci_->CassStatementBindInt64(statement_, index,
     323           0 :             (cass_int64_t)tu64));
     324           0 :         assert(rc == CASS_OK);
     325           0 :     }
     326           0 :     void operator()(const double &tdouble, size_t index) const {
     327           0 :         CassError rc(cci_->CassStatementBindDouble(statement_, index,
     328             :             (cass_double_t)tdouble));
     329           0 :         assert(rc == CASS_OK);
     330           0 :     }
     331           0 :     void operator()(const IpAddress &tipaddr, size_t index) const {
     332             :         CassInet cinet;
     333           0 :         if (tipaddr.is_v4()) {
     334           0 :             boost::asio::ip::address_v4 tv4(tipaddr.to_v4());
     335           0 :             cinet = cci_->CassInetInitV4(GENERIC_RAW_ARRAY(tv4.to_bytes()));
     336             :         } else {
     337           0 :             boost::asio::ip::address_v6 tv6(tipaddr.to_v6());
     338           0 :             cinet = cci_->CassInetInitV6(GENERIC_RAW_ARRAY(tv6.to_bytes()));
     339             :         }
     340           0 :         CassError rc(cci_->CassStatementBindInet(statement_, index,
     341             :             cinet));
     342           0 :         assert(rc == CASS_OK);
     343           0 :     }
     344           0 :     void operator()(const GenDb::Blob &tblob, size_t index) const {
     345           0 :         CassError rc(cci_->CassStatementBindBytes(statement_, index,
     346             :             tblob.data(), tblob.size()));
     347           0 :         assert(rc == CASS_OK);
     348           0 :     }
     349             :     interface::CassLibrary *cci_;
     350             :     CassStatement *statement_;
     351             : };
     352             : 
     353             : class CassStatementNameBinder : public boost::static_visitor<> {
     354             :  public:
     355           0 :     CassStatementNameBinder(interface::CassLibrary *cci,
     356           0 :         CassStatement *statement) :
     357           0 :         cci_(cci),
     358           0 :         statement_(statement) {
     359           0 :     }
     360           0 :     void operator()(const boost::blank &tblank, const char *name) const {
     361           0 :         assert(false && "CassStatement bind to boost::blank not supported");
     362             :     }
     363           0 :     void operator()(const std::string &tstring, const char *name) const {
     364           0 :         CassError rc(cci_->CassStatementBindStringByNameN(statement_, name,
     365             :             strlen(name), tstring.c_str(), tstring.length()));
     366           0 :         assert(rc == CASS_OK);
     367           0 :     }
     368           0 :     void operator()(const boost::uuids::uuid &tuuid, const char *name) const {
     369             :         CassUuid cuuid;
     370           0 :         decode_uuid((char *)&tuuid, &cuuid);
     371           0 :         CassError rc(cci_->CassStatementBindUuidByName(statement_, name,
     372             :             cuuid));
     373           0 :         assert(rc == CASS_OK);
     374           0 :     }
     375           0 :     void operator()(const uint8_t &tu8, const char *name) const {
     376           0 :         CassError rc(cci_->CassStatementBindInt32ByName(statement_, name,
     377           0 :             tu8));
     378           0 :         assert(rc == CASS_OK);
     379           0 :     }
     380           0 :     void operator()(const uint16_t &tu16, const char *name) const {
     381           0 :         CassError rc(cci_->CassStatementBindInt32ByName(statement_, name,
     382           0 :             tu16));
     383           0 :         assert(rc == CASS_OK);
     384           0 :     }
     385           0 :     void operator()(const uint32_t &tu32, const char *name) const {
     386           0 :         assert(tu32 <= (uint32_t)std::numeric_limits<int32_t>::max());
     387           0 :         CassError rc(cci_->CassStatementBindInt32ByName(statement_, name,
     388           0 :             (cass_int32_t)tu32));
     389           0 :         assert(rc == CASS_OK);
     390           0 :     }
     391           0 :     void operator()(const uint64_t &tu64, const char *name) const {
     392           0 :         assert(tu64 <= (uint64_t)std::numeric_limits<int64_t>::max());
     393           0 :         CassError rc(cci_->CassStatementBindInt64ByName(statement_, name,
     394           0 :             (cass_int64_t)tu64));
     395           0 :         assert(rc == CASS_OK);
     396           0 :     }
     397           0 :     void operator()(const double &tdouble, const char *name) const {
     398           0 :         CassError rc(cci_->CassStatementBindDoubleByName(statement_, name,
     399             :             (cass_double_t)tdouble));
     400           0 :         assert(rc == CASS_OK);
     401           0 :     }
     402           0 :     void operator()(const IpAddress &tipaddr, const char *name) const {
     403             :         CassInet cinet;
     404           0 :         if (tipaddr.is_v4()) {
     405           0 :             boost::asio::ip::address_v4 tv4(tipaddr.to_v4());
     406           0 :             cinet = cci_->CassInetInitV4(GENERIC_RAW_ARRAY(tv4.to_bytes()));
     407             :         } else {
     408           0 :             boost::asio::ip::address_v6 tv6(tipaddr.to_v6());
     409           0 :             cinet = cci_->CassInetInitV6(GENERIC_RAW_ARRAY(tv6.to_bytes()));
     410             :         }
     411           0 :         CassError rc(cci_->CassStatementBindInetByName(statement_, name,
     412             :             cinet));
     413           0 :         assert(rc == CASS_OK);
     414           0 :     }
     415           0 :     void operator()(const GenDb::Blob &tblob, const char *name) const {
     416           0 :         CassError rc(cci_->CassStatementBindBytesByNameN(statement_, name,
     417             :             strlen(name), tblob.data(), tblob.size()));
     418           0 :         assert(rc == CASS_OK);
     419           0 :     }
     420             :     interface::CassLibrary *cci_;
     421             :     CassStatement *statement_;
     422             : };
     423             : 
     424             : static const char * kQCompactionStrategy(
     425             :     "compaction = {'class': "
     426             :     "'org.apache.cassandra.db.compaction.%s'}");
     427             : static const std::string kQGCGraceSeconds("gc_grace_seconds = 0");
     428             : static const std::string kQReadRepairChanceDTCS(
     429             :              "read_repair_chance = 0.0");
     430             : 
     431             : //
     432             : // Cf2CassCreateTableIfNotExists
     433             : //
     434             : 
     435           1 : std::string StaticCf2CassCreateTableIfNotExists(const GenDb::NewCf &cf,
     436             :     const std::string &compaction_strategy) {
     437           1 :     std::ostringstream query;
     438             :     // Table name
     439           1 :     query << "CREATE TABLE IF NOT EXISTS " << cf.cfname_ << " ";
     440             :     // Row key
     441           1 :     const GenDb::DbDataTypeVec &rkeys(cf.partition_keys_);
     442           1 :     assert(rkeys.size() == 1);
     443           1 :     query << "(key " << DbDataType2CassType(rkeys[0]) <<
     444           1 :         " PRIMARY KEY";
     445             :     // Columns
     446           1 :     const GenDb::NewCf::ColumnMap &cfcolumns(cf.cfcolumns_);
     447           1 :     assert(!cfcolumns.empty());
     448          25 :     BOOST_FOREACH(const GenDb::NewCf::ColumnMap::value_type &cfcolumn,
     449             :         cfcolumns) {
     450          12 :         query << ", \"" << cfcolumn.first << "\" " <<
     451          12 :             DbDataType2CassType(cfcolumn.second);
     452             :     }
     453             :     char cbuf[512];
     454           1 :     int n(snprintf(cbuf, sizeof(cbuf), kQCompactionStrategy,
     455             :        compaction_strategy.c_str()));
     456           1 :     assert(!(n < 0 || n >= (int)sizeof(cbuf)));
     457             : 
     458             :     // The compaction strategy DateTieredCompactionStrategy precludes 
     459             :     // using read repair, because of the way timestamps are checked for 
     460             :     // DTCS compaction.In this case, you must set read_repair_chance to 
     461             :     // zero. For other compaction strategies, read repair should be 
     462             :     // enabled with a read_repair_chance value of 0.2 being typical
     463           1 :     if (compaction_strategy == 
     464             :         GenDb::g_gendb_constants.DATE_TIERED_COMPACTION_STRATEGY) {
     465           0 :         query << ") WITH " << std::string(cbuf) << " AND " <<
     466           0 :             kQReadRepairChanceDTCS << " AND " << kQGCGraceSeconds;
     467             :     } else {
     468           2 :         query << ") WITH " << std::string(cbuf) << " AND " << 
     469           2 :             kQGCGraceSeconds;
     470             :     }
     471             : 
     472           2 :     return query.str();
     473           1 : }
     474             : 
     475           4 : std::string DynamicCf2CassCreateTableIfNotExists(const GenDb::NewCf &cf,
     476             :     const std::string &compaction_strategy,
     477             :     boost::system::error_code *ec) {
     478           4 :     std::ostringstream query;
     479             : 
     480           4 :     *ec = errc::make_error_code(errc::success);
     481             :     // sanity check - # of clustering_columns cannot be 0
     482             :     // for dynamic tables
     483           4 :     if (cf.clustering_columns_.size() == 0) {
     484           1 :         *ec = errc::make_error_code(errc::invalid_argument);
     485           1 :         return query.str();
     486             :     }
     487             : 
     488             :     // Table name
     489           3 :     query << "CREATE TABLE IF NOT EXISTS " << cf.cfname_ << " (";
     490             :     // Row key
     491           3 :     const GenDb::DbDataTypeVec &rkeys(cf.partition_keys_);
     492           3 :     int rk_size(rkeys.size());
     493          28 :     for (int i = 0; i < rk_size; i++) {
     494          25 :         if (i) {
     495          22 :             int key_num(i + 1);
     496          22 :             query << "key" << key_num;
     497             :         } else {
     498           3 :             query << "key";
     499             :         }
     500          25 :         query << " " << DbDataType2CassType(rkeys[i]) << ", ";
     501             :     }
     502             :     // clustering columns
     503           3 :     const GenDb::DbDataTypeVec &clustering_columns(cf.clustering_columns_);
     504           3 :     int ccn_size(clustering_columns.size());
     505          28 :     for (int i = 0; i < ccn_size; i++) {
     506          25 :         int cnum(i + 1);
     507          25 :         query << "column" << cnum << " " <<
     508          25 :             DbDataType2CassType(clustering_columns[i]) << ", ";
     509             :     }
     510             :     // columns
     511           3 :     const GenDb::DbDataTypeVec &columns(cf.columns_);
     512           3 :     int cn_size(columns.size());
     513          15 :     for (int i = 0; i < cn_size; i++) {
     514          12 :         int cnum(i + 1 + ccn_size);
     515          12 :         query << "column" << cnum << " " <<
     516          12 :             DbDataType2CassType(columns[i]) << ", ";
     517             :     }
     518             :     // Value
     519           3 :     const GenDb::DbDataTypeVec &values(cf.value_);
     520           3 :     if (values.size() > 0) {
     521           3 :         query << "value" << " " << DbDataTypes2CassTypes(values) << ", ";
     522             :     }
     523             :     // Primary Key
     524           3 :     query << "PRIMARY KEY (";
     525           3 :     std::ostringstream rkey_ss;
     526          28 :     for (int i = 0; i < rk_size; i++) {
     527          25 :         if (i) {
     528          22 :             int key_num(i + 1);
     529          22 :             rkey_ss << ", key" << key_num;
     530             :         } else {
     531           3 :             rkey_ss << "key";
     532             :         }
     533             :     }
     534           3 :     if (rk_size >= 2) {
     535           2 :         query << "(" << rkey_ss.str() << "), ";
     536             :     } else {
     537           1 :         query << rkey_ss.str() << ", ";
     538             :     }
     539          28 :     for (int i = 0; i < ccn_size; i++) {
     540          25 :         int cnum(i + 1);
     541          25 :         if (i) {
     542          22 :             query << ", ";
     543             :         }
     544          25 :         query << "column" << cnum;
     545             :     }
     546             :     char cbuf[512];
     547           3 :     int n(snprintf(cbuf, sizeof(cbuf), kQCompactionStrategy,
     548             :        compaction_strategy.c_str()));
     549           3 :     assert(!(n < 0 || n >= (int)sizeof(cbuf)));
     550             : 
     551             :     // The compaction strategy DateTieredCompactionStrategy precludes
     552             :     // using read repair, because of the way timestamps are checked for
     553             :     // DTCS compaction.In this case, you must set read_repair_chance to
     554             :     // zero. For other compaction strategies, read repair should be
     555             :     // enabled with a read_repair_chance value of 0.2 being typical
     556           3 :     if (compaction_strategy == 
     557             :         GenDb::g_gendb_constants.DATE_TIERED_COMPACTION_STRATEGY) {
     558           4 :         query << ")) WITH " << std::string(cbuf) << " AND " <<
     559           4 :             kQReadRepairChanceDTCS << " AND " << kQGCGraceSeconds;
     560             :     } else {
     561           2 :         query << ")) WITH " << std::string(cbuf) << " AND " <<
     562           2 :             kQGCGraceSeconds;
     563             :     }
     564           3 :     return query.str();
     565           4 : }
     566             : 
     567           1 : static std::string DbColIndexMode2String(
     568             :     const GenDb::ColIndexMode::type index_mode) {
     569           1 :     switch (index_mode) {
     570           0 :         case GenDb::ColIndexMode::NONE:
     571           0 :             return "";
     572           1 :         case GenDb::ColIndexMode::PREFIX:
     573           1 :             return "PREFIX";
     574           0 :         case GenDb::ColIndexMode::CONTAINS:
     575           0 :             return "CONTAINS";
     576           0 :         default:
     577           0 :             assert(false && "INVALID");
     578             :     }
     579             : }
     580             : 
     581             : //
     582             : // CassCreateIndexIfNotExists
     583             : //
     584             : 
     585           2 : std::string CassCreateIndexIfNotExists(const std::string &cfname,
     586             :     const std::string &column, const std::string &indexname,
     587             :     const GenDb::ColIndexMode::type index_mode) {
     588           2 :     std::ostringstream query;
     589             : 
     590           2 :     query << "CREATE ";
     591           2 :     if (index_mode != GenDb::ColIndexMode::NONE) {
     592           1 :         query << "CUSTOM "; // SASI
     593             :     }
     594             :     // Indexname
     595           2 :     query << "INDEX IF NOT EXISTS " << indexname << " ";
     596             :     // Index Column
     597           2 :     query << "ON " << cfname << "(\""<< column <<"\")";
     598             :     // Mode if SASI
     599           2 :     if (index_mode != GenDb::ColIndexMode::NONE) {
     600             :         query << " USING \'org.apache.cassandra.index.sasi.SASIIndex\' " <<
     601           1 :         "WITH OPTIONS = {\'mode\': \'" << DbColIndexMode2String(index_mode) << "\'}";
     602             :     }
     603           2 :     query << ";";
     604           4 :     return query.str();
     605           2 : }
     606             : 
     607             : //
     608             : // Cf2CassInsertIntoTable
     609             : //
     610             : 
     611           1 : std::string StaticCf2CassInsertIntoTable(const GenDb::ColList *v_columns) {
     612           1 :     std::ostringstream query;
     613             :     // Table
     614           1 :     const std::string &table(v_columns->cfname_);
     615           1 :     query << "INSERT INTO " << table << " (";
     616           1 :     std::ostringstream values_ss;
     617           1 :     values_ss << "VALUES (";
     618           1 :     CassQueryPrinter values_printer(values_ss);
     619             :     // Row keys
     620           1 :     const GenDb::DbDataValueVec &rkeys(v_columns->rowkey_);
     621           1 :     int rk_size(rkeys.size());
     622           9 :     for (int i = 0; i < rk_size; i++) {
     623           8 :         if (i) {
     624           7 :             int key_num(i + 1);
     625           7 :             query << ", key" << key_num;
     626             :         } else {
     627           1 :             query << "key";
     628             :         }
     629           8 :         if (i) {
     630           7 :             values_ss << ", ";
     631             :         }
     632           8 :         boost::apply_visitor(values_printer, rkeys[i]);
     633             :     }
     634             :     // Columns
     635           1 :     int cttl(-1);
     636           1 :     CassQueryPrinter cnames_printer(query, false);
     637          17 :     BOOST_FOREACH(const GenDb::NewCol &column, v_columns->columns_) {
     638           8 :         assert(column.cftype_ == GenDb::NewCf::COLUMN_FAMILY_SQL);
     639             :         // Column Name
     640           8 :         query << ", ";
     641           8 :         const GenDb::DbDataValueVec &cnames(*column.name.get());
     642           8 :         assert(cnames.size() == 1);
     643             :         // Double quote column name strings
     644           8 :         query << "\"";
     645           8 :         boost::apply_visitor(cnames_printer, cnames[0]);
     646           8 :         query << "\"";
     647             :         // Column Values
     648           8 :         values_ss << ", ";
     649           8 :         const GenDb::DbDataValueVec &cvalues(*column.value.get());
     650           8 :         assert(cvalues.size() == 1);
     651           8 :         boost::apply_visitor(values_printer, cvalues[0]);
     652             :         // Column TTL
     653           8 :         cttl = column.ttl;
     654             :     }
     655           1 :     query << ") ";
     656           1 :     values_ss << ")";
     657           1 :     query << values_ss.str();
     658           1 :     if (cttl > 0) {
     659           1 :         query << " USING TTL " << cttl;
     660             :     }
     661           2 :     return query.str();
     662           1 : }
     663             : 
     664           1 : std::string DynamicCf2CassInsertIntoTable(const GenDb::ColList *v_columns) {
     665           1 :     std::ostringstream query;
     666             :     // Table
     667           1 :     const std::string &table(v_columns->cfname_);
     668           1 :     query << "INSERT INTO " << table << " (";
     669           1 :     std::ostringstream values_ss;
     670             :     // Row keys
     671           1 :     const GenDb::DbDataValueVec &rkeys(v_columns->rowkey_);
     672           1 :     int rk_size(rkeys.size());
     673           1 :     CassQueryPrinter values_printer(values_ss);
     674           9 :     for (int i = 0; i < rk_size; i++) {
     675           8 :         if (i) {
     676           7 :             int key_num(i + 1);
     677           7 :             query << ", key" << key_num;
     678             :         } else {
     679           1 :             query << "key";
     680             :         }
     681           8 :         boost::apply_visitor(values_printer, rkeys[i]);
     682           8 :         values_ss << ", ";
     683             :     }
     684             :     // Columns
     685           1 :     const GenDb::NewColVec &columns(v_columns->columns_);
     686           1 :     assert(columns.size() == 1);
     687           1 :     const GenDb::NewCol &column(columns[0]);
     688           1 :     assert(column.cftype_ == GenDb::NewCf::COLUMN_FAMILY_NOSQL);
     689             :     // Column Names
     690           1 :     const GenDb::DbDataValueVec &cnames(*column.name.get());
     691           1 :     int cn_size(cnames.size());
     692           9 :     for (int i = 0; i < cn_size; i++) {
     693           8 :         int cnum(i + 1);
     694           8 :         if (cnames.at(i).which() != GenDb::DB_VALUE_BLANK) {
     695           8 :             query << ", column" << cnum;
     696           8 :             boost::apply_visitor(values_printer, cnames[i]);
     697           8 :             if (i != cn_size - 1) {
     698           7 :                 values_ss << ", ";
     699             :             }
     700             :         }
     701             :     }
     702             :     // Column Values
     703           1 :     const GenDb::DbDataValueVec &cvalues(*column.value.get());
     704           1 :     if (cvalues.size() > 0) {
     705           1 :         query << ", value) VALUES (";
     706           1 :         values_ss << ", ";
     707           1 :         boost::apply_visitor(values_printer, cvalues[0]);
     708             :     } else {
     709           0 :         query << ") VALUES (";
     710             :     }
     711           1 :     values_ss << ")";
     712           1 :     query << values_ss.str();
     713           1 :     if (column.ttl > 0) {
     714           1 :         query << " USING TTL " << column.ttl;
     715             :     }
     716           2 :     return query.str();
     717           1 : }
     718             : 
     719             : //
     720             : // Cf2CassPrepareInsertIntoTable
     721             : //
     722             : 
     723           1 : std::string StaticCf2CassPrepareInsertIntoTable(const GenDb::NewCf &cf) {
     724           1 :    std::ostringstream query;
     725             :     // Table name
     726           1 :     query << "INSERT INTO " << cf.cfname_ << " ";
     727             :     // Row key
     728           1 :     const GenDb::DbDataTypeVec &rkeys(cf.partition_keys_);
     729           1 :     assert(rkeys.size() == 1);
     730           1 :     std::ostringstream values_ss;
     731           1 :     query << "(key";
     732           1 :     values_ss << ") VALUES (?";
     733             :     // Columns
     734           1 :     const GenDb::NewCf::ColumnMap &cfcolumns(cf.cfcolumns_);
     735           1 :     assert(!cfcolumns.empty());
     736          25 :     BOOST_FOREACH(const GenDb::NewCf::ColumnMap::value_type &cfcolumn,
     737             :         cfcolumns) {
     738          12 :         query << ", \"" << cfcolumn.first << "\"";
     739          12 :         values_ss << ", ?";
     740             :     }
     741           1 :     query << values_ss.str();
     742           1 :     query << ") USING TTL ?";
     743           2 :     return query.str();
     744           1 : }
     745             : 
     746           3 : std::string DynamicCf2CassPrepareInsertIntoTable(const GenDb::NewCf &cf, 
     747             :                                                  boost::system::error_code *ec) {
     748           3 :     std::ostringstream query;
     749             : 
     750           3 :     *ec = errc::make_error_code(errc::success);
     751             :     // sanity check - # of clustering_columns cannot be 0
     752             :     // for dynamic tables
     753           3 :     if (cf.clustering_columns_.size() == 0) {
     754           1 :         *ec = errc::make_error_code(errc::invalid_argument);
     755           1 :         return query.str();
     756             :     }
     757             : 
     758             :     // Table name
     759           2 :     query << "INSERT INTO " << cf.cfname_ << " (";
     760             :     // Row key
     761           2 :     const GenDb::DbDataTypeVec &rkeys(cf.partition_keys_);
     762           2 :     int rk_size(rkeys.size());
     763           2 :     std::ostringstream values_ss;
     764          26 :     for (int i = 0; i < rk_size; i++) {
     765          24 :         if (i) {
     766          22 :             int key_num(i + 1);
     767          22 :             query << "key" << key_num;
     768             :         } else {
     769           2 :             query << "key";
     770             :         }
     771          24 :         query << ", ";
     772          24 :         values_ss << "?, ";
     773             :     }
     774             :     // Clustering Column name
     775           2 :     const GenDb::DbDataTypeVec &clustering_columns(cf.clustering_columns_);
     776           2 :     int ccn_size(clustering_columns.size());
     777          26 :     for (int i = 0; i < ccn_size; i++) {
     778          24 :         int cnum(i + 1);
     779          24 :         query << "column" << cnum;
     780          24 :         values_ss << "?";
     781          24 :         if (i != ccn_size - 1) {
     782          22 :             query << ", ";
     783          22 :             values_ss << ", ";
     784             :         }
     785             :     }
     786             :     // Column name
     787           2 :     const GenDb::DbDataTypeVec &columns(cf.columns_);
     788           2 :     int cn_size(columns.size());
     789           2 :     if (cn_size > 0) {
     790           1 :         query << ", ";
     791           1 :         values_ss << ", ";
     792             :     }
     793          14 :     for (int i = 0; i < cn_size; i++) {
     794          12 :         int cnum(i + 1 + ccn_size);
     795          12 :         query << "column" << cnum;
     796          12 :         values_ss << "?";
     797          12 :         if (i != cn_size - 1) {
     798          11 :             query << ", ";
     799          11 :             values_ss << ", ";
     800             :         }
     801             :     }
     802             :     // Value
     803           2 :     const GenDb::DbDataTypeVec &values(cf.value_);
     804           2 :     if (values.size() > 0) {
     805           2 :         query << ", value";
     806           2 :         values_ss << ", ?";
     807             :     }
     808           2 :     query << ") VALUES (";
     809           2 :     values_ss << ")";
     810           2 :     query << values_ss.str();
     811           2 :     query << " USING TTL ?";
     812           2 :     return query.str();
     813           3 : }
     814             : 
     815             : //
     816             : // Cf2CassPrepareBind
     817             : //
     818             : 
     819           0 : bool StaticCf2CassPrepareBind(interface::CassLibrary *cci,
     820             :     CassStatement *statement,
     821             :     const GenDb::ColList *v_columns) {
     822           0 :     CassStatementNameBinder values_binder(cci, statement);
     823             :     // Row keys
     824           0 :     const GenDb::DbDataValueVec &rkeys(v_columns->rowkey_);
     825           0 :     int rk_size(rkeys.size());
     826           0 :     size_t idx(0);
     827           0 :     for (; (int) idx < rk_size; idx++) {
     828           0 :         std::string rk_name;
     829           0 :         if (idx) {
     830           0 :             int key_num(idx + 1);
     831           0 :             rk_name = "key" + integerToString(key_num);
     832             :         } else {
     833           0 :             rk_name = "key";
     834             :         }
     835           0 :         boost::apply_visitor(boost::bind(values_binder, _1, rk_name.c_str()),
     836           0 :             rkeys[idx]);
     837           0 :     }
     838             :     // Columns
     839           0 :     int cttl(-1);
     840           0 :     BOOST_FOREACH(const GenDb::NewCol &column, v_columns->columns_) {
     841           0 :         assert(column.cftype_ == GenDb::NewCf::COLUMN_FAMILY_SQL);
     842           0 :         const GenDb::DbDataValueVec &cnames(*column.name.get());
     843           0 :         assert(cnames.size() == 1);
     844           0 :         assert(cnames[0].which() == GenDb::DB_VALUE_STRING);
     845           0 :         std::string cname(boost::get<std::string>(cnames[0]));
     846           0 :         const GenDb::DbDataValueVec &cvalues(*column.value.get());
     847           0 :         assert(cvalues.size() == 1);
     848           0 :         boost::apply_visitor(boost::bind(values_binder, _1, cname.c_str()),
     849           0 :             cvalues[0]);
     850             :         // Column TTL
     851           0 :         cttl = column.ttl;
     852           0 :         idx++;
     853           0 :     }
     854           0 :     CassError rc(cci->CassStatementBindInt32(statement, idx++,
     855             :         (cass_int32_t)cttl));
     856           0 :     assert(rc == CASS_OK);
     857           0 :     return true;
     858             : }
     859             : 
     860           0 : bool DynamicCf2CassPrepareBind(interface::CassLibrary *cci,
     861             :     CassStatement *statement,
     862             :     const GenDb::ColList *v_columns) {
     863           0 :     CassStatementIndexBinder values_binder(cci, statement);
     864             :     // Row keys
     865           0 :     const GenDb::DbDataValueVec &rkeys(v_columns->rowkey_);
     866           0 :     int rk_size(rkeys.size());
     867           0 :     size_t idx(0);
     868           0 :     for (; (int) idx < rk_size; idx++) {
     869           0 :         boost::apply_visitor(boost::bind(values_binder, _1, idx), rkeys[idx]);
     870             :     }
     871             :     // Columns
     872           0 :     const GenDb::NewColVec &columns(v_columns->columns_);
     873           0 :     assert(columns.size() == 1);
     874           0 :     const GenDb::NewCol &column(columns[0]);
     875           0 :     assert(column.cftype_ == GenDb::NewCf::COLUMN_FAMILY_NOSQL);
     876             :     // Column Names
     877           0 :     const GenDb::DbDataValueVec &cnames(*column.name.get());
     878           0 :     int cn_size(cnames.size());
     879           0 :     for (int i = 0; i < cn_size; i++, idx++) {
     880           0 :         boost::apply_visitor(boost::bind(values_binder, _1, idx), cnames[i]);
     881             :     }
     882             :     // Column Values
     883           0 :     const GenDb::DbDataValueVec &cvalues(*column.value.get());
     884           0 :     if (cvalues.size() > 0) {
     885           0 :         boost::apply_visitor(boost::bind(values_binder, _1, idx++),
     886           0 :             cvalues[0]);
     887             :     }
     888           0 :     CassError rc(cci->CassStatementBindInt32(statement, idx++,
     889           0 :         (cass_int32_t)column.ttl));
     890           0 :     assert(rc == CASS_OK);
     891           0 :     return true;
     892             : }
     893             : 
     894      108416 : static std::string CassSelectFromTableInternal(const std::string &table,
     895             :     const std::vector<GenDb::DbDataValueVec> &rkeys,
     896             :     const GenDb::ColumnNameRange &ck_range,
     897             :     const GenDb::FieldNamesToReadVec &read_vec,
     898             :     const GenDb::WhereIndexInfoVec &where_vec) {
     899      108416 :     std::ostringstream query;
     900             :     // Table
     901      108736 :     if (read_vec.empty()) {
     902      108676 :         query << "SELECT * FROM " << table;
     903             :     } else {
     904           8 :         query << "SELECT ";
     905           8 :         for (GenDb::FieldNamesToReadVec::const_iterator it = read_vec.begin();
     906          28 :              it != read_vec.end(); it++) {
     907          20 :             query << it->get<0>() << ",";
     908          20 :             bool read_timestamp = it->get<3>();
     909          20 :             if (read_timestamp) {
     910           4 :                 query << "WRITETIME(" << it->get<0>() << "),";
     911             :             }
     912             :         }
     913           8 :         query.seekp(-1, query.cur);
     914           8 :         query << " FROM " << table;
     915             :     }
     916      108664 :     if (rkeys.size() == 1) {
     917      108698 :         GenDb::DbDataValueVec rkey = rkeys[0];
     918      108318 :         int rk_size(rkey.size());
     919      108314 :         CassQueryPrinter cprinter(query);
     920      335473 :         for (int i = 0; i < rk_size; i++) {
     921      226794 :             if (i) {
     922      118486 :                 int key_num(i + 1);
     923      118486 :                 query << " AND key" << key_num << "=";
     924             :             } else {
     925      108308 :                 query << " WHERE key=";
     926             :             }
     927      226986 :             boost::apply_visitor(cprinter, rkey[i]);
     928             :         }
     929             : 
     930      108674 :     } else if (rkeys.size() > 1) {
     931           5 :         query << " WHERE key IN (";
     932          45 :         BOOST_FOREACH(GenDb::DbDataValueVec rkey, rkeys) {
     933          20 :             int rk_size(rkey.size());
     934          20 :             assert(rk_size == 1);
     935          20 :             CassQueryPrinter cprinter(query);
     936          20 :             boost::apply_visitor(cprinter, rkey[0]);
     937          20 :             query << ",";
     938          20 :         }
     939           5 :         query.seekp(-1, query.cur);
     940           5 :         query << ")";
     941             :     }
     942      108423 :     if (!where_vec.empty()) {
     943      102138 :         for (GenDb::WhereIndexInfoVec::const_iterator it = where_vec.begin();
     944      208911 :             it != where_vec.end(); ++it) {
     945      106470 :             std::ostringstream value_ss;
     946      106798 :             CassQueryPrinter value_vprinter(value_ss);
     947      106802 :             boost::apply_visitor(value_vprinter, it->get<2>());
     948      106786 :             query << " AND";
     949      106785 :             query << " " << it->get<0>();
     950      106762 :             query << " " << GenDb::Op::ToString(it->get<1>());
     951      106724 :             query << " " << value_ss.str();
     952      106797 :         }
     953             :     }
     954      108447 :     if (!ck_range.IsEmpty()) {
     955      108023 :         if (!ck_range.start_.empty()) {
     956       88690 :             int ck_start_size(ck_range.start_.size());
     957       88690 :             std::ostringstream start_ss;
     958       88885 :             start_ss << " " << GenDb::Op::ToString(ck_range.start_op_) << " (";
     959       88871 :             CassQueryPrinter start_vprinter(start_ss);
     960       88868 :             query << " AND (";
     961      178179 :             for (int i = 0; i < ck_start_size; i++) {
     962       89282 :                 if (i) {
     963         426 :                     query << ", ";
     964         426 :                     start_ss << ", ";
     965             :                 }
     966       89282 :                 int cnum(i + 1);
     967       89282 :                 query << "column" << cnum;
     968       89300 :                 boost::apply_visitor(start_vprinter, ck_range.start_[i]);
     969             :             }
     970       88897 :             query << ")";
     971       88885 :             start_ss << ")";
     972       88881 :             query << start_ss.str();
     973       88873 :         }
     974      108126 :         if (!ck_range.finish_.empty()) {
     975      108081 :             int ck_finish_size(ck_range.finish_.size());
     976      108078 :             std::ostringstream finish_ss;
     977      108169 :             finish_ss << " " << GenDb::Op::ToString(ck_range.finish_op_) <<
     978      108157 :                 " (";
     979      108167 :             CassQueryPrinter finish_vprinter(finish_ss);
     980      108159 :             query << " AND (";
     981      224596 :             for (int i = 0; i < ck_finish_size; i++) {
     982      116407 :                 if (i) {
     983        8261 :                     query << ", ";
     984        8261 :                     finish_ss << ", ";
     985             :                 }
     986      116407 :                 int cnum(i + 1);
     987      116407 :                 query << "column" << cnum;
     988      116435 :                 boost::apply_visitor(finish_vprinter, ck_range.finish_[i]);
     989             :             }
     990      108189 :             query << ")";
     991      108183 :             finish_ss << ")";
     992      108191 :             query << finish_ss.str();
     993      108173 :         }
     994      108173 :         if (ck_range.count_) {
     995      108177 :             query << " LIMIT " << ck_range.count_;
     996             :         }
     997             :     }
     998      108661 :     if (where_vec.size() > 1) {
     999        4341 :         query << " ALLOW FILTERING";
    1000             :     }
    1001      217293 :     return query.str();
    1002      108585 : }
    1003             : 
    1004      107616 : std::string ClusteringKeyRangeAndIndexValue2CassSelectFromTable(
    1005             :     const std::string &table, const GenDb::DbDataValueVec &rkeys,
    1006             :     const GenDb::ColumnNameRange &ck_range,
    1007             :     const GenDb::WhereIndexInfoVec &where_vec,
    1008             :     const GenDb::FieldNamesToReadVec &read_vec) {
    1009      107616 :     std::vector<GenDb::DbDataValueVec> rkey_vec;
    1010      108125 :     rkey_vec.push_back(rkeys);
    1011             :     return CassSelectFromTableInternal(table, rkey_vec, ck_range,
    1012      215840 :         read_vec, where_vec);
    1013      108068 : }
    1014             : 
    1015         526 : std::string PartitionKey2CassSelectFromTable(const std::string &table,
    1016             :     const GenDb::DbDataValueVec &rkeys) {
    1017         526 :     std::vector<GenDb::DbDataValueVec> rkey_vec;
    1018         526 :     rkey_vec.push_back(rkeys);
    1019        1052 :     return CassSelectFromTableInternal(table, rkey_vec, GenDb::ColumnNameRange(),
    1020        1052 :                                        GenDb::FieldNamesToReadVec(),
    1021        2104 :                                        GenDb::WhereIndexInfoVec());
    1022         526 : }
    1023             : 
    1024          11 : std::string PartitionKeyAndClusteringKeyRange2CassSelectFromTable(
    1025             :     const std::string &table, const GenDb::DbDataValueVec &rkeys,
    1026             :     const GenDb::ColumnNameRange &ck_range,
    1027             :     const GenDb::FieldNamesToReadVec &read_vec) {
    1028          11 :     std::vector<GenDb::DbDataValueVec> rkey_vec;
    1029          11 :     rkey_vec.push_back(rkeys);
    1030             :     return CassSelectFromTableInternal(table, rkey_vec, ck_range, read_vec,
    1031          33 :         GenDb::WhereIndexInfoVec());
    1032          11 : }
    1033             : 
    1034           5 : std::string PartitionKeyAndClusteringKeyRange2CassSelectFromTable(
    1035             :     const std::string &table, const std::vector<GenDb::DbDataValueVec> &rkeys,
    1036             :     const GenDb::ColumnNameRange &ck_range,
    1037             :     const GenDb::FieldNamesToReadVec &read_vec) {
    1038             :     return CassSelectFromTableInternal(table, rkeys, ck_range, read_vec,
    1039          10 :         GenDb::WhereIndexInfoVec());
    1040             : }
    1041             : 
    1042           1 : std::string CassSelectFromTable(const std::string &table) {
    1043           1 :     std::vector<GenDb::DbDataValueVec> rkey_vec;
    1044             :     return CassSelectFromTableInternal(table, rkey_vec,
    1045           2 :         GenDb::ColumnNameRange(), GenDb::FieldNamesToReadVec(),
    1046           4 :         GenDb::WhereIndexInfoVec());
    1047           1 : }
    1048             : 
    1049       96333 : static GenDb::DbDataValue CassValue2DbDataValue(
    1050             :     interface::CassLibrary *cci, const CassValue *cvalue) {
    1051       96333 :     if (cci->CassValueIsNull(cvalue)) {
    1052       28661 :         return GenDb::DbDataValue();
    1053             :     }
    1054       67700 :     CassValueType cvtype(cci->GetCassValueType(cvalue));
    1055       67712 :     switch (cvtype) {
    1056       41511 :       case CASS_VALUE_TYPE_ASCII:
    1057             :       case CASS_VALUE_TYPE_VARCHAR:
    1058             :       case CASS_VALUE_TYPE_TEXT: {
    1059       41511 :         CassString ctstring;
    1060       41540 :         CassError rc(cci->CassValueGetString(cvalue, &ctstring.data,
    1061             :             &ctstring.length));
    1062       41540 :         assert(rc == CASS_OK);
    1063       83077 :         return std::string(ctstring.data, ctstring.length);
    1064             :       }
    1065        4571 :       case CASS_VALUE_TYPE_UUID: {
    1066             :         CassUuid ctuuid;
    1067        4571 :         CassError rc(cci->CassValueGetUuid(cvalue, &ctuuid));
    1068        4571 :         assert(rc == CASS_OK);
    1069             :         boost::uuids::uuid u;
    1070        4571 :         encode_uuid((char *)&u, ctuuid);
    1071        4571 :         return u;
    1072             :       }
    1073           0 :       case CASS_VALUE_TYPE_DOUBLE: {
    1074             :         cass_double_t ctdouble;
    1075           0 :         CassError rc(cci->CassValueGetDouble(cvalue, &ctdouble));
    1076           0 :         assert(rc == CASS_OK);
    1077           0 :         return (double)ctdouble;
    1078             :       }
    1079           0 :       case CASS_VALUE_TYPE_TINY_INT: {
    1080             :         cass_int8_t ct8;
    1081           0 :         CassError rc(cci->CassValueGetInt8(cvalue, &ct8));
    1082           0 :         assert(rc == CASS_OK);
    1083           0 :         return (uint8_t)ct8;
    1084             :       }
    1085           0 :       case CASS_VALUE_TYPE_SMALL_INT: {
    1086             :         cass_int16_t ct16;
    1087           0 :         CassError rc(cci->CassValueGetInt16(cvalue, &ct16));
    1088           0 :         assert(rc == CASS_OK);
    1089           0 :         return (uint16_t)ct16;
    1090             :       }
    1091       17736 :       case CASS_VALUE_TYPE_INT: {
    1092             :         cass_int32_t ct32;
    1093       17736 :         CassError rc(cci->CassValueGetInt32(cvalue, &ct32));
    1094       17736 :         assert(rc == CASS_OK);
    1095       35471 :         return (uint32_t)ct32;
    1096             :       }
    1097        3463 :       case CASS_VALUE_TYPE_BIGINT: {
    1098             :         cass_int64_t ct64;
    1099        3463 :         CassError rc(cci->CassValueGetInt64(cvalue, &ct64));
    1100        3463 :         assert(rc == CASS_OK);
    1101        6926 :         return (uint64_t)ct64;
    1102             :       }
    1103         408 :       case CASS_VALUE_TYPE_INET: {
    1104             :         CassInet ctinet;
    1105         408 :         CassError rc(cci->CassValueGetInet(cvalue, &ctinet));
    1106         408 :         assert(rc == CASS_OK);
    1107         408 :         IpAddress ipaddr;
    1108         408 :         if (ctinet.address_length == CASS_INET_V4_LENGTH) {
    1109             :             Ip4Address::bytes_type ipv4;
    1110         408 :             memcpy(GENERIC_RAW_ARRAY(ipv4), ctinet.address, CASS_INET_V4_LENGTH);
    1111         408 :             ipaddr = Ip4Address(ipv4);
    1112           0 :         } else if (ctinet.address_length == CASS_INET_V6_LENGTH) {
    1113             :             Ip6Address::bytes_type ipv6;
    1114           0 :             memcpy(GENERIC_RAW_ARRAY(ipv6), ctinet.address, CASS_INET_V6_LENGTH);
    1115           0 :             ipaddr = Ip6Address(ipv6);
    1116             :         } else {
    1117           0 :             assert(0);
    1118             :         }
    1119         408 :         return ipaddr;
    1120             :       }
    1121           0 :       case CASS_VALUE_TYPE_BLOB: {
    1122           0 :         const cass_byte_t *bytes(NULL);
    1123           0 :         size_t size(0);
    1124           0 :         CassError rc(cci->CassValueGetBytes(cvalue, &bytes, &size));
    1125           0 :         assert(rc == CASS_OK);
    1126           0 :         return GenDb::Blob(bytes, size);
    1127             :       }
    1128           0 :       case CASS_VALUE_TYPE_UNKNOWN: {
    1129             :         // null type
    1130           0 :         return GenDb::DbDataValue();
    1131             :       }
    1132          23 :       default: {
    1133          23 :         CQLIF_ERR_TRACE("Unhandled CassValueType: " << cvtype);
    1134           0 :         assert(false && "Unhandled value type");
    1135             :         return GenDb::DbDataValue();
    1136             :       }
    1137             :     }
    1138             : }
    1139             : 
    1140           0 : static bool PrepareSync(interface::CassLibrary *cci,
    1141             :     CassSession *session, const char* query,
    1142             :     CassPreparedPtr *prepared) {
    1143           0 :     CQLIF_DEBUG_TRACE( "PrepareSync: " << query);
    1144           0 :     CassFuturePtr future(cci->CassSessionPrepare(session, query), cci);
    1145           0 :     cci->CassFutureWait(future.get());
    1146             : 
    1147           0 :     CassError rc(cci->CassFutureErrorCode(future.get()));
    1148           0 :     if (rc != CASS_OK) {
    1149           0 :         CassString err;
    1150           0 :         cci->CassFutureErrorMessage(future.get(), &err.data, &err.length);
    1151           0 :         CQLIF_ERR_TRACE("PrepareSync: " << query << " FAILED: " <<
    1152             :             std::string(err.data, err.length));
    1153             :     } else {
    1154           0 :         *prepared = CassPreparedPtr(cci->CassFutureGetPrepared(future.get()),
    1155           0 :             cci);
    1156             :     }
    1157           0 :     return rc == CASS_OK;
    1158           0 : }
    1159             : 
    1160         550 : static bool ExecuteQuerySyncInternal(interface::CassLibrary *cci,
    1161             :     CassSession *session,
    1162             :     CassStatement *qstatement, CassResultPtr *result,
    1163             :     CassConsistency consistency) {
    1164         550 :     cci->CassStatementSetConsistency(qstatement, consistency);
    1165         550 :     CassFuturePtr future(cci->CassSessionExecute(session, qstatement), cci);
    1166         550 :     cci->CassFutureWait(future.get());
    1167             : 
    1168         550 :     CassError rc(cci->CassFutureErrorCode(future.get()));
    1169         550 :     if (rc != CASS_OK) {
    1170           0 :         CassString err;
    1171           0 :         cci->CassFutureErrorMessage(future.get(), &err.data, &err.length);
    1172           0 :         CQLIF_ERR_TRACE("SyncQuery: FAILED: " <<
    1173             :             std::string(err.data, err.length));
    1174             :     } else {
    1175         550 :         if (result) {
    1176        1050 :             *result = CassResultPtr(cci->CassFutureGetResult(future.get()),
    1177         525 :                 cci);
    1178             :         }
    1179             :     }
    1180         550 :     return rc == CASS_OK;
    1181         550 : }
    1182             : 
    1183          25 : static bool ExecuteQuerySync(interface::CassLibrary *cci,
    1184             :     CassSession *session, const char *query, CassConsistency consistency) {
    1185          25 :     CQLIF_DEBUG_TRACE( "SyncQuery: " << query);
    1186          25 :     CassStatementPtr statement(cci->CassStatementNew(query, 0), cci);
    1187          25 :     return ExecuteQuerySyncInternal(cci, session, statement.get(), NULL,
    1188          50 :         consistency);
    1189          25 : }
    1190             : 
    1191         525 : static bool ExecuteQueryResultSync(interface::CassLibrary *cci,
    1192             :     CassSession *session, const char *query,
    1193             :     CassResultPtr *result, CassConsistency consistency) {
    1194         525 :     CQLIF_DEBUG_TRACE( "SyncQuery: " << query);
    1195         525 :     CassStatementPtr statement(cci->CassStatementNew(query, 0), cci);
    1196         525 :     return ExecuteQuerySyncInternal(cci, session, statement.get(), result,
    1197        1050 :         consistency);
    1198         525 : }
    1199             : 
    1200           0 : static bool ExecuteQueryStatementSync(interface::CassLibrary *cci,
    1201             :     CassSession *session, CassStatement *statement,
    1202             :     CassConsistency consistency) {
    1203           0 :     return ExecuteQuerySyncInternal(cci, session, statement, NULL,
    1204           0 :         consistency);
    1205             : }
    1206             : 
    1207      108184 : static GenDb::DbOpResult::type CassError2DbOpResult(CassError rc) {
    1208      108184 :     switch (rc) {
    1209      108188 :       case CASS_OK:
    1210      108188 :         return GenDb::DbOpResult::OK;
    1211           0 :       case CASS_ERROR_LIB_NO_HOSTS_AVAILABLE:
    1212             :       case CASS_ERROR_LIB_REQUEST_QUEUE_FULL:
    1213             :       case CASS_ERROR_LIB_NO_AVAILABLE_IO_THREAD:
    1214           0 :         return GenDb::DbOpResult::BACK_PRESSURE;
    1215           0 :       default:
    1216           0 :         return GenDb::DbOpResult::ERROR;
    1217             :     }
    1218             : }
    1219             : 
    1220           0 : static void DynamicCfGetResult(interface::CassLibrary *cci,
    1221             :     CassResultPtr *result, const GenDb::FieldNamesToReadVec &read_vec,
    1222             :     GenDb::NewColVec *v_columns) {
    1223             :     // Row iterator
    1224           0 :     CassIteratorPtr riterator(cci->CassIteratorFromResult(result->get()), cci);
    1225           0 :     while (cci->CassIteratorNext(riterator.get())) {
    1226           0 :         const CassRow *row(cci->CassIteratorGetRow(riterator.get()));
    1227           0 :         GenDb::DbDataValueVec *cnames(new GenDb::DbDataValueVec);
    1228           0 :         GenDb::DbDataValueVec *values(new GenDb::DbDataValueVec);
    1229           0 :         GenDb::DbDataValueVec *timestamps(new GenDb::DbDataValueVec);
    1230           0 :         int i = 0;
    1231           0 :         for (GenDb::FieldNamesToReadVec::const_iterator it = read_vec.begin();
    1232           0 :              it != read_vec.end(); it++) {
    1233           0 :             bool row_key = it->get<1>();
    1234           0 :             bool row_column = it->get<2>();
    1235           0 :             bool read_timestamp = it->get<3>();
    1236           0 :             if (row_key) {
    1237           0 :                 i++;
    1238           0 :                 continue;
    1239             :             }
    1240           0 :             const CassValue *cvalue(cci->CassRowGetColumn(row, i));
    1241           0 :             assert(cvalue);
    1242           0 :             GenDb::DbDataValue db_value(CassValue2DbDataValue(cci, cvalue));
    1243           0 :             if (row_column) {
    1244           0 :                 cnames->push_back(db_value);
    1245             :             } else {
    1246           0 :                 values->push_back(db_value);
    1247           0 :                 if (read_timestamp) {
    1248           0 :                     i++;
    1249           0 :                     const CassValue *ctimestamp(cci->CassRowGetColumn(row, i));
    1250           0 :                     assert(ctimestamp);
    1251           0 :                     GenDb::DbDataValue time_value(CassValue2DbDataValue(cci, ctimestamp));
    1252           0 :                     timestamps->push_back(time_value);
    1253           0 :                 }
    1254             :             }
    1255           0 :             i++;
    1256           0 :         }
    1257           0 :         GenDb::NewCol *column(new GenDb::NewCol(cnames, values, 0, timestamps));
    1258           0 :         v_columns->push_back(column);
    1259             :     }
    1260           0 : }
    1261             : 
    1262           0 : static void DynamicCfGetResult(interface::CassLibrary *cci,
    1263             :     CassResultPtr *result, const GenDb::FieldNamesToReadVec &read_vec,
    1264             :     GenDb::ColListVec *v_col_list) {
    1265           0 :     std::auto_ptr<GenDb::ColList> col_list;
    1266             :     // Row iterator
    1267           0 :     CassIteratorPtr riterator(cci->CassIteratorFromResult(result->get()), cci);
    1268           0 :     while (cci->CassIteratorNext(riterator.get())) {
    1269           0 :         const CassRow *row(cci->CassIteratorGetRow(riterator.get()));
    1270           0 :         GenDb::DbDataValueVec rkey;
    1271           0 :         GenDb::DbDataValueVec *cnames(new GenDb::DbDataValueVec);
    1272           0 :         GenDb::DbDataValueVec *values(new GenDb::DbDataValueVec);
    1273           0 :         GenDb::DbDataValueVec *timestamps(new GenDb::DbDataValueVec);
    1274           0 :         int i = 0;
    1275           0 :         for (GenDb::FieldNamesToReadVec::const_iterator it = read_vec.begin();
    1276           0 :              it != read_vec.end(); it++) {
    1277           0 :             bool row_key = it->get<1>();
    1278           0 :             bool row_column = it->get<2>();
    1279           0 :             bool read_timestamp = it->get<3>();
    1280           0 :             if (row_key) {
    1281             :                 // Partiiton key
    1282           0 :                 const CassValue *cvalue(cci->CassRowGetColumn(row, i));
    1283           0 :                 assert(cvalue);
    1284           0 :                 GenDb::DbDataValue db_value(CassValue2DbDataValue(cci, cvalue));
    1285           0 :                 rkey.push_back(db_value);
    1286           0 :                 i++;
    1287           0 :                 continue;
    1288           0 :             }
    1289           0 :             const CassValue *cvalue(cci->CassRowGetColumn(row, i));
    1290           0 :             assert(cvalue);
    1291           0 :             GenDb::DbDataValue db_value(CassValue2DbDataValue(cci, cvalue));
    1292           0 :             if (row_column) {
    1293           0 :                 cnames->push_back(db_value);
    1294             :             } else {
    1295           0 :                 values->push_back(db_value);
    1296           0 :                 if (read_timestamp) {
    1297           0 :                     i++;
    1298           0 :                     const CassValue *ctimestamp(cci->CassRowGetColumn(row, i));
    1299           0 :                     assert(ctimestamp);
    1300           0 :                     GenDb::DbDataValue time_value(CassValue2DbDataValue(cci, ctimestamp));
    1301           0 :                     timestamps->push_back(time_value);
    1302           0 :                 }
    1303             :             }
    1304           0 :             i++;
    1305           0 :         }
    1306           0 :         GenDb::NewCol *column(new GenDb::NewCol(cnames, values, 0, timestamps));
    1307             :         // Do we need a new ColList?
    1308           0 :         if (!col_list.get()) {
    1309           0 :             col_list.reset(new GenDb::ColList);
    1310           0 :             col_list->rowkey_ = rkey;
    1311             :         }
    1312           0 :         if (rkey != col_list->rowkey_) {
    1313           0 :             v_col_list->push_back(col_list.release());
    1314           0 :             col_list.reset(new GenDb::ColList);
    1315           0 :             col_list->rowkey_ = rkey;
    1316             :         }
    1317           0 :         GenDb::NewColVec *v_columns(&col_list->columns_);
    1318           0 :         v_columns->push_back(column);
    1319           0 :     }
    1320           0 :     if (col_list.get()) {
    1321           0 :         v_col_list->push_back(col_list.release());
    1322             :     }
    1323           0 : }
    1324             : 
    1325      108625 : static void DynamicCfGetResult(interface::CassLibrary *cci,
    1326             :     CassResultPtr *result, size_t rk_count,
    1327             :     size_t ck_count, GenDb::NewColVec *v_columns) {
    1328             :     // Row iterator
    1329      108625 :     CassIteratorPtr riterator(cci->CassIteratorFromResult(result->get()), cci);
    1330      113395 :     while (cci->CassIteratorNext(riterator.get())) {
    1331        4734 :         const CassRow *row(cci->CassIteratorGetRow(riterator.get()));
    1332             :         // Iterate over columns
    1333        4734 :         size_t ccount(cci->CassResultColumnCount(result->get()));
    1334             :         // Clustering key
    1335        4734 :         GenDb::DbDataValueVec *cnames(new GenDb::DbDataValueVec);
    1336       14955 :         for (size_t i = rk_count; i < rk_count + ck_count; i++) {
    1337       10221 :             const CassValue *cvalue(cci->CassRowGetColumn(row, i));
    1338       10221 :             assert(cvalue);
    1339       10221 :             GenDb::DbDataValue db_value(CassValue2DbDataValue(cci, cvalue));
    1340       10222 :             cnames->push_back(db_value);
    1341       10222 :         }
    1342             :         // Values
    1343        4734 :         GenDb::DbDataValueVec *values(new GenDb::DbDataValueVec);
    1344       90628 :         for (size_t i = rk_count + ck_count; i < ccount; i++) {
    1345       85893 :             const CassValue *cvalue(cci->CassRowGetColumn(row, i));
    1346       85897 :             assert(cvalue);
    1347       85897 :             GenDb::DbDataValue db_value(CassValue2DbDataValue(cci, cvalue));
    1348       85898 :             values->push_back(db_value);
    1349       85899 :         }
    1350        4735 :         GenDb::NewCol *column(new GenDb::NewCol(cnames, values, 0));
    1351        4734 :         v_columns->push_back(column);
    1352             :     }
    1353      108663 : }
    1354             : 
    1355           1 : void DynamicCfGetResult(interface::CassLibrary *cci,
    1356             :     CassResultPtr *result, size_t rk_count,
    1357             :     size_t ck_count, GenDb::ColListVec *v_col_list) {
    1358           1 :     std::auto_ptr<GenDb::ColList> col_list;
    1359             :     // Row iterator
    1360           1 :     CassIteratorPtr riterator(cci->CassIteratorFromResult(result->get()), cci);
    1361           4 :     while (cci->CassIteratorNext(riterator.get())) {
    1362           3 :         const CassRow *row(cci->CassIteratorGetRow(riterator.get()));
    1363             :         // Iterate over columns
    1364           3 :         size_t ccount(cci->CassResultColumnCount(result->get()));
    1365             :         // Partiiton key
    1366           3 :         GenDb::DbDataValueVec rkey;
    1367           6 :         for (size_t i = 0; i < rk_count; i++) {
    1368           3 :             const CassValue *cvalue(cci->CassRowGetColumn(row, i));
    1369           3 :             assert(cvalue);
    1370           3 :             GenDb::DbDataValue db_value(CassValue2DbDataValue(cci, cvalue));
    1371           3 :             rkey.push_back(db_value);
    1372           3 :         }
    1373             :         // Clustering key
    1374           3 :         GenDb::DbDataValueVec *cnames(new GenDb::DbDataValueVec);
    1375           6 :         for (size_t i = rk_count; i < rk_count + ck_count; i++) {
    1376           3 :             const CassValue *cvalue(cci->CassRowGetColumn(row, i));
    1377           3 :             assert(cvalue);
    1378           3 :             GenDb::DbDataValue db_value(CassValue2DbDataValue(cci, cvalue));
    1379           3 :             cnames->push_back(db_value);
    1380           3 :         }
    1381             :         // Values
    1382           3 :         GenDb::DbDataValueVec *values(new GenDb::DbDataValueVec);
    1383           6 :         for (size_t i = rk_count + ck_count; i < ccount; i++) {
    1384           3 :             const CassValue *cvalue(cci->CassRowGetColumn(row, i));
    1385           3 :             assert(cvalue);
    1386           3 :             GenDb::DbDataValue db_value(CassValue2DbDataValue(cci, cvalue));
    1387           3 :             values->push_back(db_value);
    1388           3 :         }
    1389           3 :         GenDb::NewCol *column(new GenDb::NewCol(cnames, values, 0));
    1390             :         // Do we need a new ColList?
    1391           3 :         if (!col_list.get()) {
    1392           1 :             col_list.reset(new GenDb::ColList);
    1393           1 :             col_list->rowkey_ = rkey;
    1394             :         }
    1395           3 :         if (rkey != col_list->rowkey_) {
    1396           1 :             v_col_list->push_back(col_list.release());
    1397           1 :             col_list.reset(new GenDb::ColList);
    1398           1 :             col_list->rowkey_ = rkey;
    1399             :         }
    1400           3 :         GenDb::NewColVec *v_columns(&col_list->columns_);
    1401           3 :         v_columns->push_back(column);
    1402           3 :     }
    1403           1 :     if (col_list.get()) {
    1404           1 :         v_col_list->push_back(col_list.release());
    1405             :     }
    1406           1 : }
    1407             : 
    1408          25 : static void StaticCfGetResult(interface::CassLibrary *cci,
    1409             :     CassResultPtr *result, GenDb::NewColVec *v_columns) {
    1410             :     // Row iterator
    1411          25 :     CassIteratorPtr riterator(cci->CassIteratorFromResult(result->get()), cci);
    1412          50 :     while (cci->CassIteratorNext(riterator.get())) {
    1413          25 :         const CassRow *row(cci->CassIteratorGetRow(riterator.get()));
    1414             :         // Iterate over columns
    1415          25 :         size_t ccount(cci->CassResultColumnCount(result->get()));
    1416         250 :         for (size_t i = 0; i < ccount; i++) {
    1417         225 :             CassString cname;
    1418         225 :             CassError rc(cci->CassResultColumnName(result->get(), i,
    1419             :                 &cname.data, &cname.length));
    1420         225 :             assert(rc == CASS_OK);
    1421         225 :             const CassValue *cvalue(cci->CassRowGetColumn(row, i));
    1422         225 :             assert(cvalue);
    1423         225 :             GenDb::DbDataValue db_value(CassValue2DbDataValue(cci, cvalue));
    1424         225 :             if (db_value.which() == GenDb::DB_VALUE_BLANK) {
    1425           0 :                 continue;
    1426             :             }
    1427             :             GenDb::NewCol *column(new GenDb::NewCol(
    1428         225 :                 std::string(cname.data, cname.length), db_value, 0));
    1429         225 :             v_columns->push_back(column);
    1430         225 :         }
    1431             :     }
    1432          25 : }
    1433             : 
    1434           1 : void StaticCfGetResult(interface::CassLibrary *cci,
    1435             :     CassResultPtr *result, size_t rk_count, GenDb::ColListVec *v_col_list) {
    1436           1 :     std::auto_ptr<GenDb::ColList> col_list;
    1437             :     // Row iterator
    1438           1 :     CassIteratorPtr riterator(cci->CassIteratorFromResult(result->get()), cci);
    1439           4 :     while (cci->CassIteratorNext(riterator.get())) {
    1440           3 :         const CassRow *row(cci->CassIteratorGetRow(riterator.get()));
    1441             :         // Iterate over columns
    1442           3 :         size_t ccount(cci->CassResultColumnCount(result->get()));
    1443             :         // Partiiton key
    1444           3 :         GenDb::DbDataValueVec rkey;
    1445           6 :         for (size_t i = 0; i < rk_count; i++) {
    1446           3 :             const CassValue *cvalue(cci->CassRowGetColumn(row, i));
    1447           3 :             assert(cvalue);
    1448           3 :             GenDb::DbDataValue db_value(CassValue2DbDataValue(cci, cvalue));
    1449           3 :             rkey.push_back(db_value);
    1450           3 :         }
    1451             :         // Do we need a new ColList?
    1452           3 :         if (!col_list.get()) {
    1453           1 :             col_list.reset(new GenDb::ColList);
    1454           1 :             col_list->rowkey_ = rkey;
    1455             :         }
    1456           3 :         if (rkey != col_list->rowkey_) {
    1457           2 :             v_col_list->push_back(col_list.release());
    1458           2 :             col_list.reset(new GenDb::ColList);
    1459           2 :             col_list->rowkey_ = rkey;
    1460             :         }
    1461           3 :         GenDb::NewColVec *v_columns(&col_list->columns_);
    1462          12 :         for (size_t i = 0; i < ccount; i++) {
    1463           9 :             CassString cname;
    1464           9 :             CassError rc(cci->CassResultColumnName(result->get(), i,
    1465             :                 &cname.data, &cname.length));
    1466           9 :             assert(rc == CASS_OK);
    1467           9 :             const CassValue *cvalue(cci->CassRowGetColumn(row, i));
    1468           9 :             assert(cvalue);
    1469           9 :             GenDb::DbDataValue db_value(CassValue2DbDataValue(cci, cvalue));
    1470           9 :             if (db_value.which() == GenDb::DB_VALUE_BLANK) {
    1471           0 :                 continue;
    1472             :             }
    1473             :             GenDb::NewCol *column(new GenDb::NewCol(
    1474           9 :                 std::string(cname.data, cname.length), db_value, 0));
    1475           9 :             v_columns->push_back(column);
    1476           9 :         }
    1477           3 :     }
    1478           1 :     if (col_list.get()) {
    1479           1 :         v_col_list->push_back(col_list.release());
    1480             :     }
    1481           1 : }
    1482             : 
    1483      108183 : static void OnExecuteQueryAsync(CassFuture *future, void *data) {
    1484      108183 :     assert(data);
    1485             :     std::auto_ptr<CassAsyncQueryContext> ctx(
    1486      108183 :         boost::reinterpret_pointer_cast<CassAsyncQueryContext>(data));
    1487      108187 :     interface::CassLibrary *cci(ctx->cci_);
    1488      108187 :     CassError rc(cci->CassFutureErrorCode(future));
    1489      108190 :     GenDb::DbOpResult::type db_rc(CassError2DbOpResult(rc));
    1490      108187 :     if (rc != CASS_OK) {
    1491           0 :         CassString err;
    1492           0 :         cci->CassFutureErrorMessage(future, &err.data, &err.length);
    1493           0 :         CQLIF_ERR_TRACE("AsyncQuery: " << ctx->query_id_ << " FAILED: "
    1494             :             << std::string(err.data, err.length));
    1495           0 :         ctx->cb_(db_rc, std::auto_ptr<GenDb::ColList>());
    1496           0 :         return;
    1497             :     }
    1498      108187 :     if (ctx->result_ctx_) {
    1499      108184 :         CassQueryResultContext *rctx(ctx->result_ctx_.get());
    1500      108184 :         CassResultPtr result(cci->CassFutureGetResult(future), cci);
    1501             :         // In case of select parse the results
    1502      108178 :         if (cci->CassResultColumnCount(result.get())) {
    1503      108179 :             std::auto_ptr<GenDb::ColList> col_list(new GenDb::ColList);
    1504      108173 :             col_list->cfname_ = rctx->cf_name_;
    1505      108174 :             col_list->rowkey_ = rctx->row_key_;
    1506      108137 :             if (rctx->is_dynamic_cf_) {
    1507      108136 :                 DynamicCfGetResult(cci, &result, rctx->rk_count_,
    1508      108137 :                     rctx->ck_count_, &col_list->columns_);
    1509             :             } else {
    1510           0 :                 StaticCfGetResult(cci, &result, &col_list->columns_);
    1511             :             }
    1512      108173 :             ctx->cb_(db_rc, col_list);
    1513      108187 :             return;
    1514      108187 :        }
    1515      108187 :     }
    1516           0 :     ctx->cb_(db_rc, std::auto_ptr<GenDb::ColList>());
    1517      108191 : }
    1518             : 
    1519      107938 : static void ExecuteQueryAsyncInternal(interface::CassLibrary *cci,
    1520             :     CassSession *session, const char *qid, CassStatement *qstatement,
    1521             :     CassConsistency consistency, CassAsyncQueryCallback cb,
    1522             :     CassQueryResultContext *rctx = NULL) {
    1523      107938 :     CQLIF_DEBUG_TRACE( "AsyncQuery: " << qid);
    1524      108188 :     cci->CassStatementSetConsistency(qstatement, consistency);
    1525      108173 :     CassFuturePtr future(cci->CassSessionExecute(session, qstatement), cci);
    1526             :     std::auto_ptr<CassAsyncQueryContext> ctx(
    1527      108136 :         new CassAsyncQueryContext(qid, cb, cci, rctx));
    1528      108009 :     cci->CassFutureSetCallback(future.get(), OnExecuteQueryAsync,
    1529      108011 :         ctx.release());
    1530      108180 : }
    1531             : 
    1532           0 : static void ExecuteQueryAsync(interface::CassLibrary *cci,
    1533             :     CassSession *session, const char *query,
    1534             :     CassConsistency consistency, CassAsyncQueryCallback cb) {
    1535           0 :     CQLIF_DEBUG_TRACE( "AsyncQuery: " << query);
    1536           0 :     CassStatementPtr statement(cci->CassStatementNew(query, 0), cci);
    1537           0 :     ExecuteQueryAsyncInternal(cci, session, query, statement.get(),
    1538             :         consistency, cb);
    1539           0 : }
    1540             : 
    1541           0 : static void ExecuteQueryStatementAsync(interface::CassLibrary *cci,
    1542             :     CassSession *session, const char *query_id, CassStatement *qstatement,
    1543             :     CassConsistency consistency, CassAsyncQueryCallback cb) {
    1544           0 :     ExecuteQueryAsyncInternal(cci, session, query_id, qstatement, consistency,
    1545             :         cb);
    1546           0 : }
    1547             : 
    1548      107692 : static void ExecuteQueryResultAsync(interface::CassLibrary *cci,
    1549             :     CassSession *session, const char *query, CassConsistency consistency,
    1550             :     CassAsyncQueryCallback cb, CassQueryResultContext *rctx) {
    1551      107692 :     CassStatementPtr statement(cci->CassStatementNew(query, 0), cci);
    1552      108125 :     ExecuteQueryAsyncInternal(cci, session, query, statement.get(),
    1553             :         consistency, cb, rctx);
    1554      107918 : }
    1555             : 
    1556      108031 : static bool DynamicCfGetResultAsync(interface::CassLibrary *cci,
    1557             :     CassSession *session, const char *query, CassConsistency consistency,
    1558             :     impl::CassAsyncQueryCallback cb, size_t rk_count, size_t ck_count,
    1559             :     const std::string &cfname, const GenDb::DbDataValueVec &row_key) {
    1560             :     std::auto_ptr<CassQueryResultContext> rctx(
    1561             :         new CassQueryResultContext(cfname, true, row_key,
    1562      108031 :             rk_count, ck_count));
    1563      107857 :     ExecuteQueryResultAsync(cci, session, query, consistency, cb,
    1564             :         rctx.release());
    1565      108049 :     return true;
    1566      108028 : }
    1567             : 
    1568           0 : static bool DynamicCfGetResultSync(interface::CassLibrary *cci,
    1569             :     CassSession *session, const char *query,
    1570             :     const GenDb::FieldNamesToReadVec &read_vec,
    1571             :     CassConsistency consistency, GenDb::NewColVec *v_columns) {
    1572           0 :     CassResultPtr result(NULL, cci);
    1573           0 :     bool success(ExecuteQueryResultSync(cci, session, query, &result,
    1574             :         consistency));
    1575           0 :     if (!success) {
    1576           0 :         return success;
    1577             :     }
    1578           0 :     DynamicCfGetResult(cci, &result, read_vec, v_columns);
    1579           0 :     return success;
    1580           0 : }
    1581             : 
    1582           0 : static bool DynamicCfGetResultSync(interface::CassLibrary *cci,
    1583             :     CassSession *session, const char *query,
    1584             :     const GenDb::FieldNamesToReadVec &read_vec,
    1585             :     CassConsistency consistency, GenDb::ColListVec *v_columns) {
    1586           0 :     CassResultPtr result(NULL, cci);
    1587           0 :     bool success(ExecuteQueryResultSync(cci, session, query, &result,
    1588             :         consistency));
    1589           0 :     if (!success) {
    1590           0 :         return success;
    1591             :     }
    1592           0 :     DynamicCfGetResult(cci, &result, read_vec, v_columns);
    1593           0 :     return success;
    1594           0 : }
    1595             : 
    1596         500 : static bool DynamicCfGetResultSync(interface::CassLibrary *cci,
    1597             :     CassSession *session, const char *query,
    1598             :     size_t rk_count, size_t ck_count, CassConsistency consistency,
    1599             :     GenDb::NewColVec *v_columns) {
    1600         500 :     CassResultPtr result(NULL, cci);
    1601         500 :     bool success(ExecuteQueryResultSync(cci, session, query, &result,
    1602             :         consistency));
    1603         500 :     if (!success) {
    1604           0 :         return success;
    1605             :     }
    1606         500 :     DynamicCfGetResult(cci, &result, rk_count, ck_count, v_columns);
    1607         500 :     return success;
    1608         500 : }
    1609             : 
    1610           0 : static bool DynamicCfGetResultSync(interface::CassLibrary *cci,
    1611             :     CassSession *session, const char *query,
    1612             :     size_t rk_count, size_t ck_count, CassConsistency consistency,
    1613             :     GenDb::ColListVec *v_col_list) {
    1614           0 :     CassResultPtr result(NULL, cci);
    1615           0 :     bool success(ExecuteQueryResultSync(cci, session, query, &result,
    1616             :         consistency));
    1617           0 :     if (!success) {
    1618           0 :         return success;
    1619             :     }
    1620           0 :     DynamicCfGetResult(cci, &result, rk_count, ck_count, v_col_list);
    1621           0 :     return success;
    1622           0 : }
    1623             : 
    1624           0 : static bool StaticCfGetResultAsync(interface::CassLibrary *cci,
    1625             :     CassSession *session, const char *query,
    1626             :     CassConsistency consistency, impl::CassAsyncQueryCallback cb,
    1627             :     const std::string& cfname, const GenDb::DbDataValueVec &row_key) {
    1628             :     std::auto_ptr<CassQueryResultContext> rctx(
    1629           0 :         new CassQueryResultContext(cfname, false, row_key));
    1630           0 :     ExecuteQueryResultAsync(cci, session, query, consistency, cb,
    1631             :         rctx.release());
    1632           0 :     return true;
    1633           0 : }
    1634             : 
    1635          25 : static bool StaticCfGetResultSync(interface::CassLibrary *cci,
    1636             :     CassSession *session, const char *query,
    1637             :     CassConsistency consistency, GenDb::NewColVec *v_columns) {
    1638          25 :     CassResultPtr result(NULL, cci);
    1639          25 :     bool success(ExecuteQueryResultSync(cci, session, query, &result,
    1640             :         consistency));
    1641          25 :     if (!success) {
    1642           0 :         return success;
    1643             :     }
    1644          25 :     StaticCfGetResult(cci, &result, v_columns);
    1645          25 :     return success;
    1646          25 : }
    1647             : 
    1648           0 : static bool StaticCfGetResultSync(interface::CassLibrary *cci,
    1649             :     CassSession *session, const char *query, size_t rk_count,
    1650             :     CassConsistency consistency, GenDb::ColListVec *v_col_list) {
    1651           0 :     CassResultPtr result(NULL, cci);
    1652           0 :     bool success(ExecuteQueryResultSync(cci, session, query, &result,
    1653             :         consistency));
    1654           0 :     if (!success) {
    1655           0 :         return success;
    1656             :     }
    1657           0 :     StaticCfGetResult(cci, &result, rk_count, v_col_list);
    1658           0 :     return success;
    1659           0 : }
    1660             : 
    1661          50 : static bool SyncFutureWait(interface::CassLibrary *cci,
    1662             :     CassFuture *future) {
    1663          50 :     cci->CassFutureWait(future);
    1664          50 :     CassError rc(cci->CassFutureErrorCode(future));
    1665          50 :     if (rc != CASS_OK) {
    1666           0 :         CassString err;
    1667           0 :         cci->CassFutureErrorMessage(future, &err.data, &err.length);
    1668           0 :         CQLIF_ERR_TRACE("SyncWait: FAILED: " <<
    1669             :             std::string(err.data, err.length));
    1670             :     }
    1671          50 :     return rc == CASS_OK;
    1672             : }
    1673             : 
    1674      326090 : static const CassTableMeta * GetCassTableMeta(
    1675             :     interface::CassLibrary *cci, const CassSchemaMeta *schema_meta,
    1676             :     const std::string &keyspace, const std::string &table, bool log_error) {
    1677             :     const CassKeyspaceMeta *keyspace_meta(
    1678      326090 :         cci->CassSchemaMetaKeyspaceByName(schema_meta, keyspace.c_str()));
    1679      326116 :     if (keyspace_meta == NULL) {
    1680           0 :         if (log_error) {
    1681           0 :             CQLIF_ERR_TRACE("No keyspace schema: Keyspace: " << keyspace <<
    1682             :                 ", Table: " << table);
    1683             :         }
    1684           0 :         return NULL;
    1685             :     }
    1686      326116 :     std::string table_lower(table);
    1687      326218 :     boost::algorithm::to_lower(table_lower);
    1688             :     const CassTableMeta *table_meta(
    1689      326149 :         cci->CassKeyspaceMetaTableByName(keyspace_meta, table_lower.c_str()));
    1690      326719 :     if (table_meta == NULL) {
    1691          25 :         if (log_error) {
    1692           0 :             CQLIF_ERR_TRACE("No table schema: Keyspace: " << keyspace <<
    1693             :                 ", Table: " << table_lower);
    1694             :         }
    1695          25 :         return NULL;
    1696             :     }
    1697      326694 :     return table_meta;
    1698      326719 : }
    1699             : 
    1700         150 : static bool IsCassTableMetaPresent(interface::CassLibrary *cci,
    1701             :     CassSession *session,
    1702             :     const std::string &keyspace, const std::string &table) {
    1703         150 :     impl::CassSchemaMetaPtr schema_meta(cci->CassSessionGetSchemaMeta(
    1704         150 :         session), cci);
    1705         150 :     if (schema_meta.get() == NULL) {
    1706           0 :         CQLIF_DEBUG_TRACE( "No schema meta: Keyspace: " << keyspace <<
    1707             :             ", Table: " << table);
    1708           0 :         return false;
    1709             :     }
    1710         150 :     bool log_error(false);
    1711         150 :     const CassTableMeta *table_meta(impl::GetCassTableMeta(cci,
    1712             :         schema_meta.get(), keyspace, table, log_error));
    1713         150 :     if (table_meta == NULL) {
    1714          25 :         return false;
    1715             :     }
    1716         125 :     return true;
    1717         150 : }
    1718             : 
    1719      217424 : static bool GetCassTableClusteringKeyCount(
    1720             :     interface::CassLibrary *cci,
    1721             :     CassSession *session, const std::string &keyspace,
    1722             :     const std::string &table, size_t *ck_count) {
    1723      217424 :     impl::CassSchemaMetaPtr schema_meta(cci->CassSessionGetSchemaMeta(
    1724      217424 :         session), cci);
    1725      217712 :     if (schema_meta.get() == NULL) {
    1726           0 :         CQLIF_ERR_TRACE("No schema meta: Keyspace: " << keyspace <<
    1727             :             ", Table: " << table);
    1728           0 :         return false;
    1729             :     }
    1730      217797 :     bool log_error(true);
    1731      217797 :     const CassTableMeta *table_meta(impl::GetCassTableMeta(cci,
    1732             :         schema_meta.get(), keyspace, table, log_error));
    1733      217854 :     if (table_meta == NULL) {
    1734           0 :         return false;
    1735             :     }
    1736      217854 :     *ck_count = cci->CassTableMetaClusteringKeyCount(table_meta);
    1737      217825 :     return true;
    1738      217825 : }
    1739             : 
    1740      108415 : static bool GetCassTablePartitionKeyCount(
    1741             :     interface::CassLibrary *cci, CassSession *session,
    1742             :     const std::string &keyspace, const std::string &table, size_t *rk_count) {
    1743      108415 :     impl::CassSchemaMetaPtr schema_meta(cci->CassSessionGetSchemaMeta(
    1744      108415 :         session), cci);
    1745      108659 :     if (schema_meta.get() == NULL) {
    1746           0 :         CQLIF_ERR_TRACE("No schema meta: Keyspace: " << keyspace <<
    1747             :             ", Table: " << table);
    1748           0 :         return false;
    1749             :     }
    1750      108656 :     bool log_error(true);
    1751      108656 :     const CassTableMeta *table_meta(impl::GetCassTableMeta(cci,
    1752             :         schema_meta.get(), keyspace, table, log_error));
    1753      108679 :     if (table_meta == NULL) {
    1754           0 :         return false;
    1755             :     }
    1756      108679 :     *rk_count = cci->CassTableMetaPartitionKeyCount(table_meta);
    1757      108673 :     return true;
    1758      108673 : }
    1759             : 
    1760        3255 : static log4cplus::LogLevel Cass2log4Level(CassLogLevel clevel) {
    1761        3255 :     switch (clevel) {
    1762           0 :       case CASS_LOG_DISABLED:
    1763           0 :         return log4cplus::OFF_LOG_LEVEL;
    1764           0 :       case CASS_LOG_CRITICAL:
    1765           0 :         return log4cplus::FATAL_LOG_LEVEL;
    1766          25 :       case CASS_LOG_ERROR:
    1767          25 :         return log4cplus::ERROR_LOG_LEVEL;
    1768           0 :       case CASS_LOG_WARN:
    1769           0 :         return log4cplus::WARN_LOG_LEVEL;
    1770         175 :       case CASS_LOG_INFO:
    1771         175 :         return log4cplus::INFO_LOG_LEVEL;
    1772        3055 :       case CASS_LOG_DEBUG:
    1773        3055 :         return log4cplus::DEBUG_LOG_LEVEL;
    1774           0 :       case CASS_LOG_TRACE:
    1775           0 :         return log4cplus::TRACE_LOG_LEVEL;
    1776           0 :       default:
    1777           0 :         return log4cplus::ALL_LOG_LEVEL;
    1778             :     }
    1779             : }
    1780             : 
    1781        3703 : static CassLogLevel Log4Level2CassLogLevel(log4cplus::LogLevel level) {
    1782        3703 :     switch (level) {
    1783           0 :       case log4cplus::OFF_LOG_LEVEL:
    1784           0 :         return CASS_LOG_DISABLED;
    1785           0 :       case log4cplus::FATAL_LOG_LEVEL:
    1786           0 :         return CASS_LOG_CRITICAL;
    1787           0 :       case log4cplus::ERROR_LOG_LEVEL:
    1788           0 :         return CASS_LOG_ERROR;
    1789           0 :       case log4cplus::WARN_LOG_LEVEL:
    1790           0 :         return CASS_LOG_WARN;
    1791           0 :       case log4cplus::INFO_LOG_LEVEL:
    1792           0 :         return CASS_LOG_INFO;
    1793        3699 :       case log4cplus::DEBUG_LOG_LEVEL:
    1794        3699 :         return CASS_LOG_DEBUG;
    1795           4 :       case log4cplus::TRACE_LOG_LEVEL:
    1796           4 :         return CASS_LOG_TRACE;
    1797           0 :       default:
    1798           0 :         assert(false && "Invalid Log4Level");
    1799             :         return CASS_LOG_DISABLED;
    1800             :     }
    1801             : }
    1802             : 
    1803        3255 : static void CassLibraryLog(const CassLogMessage* message, void *data) {
    1804        3255 :     if (LoggingDisabled()) {
    1805           0 :         return;
    1806             :     }
    1807        3255 :     log4cplus::LogLevel log4level(Cass2log4Level(message->severity));
    1808        3255 :     std::stringstream buf;
    1809        3255 :     buf << "CassLibrary: " << message->file << ":" << message->line <<
    1810        3255 :             " " << message->function << "] " << message->message;
    1811        3255 :     CASS_LIB_TRACE(log4level, buf.str());
    1812        3255 : }
    1813             : 
    1814           0 : static std::string LoadCertFile(const std::string &ca_certs_path) {
    1815           0 :     if (ca_certs_path.length() == 0) {
    1816           0 :         return std::string();
    1817             :     }
    1818           0 :     std::ifstream file(ca_certs_path.c_str());
    1819           0 :     if (!file) {
    1820           0 :         return std::string();
    1821             :     }
    1822             :     std::string content((std::istreambuf_iterator<char>(file)),
    1823           0 :                         std::istreambuf_iterator<char>());
    1824           0 :     return content;
    1825           0 : }
    1826             : 
    1827             : 
    1828             : class WorkerTask : public Task {
    1829             :  public:
    1830             :     typedef boost::function<void(void)> FunctionPtr;
    1831           0 :     WorkerTask(FunctionPtr func, int task_id, int task_instance) :
    1832             :         Task(task_id, task_instance),
    1833           0 :         func_(func) {
    1834           0 :     }
    1835           0 :     bool Run() {
    1836           0 :         func_();
    1837           0 :         return true;
    1838             :     }
    1839           0 :     std::string Description() const {
    1840           0 :         return "cass::cql::impl::WorkerTask";
    1841             :     }
    1842             :  private:
    1843             :     FunctionPtr func_;
    1844             : };
    1845             : 
    1846             : }  // namespace impl
    1847             : 
    1848             : //
    1849             : // CqlIfImpl
    1850             : //
    1851        3703 : CqlIfImpl::CqlIfImpl(EventManager *evm,
    1852             :                      const std::vector<std::string> &cassandra_ips,
    1853             :                      int cassandra_port,
    1854             :                      const std::string &cassandra_user,
    1855             :                      const std::string &cassandra_password,
    1856             :                      bool use_ssl,
    1857             :                      const std::string &ca_certs_path,
    1858        3703 :                      interface::CassLibrary *cci) :
    1859        3703 :     evm_(evm),
    1860        3703 :     cci_(cci),
    1861        3703 :     cluster_(cci_->CassClusterNew(), cci_),
    1862        3703 :     ssl_(0, cci_),
    1863        3703 :     session_(cci_->CassSessionNew(), cci_),
    1864        3703 :     schema_session_(cci_->CassSessionNew(), cci_),
    1865        3703 :     keyspace_(),
    1866       11109 :     io_thread_count_(2) {
    1867             :     // Set session state to INIT
    1868        3703 :     session_state_ = SessionState::INIT;
    1869        3703 :     schema_session_state_ = SessionState::INIT;
    1870             :     
    1871        3703 :     if (cassandra_ips.size() > 0) {
    1872          26 :         schema_contact_point_ = cassandra_ips[0];
    1873          26 :         boost::system::error_code ec;
    1874          26 :         boost::asio::ip::address::from_string(cassandra_ips[0], ec);
    1875          26 :         if(ec.value() != 0){
    1876          50 :             schema_contact_point_ = GetHostIp(
    1877          50 :                          evm->io_service(), cassandra_ips[0]);
    1878             :         }
    1879             :     }
    1880             : 
    1881        3703 :     if (use_ssl) {
    1882           0 :         ssl_ = impl::CassSslPtr(cci->CassSslNew(), cci_);
    1883             :         /* Only verify the certification and not the identity */
    1884           0 :         cci_->CassSslSetVerifyFlags(ssl_.get(), CASS_SSL_VERIFY_PEER_CERT);
    1885           0 :         std::string content = impl::LoadCertFile(ca_certs_path);
    1886           0 :         if (content.length() == 0) {
    1887           0 :             cci_->CassSslSetVerifyFlags(ssl_.get(), CASS_SSL_VERIFY_NONE);
    1888             :         } else {
    1889           0 :             cci_->CassSslAddTrustedCert(ssl_.get(), content);
    1890             :         }
    1891           0 :         cci_->CassClusterSetSsl(cluster_.get(), ssl_.get());
    1892           0 :     }
    1893        3703 :     std::string contact_points(boost::algorithm::join(cassandra_ips, ","));
    1894        3703 :     cci_->CassClusterSetContactPoints(cluster_.get(), contact_points.c_str());
    1895        3703 :     cci_->CassClusterSetPort(cluster_.get(), cassandra_port);
    1896             :     // Set credentials for plain text authentication
    1897        3703 :     if (!cassandra_user.empty() && !cassandra_password.empty()) {
    1898           0 :         cci_->CassClusterSetCredentials(cluster_.get(), cassandra_user.c_str(),
    1899             :             cassandra_password.c_str());
    1900             :     }
    1901             :     // Set number of IO threads to half the number of cores
    1902        3703 :     cci_->CassClusterSetNumThreadsIo(cluster_.get(), io_thread_count_);
    1903        3703 :     cci_->CassClusterSetPendingRequestsHighWaterMark(cluster_.get(), 10000);
    1904        3703 :     cci_->CassClusterSetPendingRequestsLowWaterMark(cluster_.get(), 5000);
    1905        3703 :     cci_->CassClusterSetWriteBytesHighWaterMark(cluster_.get(), 128000);
    1906        3703 :     cci_->CassClusterSetWriteBytesLowWaterMark(cluster_.get(), 96000);
    1907        3703 : }
    1908             : 
    1909        7406 : CqlIfImpl::~CqlIfImpl() {
    1910        3703 :     assert(session_state_ == SessionState::INIT ||
    1911             :         session_state_ == SessionState::DISCONNECTED);
    1912        3703 :     assert(schema_session_state_ == SessionState::INIT ||
    1913             :         schema_session_state_ == SessionState::DISCONNECTED);
    1914        7406 : }
    1915             : 
    1916           0 : bool CqlIfImpl::CreateKeyspaceIfNotExistsSync(const std::string &keyspace,
    1917             :     const std::string &replication_factor, CassConsistency consistency) {
    1918           0 :     if (schema_session_state_ != SessionState::CONNECTED) {
    1919           0 :         return false;
    1920             :     }
    1921             :     char buf[512];
    1922           0 :     int n(snprintf(buf, sizeof(buf), kQCreateKeyspaceIfNotExists,
    1923             :         keyspace.c_str(), replication_factor.c_str()));
    1924           0 :     if (n < 0 || n >= (int)sizeof(buf)) {
    1925           0 :         CQLIF_ERR_TRACE("FAILED (" << n << "): Keyspace: " <<
    1926             :             keyspace << ", RF: " << replication_factor);
    1927           0 :         return false;
    1928             :     }
    1929           0 :     return impl::ExecuteQuerySync(cci_, schema_session_.get(), buf,
    1930           0 :         consistency);
    1931             : }
    1932             : 
    1933           0 : bool CqlIfImpl::UseKeyspaceSyncOnSchemaSession(const std::string &keyspace,
    1934             :     CassConsistency consistency) {
    1935           0 :     if (schema_session_state_ != SessionState::CONNECTED) {
    1936           0 :         return false;
    1937             :     }
    1938             :     char buf[512];
    1939           0 :     int n(snprintf(buf, sizeof(buf), kQUseKeyspace, keyspace.c_str()));
    1940           0 :     if (n < 0 || n >= (int)sizeof(buf)) {
    1941           0 :         CQLIF_ERR_TRACE("FAILED (" << n << "): Keyspace: " <<
    1942             :             keyspace);
    1943           0 :         return false;
    1944             :     }
    1945           0 :     bool success(impl::ExecuteQuerySync(cci_, schema_session_.get(), buf,
    1946             :         consistency));
    1947           0 :     if (!success) {
    1948           0 :         return false;
    1949             :     }
    1950             :     // Update keyspace
    1951           0 :     keyspace_ = keyspace;
    1952           0 :     return success;
    1953             : }
    1954             : 
    1955          25 : bool CqlIfImpl::UseKeyspaceSync(const std::string &keyspace,
    1956             :     CassConsistency consistency) {
    1957          25 :     if (session_state_ != SessionState::CONNECTED) {
    1958           0 :         return false;
    1959             :     }
    1960             :     char buf[512];
    1961          25 :     int n(snprintf(buf, sizeof(buf), kQUseKeyspace, keyspace.c_str()));
    1962          25 :     if (n < 0 || n >= (int)sizeof(buf)) {
    1963           0 :         CQLIF_ERR_TRACE("FAILED (" << n << "): Keyspace: " <<
    1964             :             keyspace);
    1965           0 :         return false;
    1966             :     }
    1967          25 :     bool success(impl::ExecuteQuerySync(cci_, session_.get(), buf,
    1968             :         consistency));
    1969          25 :     if (!success) {
    1970           0 :         return false;
    1971             :     }
    1972             :     // Update keyspace
    1973          25 :     keyspace_ = keyspace;
    1974          25 :     return success;
    1975             : }
    1976             : 
    1977           0 : bool CqlIfImpl::CreateTableIfNotExistsSync(const GenDb::NewCf &cf,
    1978             :     const std::string &compaction_strategy, CassConsistency consistency) {
    1979           0 :     if (schema_session_state_ != SessionState::CONNECTED) {
    1980           0 :         return false;
    1981             :     }
    1982             :     // There are two types of tables - Static (SQL) and Dynamic (NOSQL)
    1983             :     // column family. Static column family has more or less fixed rows,
    1984             :     // and dynamic column family has wide rows
    1985           0 :     std::string query;
    1986           0 :     switch (cf.cftype_) {
    1987           0 :       case GenDb::NewCf::COLUMN_FAMILY_SQL:
    1988             :       {
    1989           0 :         query = impl::StaticCf2CassCreateTableIfNotExists(cf,
    1990           0 :             compaction_strategy);
    1991           0 :         break;
    1992             :       }
    1993           0 :       case GenDb::NewCf::COLUMN_FAMILY_NOSQL:
    1994             :       {
    1995           0 :         boost::system::error_code ec;
    1996           0 :         query = impl::DynamicCf2CassCreateTableIfNotExists(cf,
    1997           0 :             compaction_strategy, &ec);
    1998           0 :         if (ec) {
    1999           0 :             return false;
    2000             :         }
    2001           0 :         break;
    2002             :       }
    2003           0 :       default:
    2004             :       {
    2005           0 :         return false;
    2006             :       }
    2007             :     }
    2008           0 :     return impl::ExecuteQuerySync(cci_, schema_session_.get(), query.c_str(),
    2009           0 :         consistency);
    2010           0 : }
    2011             : 
    2012           0 : bool CqlIfImpl::CreateIndexIfNotExistsSync(const std::string &cfname,
    2013             :     const std::string &column, const std::string &indexname,
    2014             :     CassConsistency consistency, const GenDb::ColIndexMode::type index_mode) {
    2015           0 :     if (schema_session_state_ != SessionState::CONNECTED) {
    2016           0 :         return false;
    2017             :     }
    2018             :     std::string query(impl::CassCreateIndexIfNotExists(cfname, column,
    2019           0 :         indexname, index_mode));
    2020           0 :     return impl::ExecuteQuerySync(cci_, schema_session_.get(), query.c_str(),
    2021           0 :         consistency);
    2022           0 : }
    2023             : 
    2024           0 : bool CqlIfImpl::LocatePrepareInsertIntoTable(const GenDb::NewCf &cf) {
    2025           0 :     const std::string &table_name(cf.cfname_);
    2026           0 :     impl::CassPreparedPtr prepared(NULL, cci_);
    2027             :     // Check if the prepared statement exists
    2028           0 :     if (GetPrepareInsertIntoTable(table_name, &prepared)) {
    2029           0 :         return true;
    2030             :     }
    2031           0 :     bool success(PrepareInsertIntoTableSync(cf, &prepared));
    2032           0 :     if (!success) {
    2033           0 :         return success;
    2034             :     }
    2035             :     // Store the prepared statement into the map
    2036           0 :     std::scoped_lock lock(map_mutex_);
    2037           0 :     success = (insert_prepared_map_.insert(
    2038           0 :         std::make_pair(table_name, prepared))).second;
    2039           0 :     assert(success);
    2040           0 :     return success;
    2041           0 : }
    2042             : 
    2043           0 : bool CqlIfImpl::GetPrepareInsertIntoTable(const std::string &table_name,
    2044             :     impl::CassPreparedPtr *prepared) const {
    2045           0 :     std::scoped_lock lock(map_mutex_);
    2046             :     CassPreparedMapType::const_iterator it(
    2047           0 :         insert_prepared_map_.find(table_name));
    2048           0 :     if (it == insert_prepared_map_.end()) {
    2049           0 :         return false;
    2050             :     }
    2051           0 :     *prepared = it->second;
    2052           0 :     return true;
    2053           0 : }
    2054             : 
    2055         150 : bool CqlIfImpl::IsTablePresent(const std::string &table) {
    2056         150 :     if (session_state_ != SessionState::CONNECTED) {
    2057           0 :         return false;
    2058             :     }
    2059         150 :     return impl::IsCassTableMetaPresent(cci_, session_.get(), keyspace_,
    2060         150 :         table);
    2061             : }
    2062             : 
    2063      108851 : int CqlIfImpl::IsTableStatic(const std::string &table) {
    2064      108851 :     if (session_state_ != SessionState::CONNECTED) {
    2065           0 :         return false;
    2066             :     }
    2067             :     size_t ck_count;
    2068      108967 :     if (!impl::GetCassTableClusteringKeyCount(cci_, session_.get(),
    2069      108970 :         keyspace_, table, &ck_count)) {
    2070           0 :         return -1;
    2071             :     }
    2072      108822 :     if (ck_count == 0) {
    2073          25 :         return 1;
    2074             :     } else {
    2075      108797 :         return 0;
    2076             :     }
    2077             : }
    2078             : 
    2079           0 : bool CqlIfImpl::SelectFromTableAsync(const std::string &cfname,
    2080             :     const GenDb::DbDataValueVec &rkey, CassConsistency consistency,
    2081             :     impl::CassAsyncQueryCallback cb) {
    2082           0 :     if (session_state_ != SessionState::CONNECTED) {
    2083           0 :         return false;
    2084             :     }
    2085           0 :     std::string query(impl::PartitionKey2CassSelectFromTable(cfname,rkey));
    2086           0 :     if (IsTableStatic(cfname) == 1) {
    2087           0 :         return impl::StaticCfGetResultAsync(cci_, session_.get(),
    2088           0 :             query.c_str(), consistency, cb, cfname.c_str(), rkey);
    2089           0 :     } else if (IsTableStatic(cfname) == 0) {
    2090             :         size_t rk_count;
    2091           0 :         assert(impl::GetCassTablePartitionKeyCount(cci_, session_.get(),
    2092             :             keyspace_, cfname, &rk_count));
    2093             :         size_t ck_count;
    2094           0 :         assert(impl::GetCassTableClusteringKeyCount(cci_, session_.get(),
    2095             :             keyspace_, cfname, &ck_count));
    2096           0 :         return impl::DynamicCfGetResultAsync(cci_, session_.get(),
    2097             :             query.c_str(), consistency, cb, rk_count, ck_count,
    2098           0 :             cfname, rkey);
    2099             :    } else {
    2100           0 :         return false;
    2101             :    }
    2102           0 : }
    2103             : 
    2104      107757 : bool CqlIfImpl::SelectFromTableClusteringKeyRangeAndIndexValueAsync(
    2105             :     const std::string &cfname, const GenDb::DbDataValueVec &rkey,
    2106             :     const GenDb::ColumnNameRange &ck_range,
    2107             :     const GenDb::WhereIndexInfoVec &where_vec,
    2108             :     const GenDb::FieldNamesToReadVec &read_vec, CassConsistency consistency,
    2109             :     impl::CassAsyncQueryCallback cb) {
    2110      107757 :         if (session_state_ != SessionState::CONNECTED) {
    2111           0 :         return false;
    2112             :     }
    2113             :     std::string query(
    2114             :         impl::ClusteringKeyRangeAndIndexValue2CassSelectFromTable(cfname,
    2115      108130 :         rkey, ck_range, where_vec, read_vec));
    2116      107833 :     assert(IsTableDynamic(cfname));
    2117             :     size_t rk_count;
    2118      108091 :     assert(impl::GetCassTablePartitionKeyCount(cci_, session_.get(),
    2119             :         keyspace_, cfname, &rk_count));
    2120             :     size_t ck_count;
    2121      108152 :     assert(impl::GetCassTableClusteringKeyCount(cci_, session_.get(),
    2122             :         keyspace_, cfname, &ck_count));
    2123      216186 :     return impl::DynamicCfGetResultAsync(cci_, session_.get(),
    2124             :         query.c_str(), consistency, cb, rk_count, ck_count, cfname.c_str(),
    2125      108023 :         rkey);
    2126      107997 : }
    2127             : 
    2128           0 : bool CqlIfImpl::SelectFromTableClusteringKeyRangeAsync(
    2129             :     const std::string &cfname, const GenDb::DbDataValueVec &rkey,
    2130             :     const GenDb::ColumnNameRange &ck_range, CassConsistency consistency,
    2131             :     impl::CassAsyncQueryCallback cb) {
    2132           0 :     if (session_state_ != SessionState::CONNECTED) {
    2133           0 :         return false;
    2134             :     }
    2135             :     std::string query(
    2136             :         impl::PartitionKeyAndClusteringKeyRange2CassSelectFromTable(cfname,
    2137           0 :         rkey, ck_range));
    2138           0 :     assert(IsTableDynamic(cfname));
    2139             :     size_t rk_count;
    2140           0 :     assert(impl::GetCassTablePartitionKeyCount(cci_, session_.get(),
    2141             :         keyspace_, cfname, &rk_count));
    2142             :     size_t ck_count;
    2143           0 :     assert(impl::GetCassTableClusteringKeyCount(cci_, session_.get(),
    2144             :         keyspace_, cfname, &ck_count));
    2145           0 :     return impl::DynamicCfGetResultAsync(cci_, session_.get(),
    2146             :         query.c_str(), consistency, cb, rk_count, ck_count, cfname.c_str(),
    2147           0 :         rkey);
    2148           0 : }
    2149             : 
    2150      107879 : bool CqlIfImpl::IsTableDynamic(const std::string &table) {
    2151      107879 :     return !IsTableStatic(table);
    2152             : }
    2153             : 
    2154           0 : bool CqlIfImpl::InsertIntoTableSync(std::auto_ptr<GenDb::ColList> v_columns,
    2155             :     CassConsistency consistency) {
    2156           0 :     return InsertIntoTableInternal(v_columns, consistency, true, NULL);
    2157             : }
    2158             : 
    2159           0 : bool CqlIfImpl::InsertIntoTableAsync(std::auto_ptr<GenDb::ColList> v_columns,
    2160             :     CassConsistency consistency, impl::CassAsyncQueryCallback cb) {
    2161           0 :     return InsertIntoTableInternal(v_columns, consistency, false, cb);
    2162             : }
    2163             : 
    2164           0 : bool CqlIfImpl::InsertIntoTablePrepareAsync(std::auto_ptr<GenDb::ColList> v_columns,
    2165             :     CassConsistency consistency, impl::CassAsyncQueryCallback cb) {
    2166           0 :     return InsertIntoTablePrepareInternal(v_columns, consistency, false,
    2167           0 :         cb);
    2168             : }
    2169             : 
    2170             : // COLLECTOR_GLOBAL_TABLE is dynamic table with 6 indexed columns
    2171             : // for object-id. Some of these might be blank. This creates tombstones
    2172             : // so we dont want to prepare for inserts.
    2173           0 : bool CqlIfImpl::IsInsertIntoTablePrepareSupported(const std::string &table) {
    2174           0 :     return (IsTableDynamic(table)) &&
    2175           0 :            (table != "MessageTablev2");
    2176             : }
    2177             : 
    2178         525 : bool CqlIfImpl::SelectFromTableSync(const std::string &cfname,
    2179             :     const GenDb::DbDataValueVec &rkey, CassConsistency consistency,
    2180             :     GenDb::NewColVec *out) {
    2181         525 :     if (session_state_ != SessionState::CONNECTED) {
    2182           0 :         return false;
    2183             :     }
    2184             :     std::string query(impl::PartitionKey2CassSelectFromTable(cfname,
    2185         525 :         rkey));
    2186         525 :     if (IsTableStatic(cfname) == 1) {
    2187          25 :         return impl::StaticCfGetResultSync(cci_, session_.get(),
    2188          25 :             query.c_str(), consistency, out);
    2189         500 :     } else if (IsTableStatic(cfname) == 0){
    2190             :         size_t rk_count;
    2191         500 :         assert(impl::GetCassTablePartitionKeyCount(cci_, session_.get(),
    2192             :             keyspace_, cfname, &rk_count));
    2193             :         size_t ck_count;
    2194         500 :         assert(impl::GetCassTableClusteringKeyCount(cci_, session_.get(),
    2195             :             keyspace_, cfname, &ck_count));
    2196         500 :         return impl::DynamicCfGetResultSync(cci_, session_.get(),
    2197         500 :             query.c_str(), rk_count, ck_count, consistency, out);
    2198             :     } else {
    2199           0 :         return false;
    2200             :     }
    2201         525 : }
    2202             : 
    2203           0 : bool CqlIfImpl::SelectFromTableSync(const std::string &cfname,
    2204             :     CassConsistency consistency, GenDb::ColListVec *out) {
    2205           0 :     if (session_state_ != SessionState::CONNECTED) {
    2206           0 :         return false;
    2207             :     }
    2208           0 :     std::string query(impl::CassSelectFromTable(cfname));
    2209             :     size_t rk_count;
    2210           0 :     assert(impl::GetCassTablePartitionKeyCount(cci_, session_.get(),
    2211             :         keyspace_, cfname, &rk_count));
    2212           0 :     if (IsTableStatic(cfname) == 1) {
    2213           0 :         return impl::StaticCfGetResultSync(cci_, session_.get(),
    2214           0 :             query.c_str(), rk_count, consistency, out);
    2215           0 :     } else if (IsTableStatic(cfname) == 0){
    2216             :         size_t ck_count;
    2217           0 :         assert(impl::GetCassTableClusteringKeyCount(cci_, session_.get(),
    2218             :             keyspace_, cfname, &ck_count));
    2219           0 :         return impl::DynamicCfGetResultSync(cci_, session_.get(),
    2220           0 :             query.c_str(), rk_count, ck_count, consistency, out);
    2221             :     } else {
    2222           0 :         return false;
    2223             :     }
    2224           0 : }
    2225             : 
    2226             : 
    2227           0 : bool CqlIfImpl::SelectFromTableClusteringKeyRangeFieldNamesSync(const std::string &cfname,
    2228             :     const GenDb::DbDataValueVec &rkey,
    2229             :     const GenDb::ColumnNameRange &ck_range, CassConsistency consistency,
    2230             :     const GenDb::FieldNamesToReadVec &read_vec,
    2231             :     GenDb::NewColVec *out) {
    2232           0 :     if (session_state_ != SessionState::CONNECTED) {
    2233           0 :         return false;
    2234             :     }
    2235             :     std::string query(
    2236             :         impl::PartitionKeyAndClusteringKeyRange2CassSelectFromTable(cfname,
    2237           0 :         rkey, ck_range, read_vec));
    2238           0 :     assert(IsTableDynamic(cfname));
    2239           0 :     return impl::DynamicCfGetResultSync(cci_, session_.get(),
    2240           0 :         query.c_str(), read_vec, consistency, out);
    2241           0 : }
    2242             : 
    2243           0 : bool CqlIfImpl::SelectFromTableClusteringKeyRangeFieldNamesSync(const std::string &cfname,
    2244             :     const std::vector<GenDb::DbDataValueVec> &rkeys,
    2245             :     const GenDb::ColumnNameRange &ck_range, CassConsistency consistency,
    2246             :     const GenDb::FieldNamesToReadVec &read_vec,
    2247             :     GenDb::ColListVec *out) {
    2248           0 :     if (session_state_ != SessionState::CONNECTED) {
    2249           0 :         return false;
    2250             :     }
    2251             :     std::string query(
    2252             :         impl::PartitionKeyAndClusteringKeyRange2CassSelectFromTable(cfname,
    2253           0 :         rkeys, ck_range, read_vec));
    2254           0 :     assert(IsTableDynamic(cfname));
    2255           0 :     return impl::DynamicCfGetResultSync(cci_, session_.get(),
    2256           0 :         query.c_str(), read_vec, consistency, out);
    2257           0 : }
    2258             : 
    2259             : 
    2260           0 : bool CqlIfImpl::SelectFromTableClusteringKeyRangeSync(const std::string &cfname,
    2261             :     const GenDb::DbDataValueVec &rkey,
    2262             :     const GenDb::ColumnNameRange &ck_range, CassConsistency consistency,
    2263             :     GenDb::NewColVec *out) {
    2264           0 :     if (session_state_ != SessionState::CONNECTED) {
    2265           0 :         return false;
    2266             :     }
    2267             :     std::string query(
    2268             :         impl::PartitionKeyAndClusteringKeyRange2CassSelectFromTable(cfname,
    2269           0 :         rkey, ck_range));
    2270           0 :     assert(IsTableDynamic(cfname));
    2271             :     size_t rk_count;
    2272           0 :     assert(impl::GetCassTablePartitionKeyCount(cci_, session_.get(),
    2273             :         keyspace_, cfname, &rk_count));
    2274             :     size_t ck_count;
    2275           0 :     assert(impl::GetCassTableClusteringKeyCount(cci_, session_.get(),
    2276             :         keyspace_, cfname, &ck_count));
    2277           0 :     return impl::DynamicCfGetResultSync(cci_, session_.get(),
    2278           0 :         query.c_str(), rk_count, ck_count, consistency, out);
    2279           0 : }
    2280             : 
    2281           0 : void CqlIfImpl::SetRequestTimeout(uint32_t timeout_ms) {
    2282           0 :     CQLIF_DEBUG_TRACE("request timeout set to " << timeout_ms);
    2283           0 :     cci_->CassClusterSetRequestTimeout(cluster_.get(), timeout_ms);
    2284           0 : }
    2285             : 
    2286           0 : bool CqlIfImpl::ConnectSchemaSync() {
    2287             :     /* If Connect is called multiple times due to DB failure,
    2288             :      * then it is better to delete previous session and use
    2289             :      * a new one to avoid gradual leak.
    2290             :      */
    2291           0 :     schema_session_.reset();
    2292           0 :     impl::CassSessionPtr schema_session(cci_->CassSessionNew(), cci_);
    2293           0 :     schema_session_.swap(schema_session);
    2294             : 
    2295             :     // First set the cluster whitelist filtering to just one node
    2296           0 :     cci_->CassClusterSetWhitelistFiltering(cluster_.get(),
    2297             :            schema_contact_point_.c_str());
    2298             : 
    2299           0 :     impl::CassFuturePtr future(cci_->CassSessionConnect(schema_session_.get(),
    2300           0 :         cluster_.get()), cci_);
    2301           0 :     bool success(impl::SyncFutureWait(cci_, future.get()));
    2302           0 :     if (success) {
    2303           0 :         schema_session_state_ = SessionState::CONNECTED;
    2304           0 :         CQLIF_INFO_TRACE("ConnectSchemaSync Done");
    2305             :     } else {
    2306           0 :         CQLIF_ERR_TRACE("ConnectSchemaSync FAILED");
    2307             :     }
    2308             : 
    2309           0 :     cci_->CassClusterSetWhitelistFiltering(cluster_.get(), "");
    2310           0 :     return success;
    2311           0 : }
    2312             : 
    2313          25 : bool CqlIfImpl::ConnectSync() {
    2314             :     /* If Connect is called multiple times due to DB failure,
    2315             :      * then it is better to delete previous session and use
    2316             :      * a new one to avoid gradual leak.
    2317             :      */
    2318          25 :     session_.reset();
    2319          25 :     impl::CassSessionPtr session(cci_->CassSessionNew(), cci_);
    2320          25 :     session_.swap(session);
    2321             : 
    2322          25 :     impl::CassFuturePtr future(cci_->CassSessionConnect(session_.get(),
    2323          25 :         cluster_.get()), cci_);
    2324          25 :     bool success(impl::SyncFutureWait(cci_, future.get()));
    2325          25 :     if (success) {
    2326          25 :         session_state_ = SessionState::CONNECTED;
    2327          25 :         CQLIF_INFO_TRACE("ConnectSync Done");
    2328             :     } else {
    2329           0 :         CQLIF_ERR_TRACE("ConnectSync FAILED");
    2330             :     }
    2331          25 :     return success;
    2332          25 : }
    2333             : 
    2334          25 : bool CqlIfImpl::DisconnectSync() {
    2335             :     // Close all session and pending queries
    2336          25 :     impl::CassFuturePtr future(cci_->CassSessionClose(session_.get()), cci_);
    2337          25 :     bool success(impl::SyncFutureWait(cci_, future.get()));
    2338          25 :     if (success) {
    2339          25 :         session_state_ = SessionState::DISCONNECTED;
    2340          25 :         CQLIF_INFO_TRACE("DisconnectSync Done");
    2341             :     } else {
    2342           0 :         CQLIF_ERR_TRACE("DisconnectSync FAILED");
    2343             :     }
    2344          25 :     return success;
    2345          25 : }
    2346             : 
    2347           0 : bool CqlIfImpl::DisconnectSchemaSync() {
    2348             :     // Close the schema session
    2349           0 :     impl::CassFuturePtr future(cci_->CassSessionClose(schema_session_.get()),
    2350           0 :         cci_);
    2351           0 :     bool success(impl::SyncFutureWait(cci_, future.get()));
    2352           0 :     if (success) {
    2353           0 :         schema_session_state_ = SessionState::DISCONNECTED;
    2354           0 :         CQLIF_INFO_TRACE("DisconnectSchemaSync Done");
    2355             :     } else {
    2356           0 :         CQLIF_ERR_TRACE("DisconnectSchemaSync FAILED");
    2357             :     }
    2358           0 :     return success;
    2359           0 : }
    2360             : 
    2361          27 : bool CqlIfImpl::GetMetrics(Metrics *metrics) const {
    2362          27 :     if (session_state_ != SessionState::CONNECTED) {
    2363           0 :         return false;
    2364             :     }
    2365             :     CassMetrics cass_metrics;
    2366          27 :     cci_->CassSessionGetMetrics(session_.get(), &cass_metrics);
    2367             :     // Requests
    2368          27 :     metrics->requests.min = cass_metrics.requests.min;
    2369          27 :     metrics->requests.max = cass_metrics.requests.max;
    2370          27 :     metrics->requests.mean = cass_metrics.requests.mean;
    2371          27 :     metrics->requests.stddev = cass_metrics.requests.stddev;
    2372          27 :     metrics->requests.median = cass_metrics.requests.median;
    2373          27 :     metrics->requests.percentile_75th =
    2374          27 :         cass_metrics.requests.percentile_75th;
    2375          27 :     metrics->requests.percentile_95th =
    2376          27 :         cass_metrics.requests.percentile_95th;
    2377          27 :     metrics->requests.percentile_98th =
    2378          27 :         cass_metrics.requests.percentile_98th;
    2379          27 :     metrics->requests.percentile_99th =
    2380          27 :         cass_metrics.requests.percentile_99th;
    2381          27 :     metrics->requests.percentile_999th =
    2382          27 :         cass_metrics.requests.percentile_999th;
    2383          27 :     metrics->requests.mean_rate = cass_metrics.requests.mean_rate;
    2384          27 :     metrics->requests.one_minute_rate =
    2385          27 :         cass_metrics.requests.one_minute_rate;
    2386          27 :     metrics->requests.five_minute_rate =
    2387          27 :         cass_metrics.requests.five_minute_rate;
    2388          27 :     metrics->requests.fifteen_minute_rate =
    2389          27 :         cass_metrics.requests.fifteen_minute_rate;
    2390             :     // Stats
    2391          27 :     metrics->stats.total_connections =
    2392          27 :         cass_metrics.stats.total_connections;
    2393          27 :     metrics->stats.available_connections =
    2394          27 :         cass_metrics.stats.available_connections;
    2395          27 :     metrics->stats.exceeded_pending_requests_water_mark =
    2396          27 :         cass_metrics.stats.exceeded_pending_requests_water_mark;
    2397          27 :     metrics->stats.exceeded_write_bytes_water_mark =
    2398          27 :         cass_metrics.stats.exceeded_write_bytes_water_mark;
    2399             :     // Errors
    2400          27 :     metrics->errors.connection_timeouts =
    2401          27 :         cass_metrics.errors.connection_timeouts;
    2402          27 :     metrics->errors.pending_request_timeouts =
    2403          27 :         cass_metrics.errors.pending_request_timeouts;
    2404          27 :     metrics->errors.request_timeouts =
    2405          27 :         cass_metrics.errors.request_timeouts;
    2406          27 :     return true;
    2407             : }
    2408             : 
    2409           0 : bool CqlIfImpl::InsertIntoTableInternal(std::auto_ptr<GenDb::ColList> v_columns,
    2410             :     CassConsistency consistency, bool sync,
    2411             :     impl::CassAsyncQueryCallback cb) {
    2412           0 :     if (session_state_ != SessionState::CONNECTED) {
    2413           0 :         return false;
    2414             :     }
    2415           0 :     std::string query;
    2416           0 :     if (IsTableStatic(v_columns->cfname_) == 1) {
    2417           0 :         query = impl::StaticCf2CassInsertIntoTable(v_columns.get());
    2418           0 :     } else if (IsTableStatic(v_columns->cfname_) == 0){
    2419           0 :         query = impl::DynamicCf2CassInsertIntoTable(v_columns.get());
    2420             :     } else {
    2421           0 :         return false;
    2422             :     }
    2423           0 :     if (sync) {
    2424           0 :         return impl::ExecuteQuerySync(cci_, session_.get(), query.c_str(),
    2425           0 :             consistency);
    2426             :     } else {
    2427           0 :         impl::ExecuteQueryAsync(cci_, session_.get(), query.c_str(),
    2428             :             consistency, cb);
    2429           0 :         return true;
    2430             :     }
    2431           0 : }
    2432             : 
    2433           0 : bool CqlIfImpl::PrepareInsertIntoTableSync(const GenDb::NewCf &cf,
    2434             :     impl::CassPreparedPtr *prepared) {
    2435           0 :     if (schema_session_state_ != SessionState::CONNECTED) {
    2436           0 :         return false;
    2437             :     }
    2438           0 :     std::string query;
    2439           0 :     switch (cf.cftype_) {
    2440           0 :       case GenDb::NewCf::COLUMN_FAMILY_SQL:
    2441             :       {
    2442           0 :         query = impl::StaticCf2CassPrepareInsertIntoTable(cf);
    2443           0 :         break;
    2444             :       }
    2445           0 :       case GenDb::NewCf::COLUMN_FAMILY_NOSQL:
    2446             :       {
    2447           0 :         boost::system::error_code ec;
    2448           0 :         query = impl::DynamicCf2CassPrepareInsertIntoTable(cf, &ec);
    2449           0 :         if (ec.value() != boost::system::errc::success) {
    2450           0 :             return false;
    2451             :         }
    2452           0 :         break;
    2453             :       }
    2454           0 :       default:
    2455             :       {
    2456           0 :         return false;
    2457             :       }
    2458             :     }
    2459           0 :     return impl::PrepareSync(cci_, schema_session_.get(), query.c_str(),
    2460           0 :         prepared);
    2461           0 : }
    2462             : 
    2463           0 : bool CqlIfImpl::InsertIntoTablePrepareInternal(
    2464             :     std::auto_ptr<GenDb::ColList> v_columns,
    2465             :     CassConsistency consistency, bool sync,
    2466             :     impl::CassAsyncQueryCallback cb) {
    2467           0 :     if (session_state_ != SessionState::CONNECTED) {
    2468           0 :         return false;
    2469             :     }
    2470           0 :     impl::CassPreparedPtr prepared(NULL, cci_);
    2471           0 :     bool success(GetPrepareInsertIntoTable(v_columns->cfname_, &prepared));
    2472           0 :     if (!success) {
    2473           0 :         CQLIF_ERR_TRACE("CassPrepared statement NOT found: " <<
    2474             :             v_columns->cfname_);
    2475           0 :         return false;
    2476             :     }
    2477           0 :     impl::CassStatementPtr qstatement(cci_->CassPreparedBind(prepared.get()),
    2478           0 :         cci_);
    2479           0 :     if (IsTableStatic(v_columns->cfname_) == 1) {
    2480           0 :         success = impl::StaticCf2CassPrepareBind(cci_, qstatement.get(),
    2481           0 :             v_columns.get());
    2482           0 :     } else if (IsTableStatic(v_columns->cfname_) == 0){
    2483           0 :         success = impl::DynamicCf2CassPrepareBind(cci_, qstatement.get(),
    2484           0 :             v_columns.get());
    2485             :     } else {
    2486           0 :         return false;
    2487             :     }
    2488           0 :     if (!success) {
    2489           0 :         return false;
    2490             :     }
    2491           0 :     if (sync) {
    2492           0 :         return impl::ExecuteQueryStatementSync(cci_, session_.get(),
    2493           0 :             qstatement.get(), consistency);
    2494             :     } else {
    2495           0 :         std::string qid("Prepare: " + v_columns->cfname_);
    2496           0 :         impl::ExecuteQueryStatementAsync(cci_, session_.get(), qid.c_str(),
    2497             :             qstatement.get(), consistency, cb);
    2498           0 :         return true;
    2499           0 :     }
    2500           0 : }
    2501             : 
    2502             : const char * CqlIfImpl::kQCreateKeyspaceIfNotExists(
    2503             :     "CREATE KEYSPACE IF NOT EXISTS \"%s\" WITH "
    2504             :     "replication = { 'class' : 'SimpleStrategy', 'replication_factor' : %s }");
    2505             : const char * CqlIfImpl::kQUseKeyspace("USE \"%s\"");
    2506             : const char * CqlIfImpl::kTaskName("CqlIfImpl::Task");
    2507             : 
    2508             : //
    2509             : // CqlIf
    2510             : //
    2511        3703 : CqlIf::CqlIf(EventManager *evm,
    2512             :              const std::vector<std::string> &cassandra_ips,
    2513             :              int cassandra_port,
    2514             :              const std::string &cassandra_user,
    2515             :              const std::string &cassandra_password,
    2516             :              bool use_ssl,
    2517             :              const std::string &ca_certs_path,
    2518        3703 :              bool create_schema) :
    2519        3703 :     cci_(new interface::CassDatastaxLibrary),
    2520        3703 :     impl_(new CqlIfImpl(evm, cassandra_ips, cassandra_port,
    2521             :         cassandra_user, cassandra_password, use_ssl,
    2522        3703 :         ca_certs_path, cci_.get())),
    2523        3703 :     use_prepared_for_insert_(true),
    2524        7406 :     create_schema_(create_schema) {
    2525             :     // Setup library logging
    2526        7406 :     cci_->CassLogSetLevel(impl::Log4Level2CassLogLevel(
    2527        7406 :         log4cplus::Logger::getRoot().getLogLevel()));
    2528        3703 :     cci_->CassLogSetCallback(impl::CassLibraryLog, NULL);
    2529        3703 :     initialized_ = false;
    2530        3755 :     BOOST_FOREACH(const std::string &cassandra_ip, cassandra_ips) {
    2531          26 :         boost::system::error_code ec;
    2532             :         boost::asio::ip::address cassandra_addr(
    2533          26 :             AddressFromString(cassandra_ip, &ec));
    2534          26 :         GenDb::Endpoint endpoint(cassandra_addr, cassandra_port);
    2535          26 :         endpoints_.push_back(endpoint);
    2536             :     }
    2537        3703 : }
    2538             : 
    2539          26 : CqlIf::CqlIf() : impl_(NULL) {
    2540          26 : }
    2541             : 
    2542        3918 : CqlIf::~CqlIf() {
    2543        3918 : }
    2544             : 
    2545             : // Init/Uninit
    2546          25 : bool CqlIf::Db_Init() {
    2547          25 :     if (create_schema_) {
    2548           0 :         impl_->SetRequestTimeout(GenDb::g_gendb_constants.SCHEMA_REQUEST_TIMEOUT);
    2549           0 :         bool success(impl_->ConnectSchemaSync());
    2550           0 :         if (!success) {
    2551           0 :             return success;
    2552             :         }
    2553             :     }
    2554          25 :     return impl_->ConnectSync();
    2555             : }
    2556             : 
    2557          25 : void CqlIf::Db_Uninit() {
    2558          25 :     if (create_schema_) {
    2559           0 :         impl_->DisconnectSchemaSync();
    2560             :     }
    2561          25 :     impl_->DisconnectSync();
    2562          25 : }
    2563             : 
    2564          50 : void CqlIf::Db_SetInitDone(bool init_done) {
    2565          50 :     initialized_ = init_done;
    2566             :     // No need for schema session if initialization is done
    2567          50 :     if (create_schema_) {
    2568           0 :         if (initialized_) {
    2569           0 :             impl_->SetRequestTimeout(GenDb::g_gendb_constants.DEFAULT_REQUEST_TIMEOUT);
    2570           0 :             impl_->DisconnectSchemaSync();
    2571             :         }
    2572             :     }
    2573          50 : }
    2574             : 
    2575             : // Tablespace
    2576           0 : bool CqlIf::Db_AddSetTablespace(const std::string &tablespace,
    2577             :     const std::string &replication_factor) {
    2578           0 :     bool success(impl_->CreateKeyspaceIfNotExistsSync(tablespace,
    2579             :         replication_factor, CASS_CONSISTENCY_QUORUM));
    2580           0 :     if (!success) {
    2581           0 :         IncrementErrors(GenDb::IfErrors::ERR_WRITE_TABLESPACE);
    2582           0 :         return success;
    2583             :     }
    2584           0 :     success = impl_->UseKeyspaceSyncOnSchemaSession(tablespace,
    2585             :         CASS_CONSISTENCY_ONE);
    2586           0 :     if (!success) {
    2587           0 :         IncrementErrors(GenDb::IfErrors::ERR_READ_TABLESPACE);
    2588           0 :         return success;
    2589             :     }
    2590           0 :     return success;
    2591             : }
    2592             : 
    2593          25 : bool CqlIf::Db_SetTablespace(const std::string &tablespace) {
    2594          25 :     bool success(impl_->UseKeyspaceSync(tablespace, CASS_CONSISTENCY_ONE));
    2595          25 :     if (!success) {
    2596           0 :         IncrementErrors(GenDb::IfErrors::ERR_READ_TABLESPACE);
    2597           0 :         return success;
    2598             :     }
    2599          25 :     return success;
    2600             : }
    2601             : 
    2602             : // Column family
    2603           0 : bool CqlIf::Db_AddColumnfamily(const GenDb::NewCf &cf,
    2604             :     const std::string &compaction_strategy) {
    2605             :     bool success(
    2606           0 :         impl_->CreateTableIfNotExistsSync(cf, compaction_strategy,
    2607             :             CASS_CONSISTENCY_QUORUM));
    2608           0 :     if (!success) {
    2609           0 :         IncrementTableWriteFailStats(cf.cfname_);
    2610           0 :         IncrementErrors(GenDb::IfErrors::ERR_WRITE_COLUMN_FAMILY);
    2611           0 :         return success;
    2612             :     }
    2613             :     // Locate (add if not exists) INSERT INTO prepare statement
    2614           0 :     success = impl_->LocatePrepareInsertIntoTable(cf);
    2615           0 :     if (!success) {
    2616           0 :         IncrementTableWriteFailStats(cf.cfname_);
    2617           0 :         IncrementErrors(GenDb::IfErrors::ERR_WRITE_COLUMN_FAMILY);
    2618           0 :         return success;
    2619             :     }
    2620           0 :     IncrementTableWriteStats(cf.cfname_);
    2621           0 :     return success;
    2622             : }
    2623             : 
    2624         125 : bool CqlIf::Db_UseColumnfamily(const GenDb::NewCf &cf) {
    2625             :     // Check existence of table
    2626         125 :     return Db_UseColumnfamily(cf.cfname_);
    2627             : }
    2628             : 
    2629         150 : bool CqlIf::Db_UseColumnfamily(const std::string &cfname) {
    2630             :     // Check existence of table
    2631         150 :     bool success(impl_->IsTablePresent(cfname));
    2632         150 :     if (!success) {
    2633          25 :         IncrementTableReadFailStats(cfname);
    2634          25 :         IncrementErrors(GenDb::IfErrors::ERR_READ_COLUMN_FAMILY);
    2635          25 :         return success;
    2636             :     }
    2637         125 :     IncrementTableReadStats(cfname);
    2638         125 :     return success;
    2639             : }
    2640             : 
    2641             : // Index
    2642           0 : bool CqlIf::Db_CreateIndex(const std::string &cfname,
    2643             :         const std::string &column, const std::string &indexname,
    2644             :         const GenDb::ColIndexMode::type index_mode) {
    2645           0 :     bool success(impl_->CreateIndexIfNotExistsSync(cfname, column, indexname,
    2646             :         CASS_CONSISTENCY_QUORUM, index_mode));
    2647           0 :     if (!success) {
    2648           0 :         IncrementTableWriteFailStats(cfname);
    2649           0 :         IncrementErrors(GenDb::IfErrors::ERR_WRITE_COLUMN_FAMILY);
    2650           0 :         return success;
    2651             :     }
    2652           0 :     return success;
    2653             : }
    2654             : 
    2655             : // Column
    2656           0 : void CqlIf::OnAsyncColumnAddCompletion(GenDb::DbOpResult::type drc,
    2657             :     std::auto_ptr<GenDb::ColList> row,
    2658             :     std::string cfname, GenDb::GenDbIf::DbAddColumnCb cb) {
    2659           0 :     if (drc == GenDb::DbOpResult::OK) {
    2660           0 :         IncrementTableWriteStats(cfname);
    2661           0 :     } else if (drc == GenDb::DbOpResult::BACK_PRESSURE) {
    2662           0 :         IncrementTableWriteBackPressureFailStats(cfname);
    2663           0 :         IncrementErrors(GenDb::IfErrors::ERR_WRITE_COLUMN);
    2664             :     } else {
    2665           0 :         IncrementTableWriteFailStats(cfname);
    2666           0 :         IncrementErrors(GenDb::IfErrors::ERR_WRITE_COLUMN);
    2667             :     }
    2668           0 :     if (!cb.empty()) {
    2669           0 :         cb(drc);
    2670             :     }
    2671           0 : }
    2672             : 
    2673             : struct AsyncRowGetCallbackContext {
    2674           0 :     AsyncRowGetCallbackContext(GenDb::GenDbIf::DbGetRowCb cb,
    2675           0 :         GenDb::DbOpResult::type drc, std::auto_ptr<GenDb::ColList> row) :
    2676           0 :         cb_(cb),
    2677           0 :         drc_(drc),
    2678           0 :         row_(row) {
    2679           0 :     }
    2680             :     GenDb::GenDbIf::DbGetRowCb cb_;
    2681             :     GenDb::DbOpResult::type drc_;
    2682             :     std::auto_ptr<GenDb::ColList> row_;
    2683             : };
    2684             : 
    2685           0 : static void AsyncRowGetCompletionCallback(
    2686             :     boost::shared_ptr<AsyncRowGetCallbackContext> cb_ctx) {
    2687           0 :     cb_ctx->cb_(cb_ctx->drc_, cb_ctx->row_);
    2688           0 : }
    2689             : 
    2690      108123 : void CqlIf::OnAsyncRowGetCompletion(GenDb::DbOpResult::type drc,
    2691             :     std::auto_ptr<GenDb::ColList> row, std::string cfname,
    2692             :     GenDb::GenDbIf::DbGetRowCb cb, bool use_worker, int task_id,
    2693             :     int task_instance) {
    2694      108123 :     if (drc == GenDb::DbOpResult::OK) {
    2695      108139 :         IncrementTableReadStats(cfname);
    2696           0 :     } else if (drc == GenDb::DbOpResult::BACK_PRESSURE) {
    2697           0 :         IncrementTableReadBackPressureFailStats(cfname);
    2698           0 :         IncrementErrors(GenDb::IfErrors::ERR_READ_COLUMN);
    2699             :     } else {
    2700           0 :         IncrementTableReadFailStats(cfname);
    2701           0 :         IncrementErrors(GenDb::IfErrors::ERR_READ_COLUMN);
    2702             :     }
    2703      108192 :     if (use_worker) {
    2704           0 :         if (!cb.empty()) {
    2705             :             boost::shared_ptr<AsyncRowGetCallbackContext> ctx(
    2706           0 :                 new AsyncRowGetCallbackContext(cb, drc, row));
    2707             :             impl::WorkerTask *worker(new impl::WorkerTask(
    2708           0 :                 boost::bind(&AsyncRowGetCompletionCallback, ctx),
    2709           0 :                     task_id, task_instance));
    2710           0 :             TaskScheduler *scheduler = TaskScheduler::GetInstance();
    2711           0 :             scheduler->Enqueue(worker);
    2712           0 :         }
    2713             :     } else {
    2714      108192 :         if (!cb.empty()) {
    2715      108192 :             cb(drc, row);
    2716             :         }
    2717             :     }
    2718      108182 : }
    2719             : 
    2720      108118 : void CqlIf::OnAsyncRowGetCompletion(GenDb::DbOpResult::type drc,
    2721             :     std::auto_ptr<GenDb::ColList> row, std::string cfname,
    2722             :     GenDb::GenDbIf::DbGetRowCb cb) {
    2723      108118 :     OnAsyncRowGetCompletion(drc, row, cfname, cb, false, -1, -2);
    2724      108185 : }
    2725           0 : bool CqlIf::Db_AddColumn(std::auto_ptr<GenDb::ColList> cl,
    2726             :     GenDb::DbConsistency::type dconsistency,
    2727             :     GenDb::GenDbIf::DbAddColumnCb cb) {
    2728           0 :     std::string cfname(cl->cfname_);
    2729           0 :     if (!initialized_) {
    2730           0 :         IncrementTableWriteFailStats(cfname);
    2731           0 :         IncrementErrors(GenDb::IfErrors::ERR_WRITE_COLUMN);
    2732           0 :         return false;
    2733             :     }
    2734           0 :     CassConsistency consistency(impl::Db2CassConsistency(dconsistency));
    2735             :     bool success;
    2736           0 :     if (use_prepared_for_insert_ &&
    2737           0 :         impl_->IsInsertIntoTablePrepareSupported(cfname)) {
    2738           0 :         success = impl_->InsertIntoTablePrepareAsync(cl, consistency,
    2739           0 :             boost::bind(&CqlIf::OnAsyncColumnAddCompletion, this, _1, _2, cfname,
    2740             :             cb));
    2741             :     } else {
    2742           0 :         success = impl_->InsertIntoTableAsync(cl, consistency,
    2743           0 :             boost::bind(&CqlIf::OnAsyncColumnAddCompletion, this, _1, _2, cfname,
    2744             :             cb));
    2745             :     }
    2746           0 :     if (!success) {
    2747           0 :         IncrementTableWriteFailStats(cfname);
    2748           0 :         IncrementErrors(GenDb::IfErrors::ERR_WRITE_COLUMN);
    2749           0 :         return success;
    2750             :     }
    2751           0 :     return success;
    2752           0 : }
    2753             : 
    2754           0 : bool CqlIf::Db_AddColumnSync(std::auto_ptr<GenDb::ColList> cl,
    2755             :     GenDb::DbConsistency::type dconsistency) {
    2756           0 :     std::string cfname(cl->cfname_);
    2757           0 :     CassConsistency consistency(impl::Db2CassConsistency(dconsistency));
    2758           0 :     bool success(impl_->InsertIntoTableSync(cl, consistency));
    2759           0 :     if (!success) {
    2760           0 :         IncrementTableWriteFailStats(cfname);
    2761           0 :         IncrementErrors(GenDb::IfErrors::ERR_WRITE_COLUMN);
    2762           0 :         return success;
    2763             :     }
    2764           0 :     IncrementTableWriteStats(cfname);
    2765           0 :     return success;
    2766           0 : }
    2767             : 
    2768             : // Read
    2769           0 : bool CqlIf::Db_GetRowAsync(const std::string &cfname,
    2770             :     const GenDb::DbDataValueVec &rowkey, const GenDb::ColumnNameRange &crange,
    2771             :     GenDb::DbConsistency::type dconsistency, GenDb::GenDbIf::DbGetRowCb cb) {
    2772           0 :     CassConsistency consistency(impl::Db2CassConsistency(dconsistency));
    2773           0 :     bool success(impl_->SelectFromTableClusteringKeyRangeAsync(cfname, rowkey,
    2774           0 :         crange, consistency, boost::bind(&CqlIf::OnAsyncRowGetCompletion, this,
    2775             :         _1, _2, cfname, cb)));
    2776           0 :     if (!success) {
    2777           0 :         IncrementTableReadFailStats(cfname);
    2778           0 :         IncrementErrors(GenDb::IfErrors::ERR_READ_COLUMN_FAMILY);
    2779             :     }
    2780           0 :     return success;
    2781             : }
    2782             : 
    2783           0 : bool CqlIf::Db_GetRowAsync(const std::string &cfname,
    2784             :     const GenDb::DbDataValueVec &rowkey, const GenDb::ColumnNameRange &crange,
    2785             :     GenDb::DbConsistency::type dconsistency, int task_id, int task_instance,
    2786             :     GenDb::GenDbIf::DbGetRowCb cb) {
    2787           0 :     CassConsistency consistency(impl::Db2CassConsistency(dconsistency));
    2788           0 :     bool success(impl_->SelectFromTableClusteringKeyRangeAsync(cfname, rowkey,
    2789           0 :         crange, consistency, boost::bind(&CqlIf::OnAsyncRowGetCompletion, this,
    2790             :         _1, _2, cfname, cb, true, task_id, task_instance)));
    2791           0 :     if (!success) {
    2792           0 :         IncrementTableReadFailStats(cfname);
    2793           0 :         IncrementErrors(GenDb::IfErrors::ERR_READ_COLUMN_FAMILY);
    2794             :     }
    2795           0 :     return success;
    2796             : }
    2797             : 
    2798           0 : bool CqlIf::Db_GetRowAsync(const std::string &cfname,
    2799             :     const GenDb::DbDataValueVec &rowkey,
    2800             :     GenDb::DbConsistency::type dconsistency,
    2801             :     GenDb::GenDbIf::DbGetRowCb cb) {
    2802           0 :     CassConsistency consistency(impl::Db2CassConsistency(dconsistency));
    2803           0 :     bool success(impl_->SelectFromTableAsync(cfname, rowkey,
    2804           0 :         consistency, boost::bind(&CqlIf::OnAsyncRowGetCompletion, this, _1, _2,
    2805             :         cfname, cb)));
    2806           0 :     if (!success) {
    2807           0 :         IncrementTableReadFailStats(cfname);
    2808           0 :         IncrementErrors(GenDb::IfErrors::ERR_READ_COLUMN_FAMILY);
    2809             :     }
    2810           0 :     return success;
    2811             : }
    2812             : 
    2813           0 : bool CqlIf::Db_GetRowAsync(const std::string &cfname,
    2814             :     const GenDb::DbDataValueVec &rowkey,
    2815             :     GenDb::DbConsistency::type dconsistency, int task_id, int task_instance,
    2816             :     GenDb::GenDbIf::DbGetRowCb cb) {
    2817           0 :     CassConsistency consistency(impl::Db2CassConsistency(dconsistency));
    2818           0 :     bool success(impl_->SelectFromTableAsync(cfname, rowkey,
    2819           0 :         consistency, boost::bind(&CqlIf::OnAsyncRowGetCompletion, this, _1, _2,
    2820             :         cfname, cb, true, task_id, task_instance)));
    2821           0 :     if (!success) {
    2822           0 :         IncrementTableReadFailStats(cfname);
    2823           0 :         IncrementErrors(GenDb::IfErrors::ERR_READ_COLUMN_FAMILY);
    2824             :     }
    2825           0 :     return success;
    2826             : }
    2827             : 
    2828      107505 : bool CqlIf::Db_GetRowAsync(const std::string &cfname,
    2829             :     const GenDb::DbDataValueVec &rowkey, const GenDb::ColumnNameRange &crange,
    2830             :     const GenDb::WhereIndexInfoVec &where_vec,
    2831             :     GenDb::DbConsistency::type dconsistency, GenDb::GenDbIf::DbGetRowCb cb) {
    2832      107505 :     CassConsistency consistency(impl::Db2CassConsistency(dconsistency));
    2833      324207 :     bool success(impl_->SelectFromTableClusteringKeyRangeAndIndexValueAsync(cfname,
    2834      215878 :         rowkey, crange, where_vec, GenDb::FieldNamesToReadVec(), consistency,
    2835      216073 :         boost::bind(&CqlIf::OnAsyncRowGetCompletion, this, _1, _2, cfname, cb)));
    2836      108066 :     if (!success) {
    2837           0 :         IncrementTableReadFailStats(cfname);
    2838           0 :         IncrementErrors(GenDb::IfErrors::ERR_READ_COLUMN_FAMILY);
    2839             :     }
    2840      108070 :     return success;
    2841             : }
    2842             : 
    2843          25 : bool CqlIf::Db_GetRow(GenDb::ColList *out, const std::string &cfname,
    2844             :     const GenDb::DbDataValueVec &rowkey,
    2845             :     GenDb::DbConsistency::type dconsistency) {
    2846          25 :     CassConsistency consistency(impl::Db2CassConsistency(dconsistency));
    2847          25 :     bool success(impl_->SelectFromTableSync(cfname, rowkey,
    2848             :         consistency, &out->columns_));
    2849          25 :     if (!success) {
    2850           0 :         IncrementTableReadFailStats(cfname);
    2851           0 :         IncrementErrors(GenDb::IfErrors::ERR_READ_COLUMN);
    2852           0 :         return success;
    2853             :     }
    2854          25 :     IncrementTableReadStats(cfname);
    2855          25 :     return success;
    2856             : }
    2857             : 
    2858           0 : bool CqlIf::Db_GetRow(GenDb::ColList *out, const std::string &cfname,
    2859             :     const GenDb::DbDataValueVec &rowkey,
    2860             :     GenDb::DbConsistency::type dconsistency,
    2861             :     const GenDb::ColumnNameRange &crange,
    2862             :     const GenDb::FieldNamesToReadVec &read_vec) {
    2863           0 :     CassConsistency consistency(impl::Db2CassConsistency(dconsistency));
    2864           0 :     bool success(impl_->SelectFromTableClusteringKeyRangeFieldNamesSync(cfname,
    2865             :        rowkey, crange, consistency, read_vec, &out->columns_));
    2866           0 :     if (!success) {
    2867           0 :         IncrementTableReadFailStats(cfname);
    2868           0 :         IncrementErrors(GenDb::IfErrors::ERR_READ_COLUMN);
    2869           0 :         return success;
    2870             :     }
    2871           0 :     IncrementTableReadStats(cfname);
    2872           0 :     return success;
    2873             : }
    2874             : 
    2875           7 : bool CqlIf::Db_GetMultiRow(GenDb::ColListVec *out, const std::string &cfname,
    2876             :     const std::vector<GenDb::DbDataValueVec> &v_rowkey) {
    2877        1007 :     BOOST_FOREACH(const GenDb::DbDataValueVec &rkey, v_rowkey) {
    2878         500 :         std::auto_ptr<GenDb::ColList> v_columns(new GenDb::ColList);
    2879             :         // Partition Key
    2880         500 :         v_columns->rowkey_ = rkey;
    2881        1000 :         bool success(impl_->SelectFromTableSync(cfname, rkey,
    2882         500 :             CASS_CONSISTENCY_ONE, &v_columns->columns_));
    2883         500 :         if (!success) {
    2884           0 :             CQLIF_ERR_TRACE("SELECT FROM Table: " << cfname << " Partition Key: "
    2885             :                 << GenDb::DbDataValueVecToString(rkey) << " FAILED");
    2886           0 :             IncrementTableReadFailStats(cfname);
    2887           0 :             IncrementErrors(GenDb::IfErrors::ERR_READ_COLUMN);
    2888           0 :             return false;
    2889             :         }
    2890         500 :         out->push_back(v_columns.release());
    2891         500 :     }
    2892           7 :     IncrementTableReadStats(cfname, v_rowkey.size());
    2893           7 :     return true;
    2894             : }
    2895             : 
    2896           0 : bool CqlIf::Db_GetMultiRow(GenDb::ColListVec *out, const std::string &cfname,
    2897             :     const std::vector<GenDb::DbDataValueVec> &v_rowkey,
    2898             :     const GenDb::ColumnNameRange &crange) {
    2899           0 :     BOOST_FOREACH(const GenDb::DbDataValueVec &rkey, v_rowkey) {
    2900           0 :         std::auto_ptr<GenDb::ColList> v_columns(new GenDb::ColList);
    2901             :         // Partition Key
    2902           0 :         v_columns->rowkey_ = rkey;
    2903           0 :         bool success(impl_->SelectFromTableClusteringKeyRangeSync(cfname,
    2904           0 :             rkey, crange, CASS_CONSISTENCY_ONE, &v_columns->columns_));
    2905           0 :         if (!success) {
    2906           0 :             CQLIF_ERR_TRACE("SELECT FROM Table: " << cfname << " Partition Key: "
    2907             :                 << GenDb::DbDataValueVecToString(rkey) <<
    2908             :                 " Clustering Key Range: " << crange.ToString() << " FAILED");
    2909           0 :             IncrementTableReadFailStats(cfname);
    2910           0 :             IncrementErrors(GenDb::IfErrors::ERR_READ_COLUMN);
    2911           0 :             return false;
    2912             :         }
    2913           0 :         out->push_back(v_columns.release());
    2914           0 :     }
    2915           0 :     IncrementTableReadStats(cfname, v_rowkey.size());
    2916           0 :     return true;
    2917             : }
    2918             : 
    2919           0 : bool CqlIf::Db_GetMultiRow(GenDb::ColListVec *out, const std::string &cfname,
    2920             :     const std::vector<GenDb::DbDataValueVec> &v_rowkey,
    2921             :     const GenDb::ColumnNameRange &crange,
    2922             :     const GenDb::FieldNamesToReadVec &read_vec,
    2923             :     GenDb::DbConsistency::type dconsistency) {
    2924           0 :     CassConsistency consistency(impl::Db2CassConsistency(dconsistency));
    2925           0 :     bool success(impl_->SelectFromTableClusteringKeyRangeFieldNamesSync(cfname,
    2926             :         v_rowkey, crange, consistency, read_vec, out));
    2927           0 :     if (!success) {
    2928           0 :         IncrementTableReadFailStats(cfname);
    2929           0 :         IncrementErrors(GenDb::IfErrors::ERR_READ_COLUMN);
    2930           0 :         return false;
    2931             :     }
    2932           0 :     IncrementTableReadStats(cfname, v_rowkey.size());
    2933           0 :     return true;
    2934             : }
    2935             : 
    2936           0 : bool CqlIf::Db_GetAllRows(GenDb::ColListVec *out, const std::string &cfname,
    2937             :     GenDb::DbConsistency::type dconsistency) {
    2938           0 :     CassConsistency consistency(impl::Db2CassConsistency(dconsistency));
    2939           0 :     bool success(impl_->SelectFromTableSync(cfname, consistency, out));
    2940           0 :     if (!success) {
    2941           0 :         IncrementTableReadFailStats(cfname);
    2942           0 :         IncrementErrors(GenDb::IfErrors::ERR_READ_COLUMN);
    2943           0 :         return success;
    2944             :     }
    2945           0 :     IncrementTableReadStats(cfname);
    2946           0 :     return success;
    2947             : }
    2948             : 
    2949             : // Queue
    2950           0 : bool CqlIf::Db_GetQueueStats(uint64_t *queue_count,
    2951             :         uint64_t *enqueues) const {
    2952             :     //return impl_->Db_GetQueueStats(queue_count, enqueues);
    2953           0 :     return true;
    2954             : }
    2955             : 
    2956           0 : void CqlIf::Db_SetQueueWaterMark(bool high, size_t queue_count,
    2957             :         GenDb::GenDbIf::DbQueueWaterMarkCb cb) {
    2958             :     //impl_->Db_SetQueueWaterMark(high, queue_count, cb);
    2959           0 : }
    2960             : 
    2961           0 : void CqlIf::Db_ResetQueueWaterMarks() {
    2962             :     //impl_->Db_ResetQueueWaterMarks();
    2963           0 : }
    2964             : 
    2965             : // Stats
    2966          23 : bool CqlIf::Db_GetStats(std::vector<GenDb::DbTableInfo> *vdbti,
    2967             :         GenDb::DbErrors *dbe) {
    2968          23 :     std::scoped_lock lock(stats_mutex_);
    2969          23 :     stats_.GetDiffs(vdbti, dbe);
    2970          23 :     return true;
    2971          23 : }
    2972             : 
    2973           4 : bool CqlIf::Db_GetCumulativeStats(std::vector<GenDb::DbTableInfo> *vdbti,
    2974             :         GenDb::DbErrors *dbe) const {
    2975           4 :     std::scoped_lock lock(stats_mutex_);
    2976           4 :     stats_.GetCumulative(vdbti, dbe);
    2977           4 :     return true;
    2978           4 : }
    2979             : 
    2980           4 : bool CqlIf::Db_GetCqlMetrics(Metrics *metrics) const {
    2981           4 :     return impl_->GetMetrics(metrics);
    2982             : }
    2983             : 
    2984          23 : bool CqlIf::Db_GetCqlStats(DbStats *db_stats) const {
    2985          23 :     Metrics metrics;
    2986          23 :     bool success(impl_->GetMetrics(&metrics));
    2987          23 :     if (!success) {
    2988           0 :         return success;
    2989             :     }
    2990          23 :     db_stats->requests_one_minute_rate = metrics.requests.one_minute_rate;
    2991          23 :     db_stats->stats = metrics.stats;
    2992          23 :     db_stats->errors = metrics.errors;
    2993          23 :     return success;
    2994          23 : }
    2995             : 
    2996           0 : void CqlIf::IncrementTableWriteStats(const std::string &table_name) {
    2997           0 :     std::scoped_lock lock(stats_mutex_);
    2998           0 :     stats_.IncrementTableWrite(table_name);
    2999           0 : }
    3000             : 
    3001           0 : void CqlIf::IncrementTableWriteStats(const std::string &table_name,
    3002             :     uint64_t num_writes) {
    3003           0 :     std::scoped_lock lock(stats_mutex_);
    3004           0 :     stats_.IncrementTableWrite(table_name, num_writes);
    3005           0 : }
    3006             : 
    3007           0 : void CqlIf::IncrementTableWriteFailStats(const std::string &table_name) {
    3008           0 :     std::scoped_lock lock(stats_mutex_);
    3009           0 :     stats_.IncrementTableWriteFail(table_name);
    3010           0 : }
    3011             : 
    3012           0 : void CqlIf::IncrementTableWriteFailStats(const std::string &table_name,
    3013             :     uint64_t num_writes) {
    3014           0 :     std::scoped_lock lock(stats_mutex_);
    3015           0 :     stats_.IncrementTableWriteFail(table_name, num_writes);
    3016           0 : }
    3017             : 
    3018           0 : void CqlIf::IncrementTableWriteBackPressureFailStats(
    3019             :     const std::string &table_name) {
    3020           0 :     std::scoped_lock lock(stats_mutex_);
    3021           0 :     stats_.IncrementTableWriteBackPressureFail(table_name);
    3022           0 : }
    3023             : 
    3024           0 : void CqlIf::IncrementTableReadBackPressureFailStats(
    3025             :     const std::string &table_name) {
    3026           0 :     std::scoped_lock lock(stats_mutex_);
    3027           0 :     stats_.IncrementTableReadBackPressureFail(table_name);
    3028           0 : }
    3029             : 
    3030      108280 : void CqlIf::IncrementTableReadStats(const std::string &table_name) {
    3031      108280 :     std::scoped_lock lock(stats_mutex_);
    3032      108342 :     stats_.IncrementTableRead(table_name);
    3033      108342 : }
    3034             : 
    3035           7 : void CqlIf::IncrementTableReadStats(const std::string &table_name,
    3036             :     uint64_t num_reads) {
    3037           7 :     std::scoped_lock lock(stats_mutex_);
    3038           7 :     stats_.IncrementTableRead(table_name, num_reads);
    3039           7 : }
    3040             : 
    3041          25 : void CqlIf::IncrementTableReadFailStats(const std::string &table_name) {
    3042          25 :     std::scoped_lock lock(stats_mutex_);
    3043          25 :     stats_.IncrementTableReadFail(table_name);
    3044          25 : }
    3045             : 
    3046           0 : void CqlIf::IncrementTableReadFailStats(const std::string &table_name,
    3047             :     uint64_t num_reads) {
    3048           0 :     std::scoped_lock lock(stats_mutex_);
    3049           0 :     stats_.IncrementTableReadFail(table_name, num_reads);
    3050           0 : }
    3051             : 
    3052          25 : void CqlIf::IncrementErrors(GenDb::IfErrors::Type err_type) {
    3053          25 :     std::scoped_lock lock(stats_mutex_);
    3054          25 :     stats_.IncrementErrors(err_type);
    3055          25 : }
    3056             : 
    3057             : // Connection
    3058          25 : std::vector<GenDb::Endpoint> CqlIf::Db_GetEndpoints() const {
    3059          25 :     return endpoints_;
    3060             : }
    3061             : 
    3062             : namespace interface {
    3063             : 
    3064             : //
    3065             : // CassDatastaxLibrary
    3066             : //
    3067        3703 : CassDatastaxLibrary::CassDatastaxLibrary() {
    3068        3703 : }
    3069             : 
    3070        7406 : CassDatastaxLibrary::~CassDatastaxLibrary() {
    3071        7406 : }
    3072             : 
    3073             : // CassCluster
    3074        3703 : CassCluster* CassDatastaxLibrary::CassClusterNew() {
    3075        3703 :     return cass_cluster_new();
    3076             : }
    3077             : 
    3078        3703 : void CassDatastaxLibrary::CassClusterFree(CassCluster* cluster) {
    3079        3703 :     cass_cluster_free(cluster);
    3080        3703 : }
    3081             : 
    3082        3703 : CassError CassDatastaxLibrary::CassClusterSetContactPoints(
    3083             :     CassCluster* cluster, const char* contact_points) {
    3084        3703 :     return cass_cluster_set_contact_points(cluster, contact_points);
    3085             : }
    3086             : 
    3087        3703 : CassError CassDatastaxLibrary::CassClusterSetPort(CassCluster* cluster,
    3088             :     int port) {
    3089        3703 :     return cass_cluster_set_port(cluster, port);
    3090             : }
    3091             : 
    3092           0 : void CassDatastaxLibrary::CassClusterSetSsl(CassCluster* cluster, CassSsl* ssl) {
    3093           0 :     cass_cluster_set_ssl(cluster, ssl);
    3094           0 : }
    3095             : 
    3096           0 : void CassDatastaxLibrary::CassClusterSetCredentials(CassCluster* cluster,
    3097             :     const char* username, const char* password) {
    3098           0 :     cass_cluster_set_credentials(cluster, username, password);
    3099           0 : }
    3100             : 
    3101        3703 : CassError CassDatastaxLibrary::CassClusterSetNumThreadsIo(CassCluster* cluster,
    3102             :     unsigned num_threads) {
    3103        3703 :     return cass_cluster_set_num_threads_io(cluster, num_threads);
    3104             : }
    3105             : 
    3106        3703 : CassError CassDatastaxLibrary::CassClusterSetPendingRequestsHighWaterMark(
    3107             :     CassCluster* cluster, unsigned num_requests) {
    3108        3703 :     return cass_cluster_set_pending_requests_high_water_mark(cluster,
    3109        3703 :         num_requests);
    3110             : }
    3111             : 
    3112        3703 : CassError CassDatastaxLibrary::CassClusterSetPendingRequestsLowWaterMark(
    3113             :     CassCluster* cluster, unsigned num_requests) {
    3114        3703 :     return cass_cluster_set_pending_requests_low_water_mark(cluster,
    3115        3703 :         num_requests);
    3116             : }
    3117             : 
    3118        3703 : CassError CassDatastaxLibrary::CassClusterSetWriteBytesHighWaterMark(
    3119             :     CassCluster* cluster, unsigned num_bytes) {
    3120        3703 :     return cass_cluster_set_write_bytes_high_water_mark(cluster, num_bytes);
    3121             : }
    3122             : 
    3123        3703 : CassError CassDatastaxLibrary::CassClusterSetWriteBytesLowWaterMark(
    3124             :     CassCluster* cluster, unsigned num_bytes) {
    3125        3703 :     return cass_cluster_set_write_bytes_low_water_mark(cluster, num_bytes);
    3126             : }
    3127             : 
    3128           0 : void CassDatastaxLibrary::CassClusterSetWhitelistFiltering(
    3129             :     CassCluster* cluster, const char* hosts) {
    3130           0 :     cass_cluster_set_whitelist_filtering(cluster, hosts);
    3131           0 : }
    3132             : 
    3133             : // CassSsl
    3134           0 : CassSsl* CassDatastaxLibrary::CassSslNew() {
    3135           0 :     return cass_ssl_new();
    3136             : }
    3137             : 
    3138           0 : void CassDatastaxLibrary::CassSslFree(CassSsl* ssl) {
    3139           0 :     return cass_ssl_free(ssl);
    3140             : }
    3141             : 
    3142           0 : CassError CassDatastaxLibrary::CassSslAddTrustedCert(CassSsl* ssl,
    3143             :     const std::string &cert) {
    3144           0 :     return cass_ssl_add_trusted_cert_n(ssl, cert.c_str(), cert.length());
    3145             : }
    3146             : 
    3147           0 : void CassDatastaxLibrary::CassSslSetVerifyFlags(CassSsl* ssl, int flags) {
    3148           0 :     cass_ssl_set_verify_flags(ssl, flags);
    3149           0 : }
    3150             : 
    3151             : // CassSession
    3152        7431 : CassSession* CassDatastaxLibrary::CassSessionNew() {
    3153        7431 :     return cass_session_new();
    3154             : }
    3155             : 
    3156        7431 : void CassDatastaxLibrary::CassSessionFree(CassSession* session) {
    3157        7431 :     cass_session_free(session);
    3158        7431 : }
    3159             : 
    3160           0 : void CassDatastaxLibrary::CassClusterSetRequestTimeout(CassCluster* cluster,
    3161             :     unsigned timeout_ms) {
    3162           0 :     return cass_cluster_set_request_timeout(cluster, timeout_ms);
    3163             : }
    3164             : 
    3165          25 : CassFuture* CassDatastaxLibrary::CassSessionConnect(CassSession* session,
    3166             :     const CassCluster* cluster) {
    3167          25 :     return cass_session_connect(session, cluster);
    3168             : }
    3169             : 
    3170          25 : CassFuture* CassDatastaxLibrary::CassSessionClose(CassSession* session) {
    3171          25 :     return cass_session_close(session);
    3172             : }
    3173             : 
    3174      108698 : CassFuture* CassDatastaxLibrary::CassSessionExecute(CassSession* session,
    3175             :     const CassStatement* statement) {
    3176      108698 :     return cass_session_execute(session, statement);
    3177             : }
    3178             : 
    3179      325903 : const CassSchemaMeta* CassDatastaxLibrary::CassSessionGetSchemaMeta(
    3180             :     const CassSession* session) {
    3181      325903 :     return cass_session_get_schema_meta(session);
    3182             : }
    3183             : 
    3184           0 : CassFuture* CassDatastaxLibrary::CassSessionPrepare(CassSession* session,
    3185             :     const char* query) {
    3186           0 :     return cass_session_prepare(session, query);
    3187             : }
    3188             : 
    3189          27 : void CassDatastaxLibrary::CassSessionGetMetrics(const CassSession* session,
    3190             :     CassMetrics* output) {
    3191          27 :     cass_session_get_metrics(session, output);
    3192          27 : }
    3193             : 
    3194             : // CassSchema
    3195      326459 : void CassDatastaxLibrary::CassSchemaMetaFree(
    3196             :     const CassSchemaMeta* schema_meta) {
    3197      326459 :     cass_schema_meta_free(schema_meta);
    3198      326645 : }
    3199             : 
    3200      326245 : const CassKeyspaceMeta* CassDatastaxLibrary::CassSchemaMetaKeyspaceByName(
    3201             :     const CassSchemaMeta* schema_meta, const char* keyspace) {
    3202      326245 :     return cass_schema_meta_keyspace_by_name(schema_meta, keyspace);
    3203             : }
    3204             : 
    3205      326129 : const CassTableMeta* CassDatastaxLibrary::CassKeyspaceMetaTableByName(
    3206             :     const CassKeyspaceMeta* keyspace_meta, const char* table) {
    3207      326129 :     return cass_keyspace_meta_table_by_name(keyspace_meta, table);
    3208             : }
    3209             : 
    3210      108675 : size_t CassDatastaxLibrary::CassTableMetaPartitionKeyCount(
    3211             :     const CassTableMeta* table_meta) {
    3212      108675 :     return cass_table_meta_partition_key_count(table_meta);
    3213             : }
    3214             : 
    3215      217761 : size_t CassDatastaxLibrary::CassTableMetaClusteringKeyCount(
    3216             :     const CassTableMeta* table_meta) {
    3217      217761 :     return cass_table_meta_clustering_key_count(table_meta);
    3218             : }
    3219             : 
    3220             : // CassFuture
    3221      108766 : void CassDatastaxLibrary::CassFutureFree(CassFuture* future) {
    3222      108766 :     cass_future_free(future);
    3223      108786 : }
    3224             : 
    3225      107962 : CassError CassDatastaxLibrary::CassFutureSetCallback(CassFuture* future,
    3226             :     CassFutureCallback callback, void* data) {
    3227      107962 :     return cass_future_set_callback(future, callback, data);
    3228             : }
    3229             : 
    3230         600 : void CassDatastaxLibrary::CassFutureWait(CassFuture* future) {
    3231         600 :     cass_future_wait(future);
    3232         600 : }
    3233             : 
    3234      108709 : const CassResult* CassDatastaxLibrary::CassFutureGetResult(
    3235             :     CassFuture* future) {
    3236      108709 :     return cass_future_get_result(future);
    3237             : }
    3238             : 
    3239           0 : void CassDatastaxLibrary::CassFutureErrorMessage(CassFuture* future,
    3240             :     const char** message, size_t* message_length) {
    3241           0 :     cass_future_error_message(future, message, message_length);
    3242           0 : }
    3243             : 
    3244      108777 : CassError CassDatastaxLibrary::CassFutureErrorCode(CassFuture* future) {
    3245      108777 :     return cass_future_error_code(future);
    3246             : }
    3247             : 
    3248           0 : const CassPrepared* CassDatastaxLibrary::CassFutureGetPrepared(
    3249             :     CassFuture* future) {
    3250           0 :     return cass_future_get_prepared(future);
    3251             : }
    3252             : 
    3253             : // CassResult
    3254      108715 : void CassDatastaxLibrary::CassResultFree(const CassResult* result) {
    3255      108715 :     cass_result_free(result);
    3256      108716 : }
    3257             : 
    3258      112936 : size_t CassDatastaxLibrary::CassResultColumnCount(const CassResult* result) {
    3259      112936 :     return cass_result_column_count(result);
    3260             : }
    3261             : 
    3262         225 : CassError CassDatastaxLibrary::CassResultColumnName(const CassResult *result,
    3263             :     size_t index, const char** name, size_t* name_length) {
    3264         225 :     return cass_result_column_name(result, index, name, name_length);
    3265             : }
    3266             : 
    3267             : // CassIterator
    3268      108708 : void CassDatastaxLibrary::CassIteratorFree(CassIterator* iterator) {
    3269      108708 :     cass_iterator_free(iterator);
    3270      108660 : }
    3271             : 
    3272      108662 : CassIterator* CassDatastaxLibrary::CassIteratorFromResult(
    3273             :     const CassResult* result) {
    3274      108662 :     return cass_iterator_from_result(result);
    3275             : }
    3276             : 
    3277      113445 : cass_bool_t CassDatastaxLibrary::CassIteratorNext(CassIterator* iterator) {
    3278      113445 :     return cass_iterator_next(iterator);
    3279             : }
    3280             : 
    3281        4759 : const CassRow* CassDatastaxLibrary::CassIteratorGetRow(
    3282             :     const CassIterator* iterator) {
    3283        4759 :     return cass_iterator_get_row(iterator);
    3284             : }
    3285             : 
    3286             : // CassStatement
    3287      108339 : CassStatement* CassDatastaxLibrary::CassStatementNew(const char* query,
    3288             :     size_t parameter_count) {
    3289      108339 :     return cass_statement_new(query, parameter_count);
    3290             : }
    3291             : 
    3292      108682 : void CassDatastaxLibrary::CassStatementFree(CassStatement* statement) {
    3293      108682 :     cass_statement_free(statement);
    3294      108735 : }
    3295             : 
    3296      108671 : CassError CassDatastaxLibrary::CassStatementSetConsistency(
    3297             :     CassStatement* statement, CassConsistency consistency) {
    3298      108671 :     return cass_statement_set_consistency(statement, consistency);
    3299             : }
    3300             : 
    3301           0 : CassError CassDatastaxLibrary::CassStatementBindStringN(
    3302             :     CassStatement* statement,
    3303             :     size_t index, const char* value, size_t value_length) {
    3304           0 :     return cass_statement_bind_string_n(statement, index, value, value_length);
    3305             : }
    3306             : 
    3307           0 : CassError CassDatastaxLibrary::CassStatementBindInt32(CassStatement* statement,
    3308             :     size_t index, cass_int32_t value) {
    3309           0 :     return cass_statement_bind_int32(statement, index, value);
    3310             : }
    3311             : 
    3312           0 : CassError CassDatastaxLibrary::CassStatementBindInt64(CassStatement* statement,
    3313             :     size_t index, cass_int64_t value) {
    3314           0 :     return cass_statement_bind_int64(statement, index, value);
    3315             : }
    3316             : 
    3317           0 : CassError CassDatastaxLibrary::CassStatementBindUuid(CassStatement* statement,
    3318             :     size_t index, CassUuid value) {
    3319           0 :     return cass_statement_bind_uuid(statement, index, value);
    3320             : }
    3321             : 
    3322           0 : CassError CassDatastaxLibrary::CassStatementBindDouble(
    3323             :     CassStatement* statement, size_t index, cass_double_t value) {
    3324           0 :     return cass_statement_bind_double(statement, index, value);
    3325             : }
    3326             : 
    3327           0 : CassError CassDatastaxLibrary::CassStatementBindInet(CassStatement* statement,
    3328             :     size_t index, CassInet value) {
    3329           0 :     return cass_statement_bind_inet(statement, index, value);
    3330             : }
    3331             : 
    3332           0 : CassError CassDatastaxLibrary::CassStatementBindBytes(
    3333             :     CassStatement* statement,
    3334             :     size_t index, const cass_byte_t* value, size_t value_length) {
    3335           0 :     return cass_statement_bind_bytes(statement, index, value, value_length);
    3336             : }
    3337             : 
    3338           0 : CassError CassDatastaxLibrary::CassStatementBindStringByNameN(
    3339             :     CassStatement* statement,
    3340             :     const char* name, size_t name_length, const char* value,
    3341             :     size_t value_length) {
    3342           0 :     return cass_statement_bind_string_by_name_n(statement, name, name_length,
    3343           0 :         value, value_length);
    3344             : }
    3345             : 
    3346           0 : CassError CassDatastaxLibrary::CassStatementBindInt32ByName(
    3347             :     CassStatement* statement, const char* name, cass_int32_t value) {
    3348           0 :     return cass_statement_bind_int32_by_name(statement, name, value);
    3349             : }
    3350             : 
    3351           0 : CassError CassDatastaxLibrary::CassStatementBindInt64ByName(
    3352             :     CassStatement* statement, const char* name, cass_int64_t value) {
    3353           0 :     return cass_statement_bind_int64_by_name(statement, name, value);
    3354             : }
    3355             : 
    3356           0 : CassError CassDatastaxLibrary::CassStatementBindUuidByName(
    3357             :     CassStatement* statement, const char* name, CassUuid value) {
    3358           0 :     return cass_statement_bind_uuid_by_name(statement, name, value);
    3359             : }
    3360             : 
    3361           0 : CassError CassDatastaxLibrary::CassStatementBindDoubleByName(
    3362             :     CassStatement* statement, const char* name, cass_double_t value) {
    3363           0 :     return cass_statement_bind_double_by_name(statement, name, value);
    3364             : }
    3365             : 
    3366           0 : CassError CassDatastaxLibrary::CassStatementBindInetByName(
    3367             :     CassStatement* statement, const char* name, CassInet value) {
    3368           0 :     return cass_statement_bind_inet_by_name(statement, name, value);
    3369             : }
    3370             : 
    3371           0 : CassError CassDatastaxLibrary::CassStatementBindBytesByNameN(
    3372             :     CassStatement* statement,
    3373             :     const char* name, size_t name_length, const cass_byte_t* value,
    3374             :     size_t value_length) {
    3375           0 :     return cass_statement_bind_bytes_by_name_n(statement, name, name_length,
    3376           0 :         value, value_length);
    3377             : }
    3378             : 
    3379             : // CassPrepare
    3380           0 : void CassDatastaxLibrary::CassPreparedFree(const CassPrepared* prepared) {
    3381           0 :     cass_prepared_free(prepared);
    3382           0 : }
    3383             : 
    3384           0 : CassStatement* CassDatastaxLibrary::CassPreparedBind(
    3385             :     const CassPrepared* prepared)  {
    3386           0 :     return cass_prepared_bind(prepared);
    3387             : }
    3388             : 
    3389             : // CassValue
    3390       67691 : CassValueType CassDatastaxLibrary::GetCassValueType(const CassValue* value) {
    3391       67691 :     return cass_value_type(value);
    3392             : }
    3393             : 
    3394       41514 : CassError CassDatastaxLibrary::CassValueGetString(const CassValue* value,
    3395             :     const char** output, size_t* output_size) {
    3396       41514 :     return cass_value_get_string(value, output, output_size);
    3397             : }
    3398             : 
    3399           0 : CassError CassDatastaxLibrary::CassValueGetInt8(const CassValue* value,
    3400             :     cass_int8_t* output) {
    3401           0 :     return cass_value_get_int8(value, output);
    3402             : }
    3403             : 
    3404           0 : CassError CassDatastaxLibrary::CassValueGetInt16(const CassValue* value,
    3405             :     cass_int16_t* output) {
    3406           0 :     return cass_value_get_int16(value, output);
    3407             : }
    3408             : 
    3409       17736 : CassError CassDatastaxLibrary::CassValueGetInt32(const CassValue* value,
    3410             :     cass_int32_t* output) {
    3411       17736 :     return cass_value_get_int32(value, output);
    3412             : }
    3413             : 
    3414        3464 : CassError CassDatastaxLibrary::CassValueGetInt64(const CassValue* value,
    3415             :     cass_int64_t* output) {
    3416        3464 :     return cass_value_get_int64(value, output);
    3417             : }
    3418             : 
    3419        4571 : CassError CassDatastaxLibrary::CassValueGetUuid(const CassValue* value,
    3420             :     CassUuid* output) {
    3421        4571 :     return cass_value_get_uuid(value, output);
    3422             : }
    3423             : 
    3424           0 : CassError CassDatastaxLibrary::CassValueGetDouble(const CassValue* value,
    3425             :     cass_double_t* output) {
    3426           0 :     return cass_value_get_double(value, output);
    3427             : }
    3428             : 
    3429         408 : CassError CassDatastaxLibrary::CassValueGetInet(const CassValue* value,
    3430             :     CassInet* output) {
    3431         408 :     return cass_value_get_inet(value, output);
    3432             : }
    3433             :     
    3434           0 : CassError CassDatastaxLibrary::CassValueGetBytes(const CassValue* value,
    3435             :     const cass_byte_t** output, size_t* output_size) {
    3436           0 :     return cass_value_get_bytes(value, output, output_size);
    3437             : }
    3438             : 
    3439       96340 : cass_bool_t CassDatastaxLibrary::CassValueIsNull(const CassValue* value) {
    3440       96340 :     return cass_value_is_null(value);
    3441             : }
    3442             : 
    3443             : // CassInet
    3444           0 : CassInet CassDatastaxLibrary::CassInetInitV4(
    3445             :     const cass_uint8_t* address) {
    3446           0 :     return cass_inet_init_v4(address);
    3447             : }
    3448             : 
    3449           0 : CassInet CassDatastaxLibrary::CassInetInitV6(
    3450             :     const cass_uint8_t* address) {
    3451           0 :     return cass_inet_init_v6(address);
    3452             : }
    3453             : 
    3454             : // CassRow
    3455       96340 : const CassValue* CassDatastaxLibrary::CassRowGetColumn(const CassRow* row,
    3456             :     size_t index) {
    3457       96340 :     return cass_row_get_column(row, index);
    3458             : }
    3459             : 
    3460             : // CassLog
    3461        3703 : void CassDatastaxLibrary::CassLogSetLevel(CassLogLevel log_level) {
    3462        3703 :     cass_log_set_level(log_level);
    3463        3703 : }
    3464             : 
    3465        3703 : void CassDatastaxLibrary::CassLogSetCallback(CassLogCallback callback,
    3466             :     void* data) {
    3467        3703 :     cass_log_set_callback(callback, data);
    3468        3703 : }
    3469             : 
    3470             : }  // namespace interface
    3471             : }  // namespace cql
    3472             : }  // namespace cass

Generated by: LCOV version 1.14