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

Generated by: LCOV version 1.14