void DbCassandra::Initialize( const std::string &configPath ) { ParseConfig( configPath ); const std::string remotes = config_.get<std::string>( "remotes" ); db_ = std::make_shared<DbConnection>(); auto cluster = cass_cluster_new(); db_->SetCluster( cluster ); auto session = cass_session_new(); db_->SetSession( session ); cass_cluster_set_contact_points( cluster, remotes.c_str() ); CassFuture *connect_future = cass_session_connect( session, cluster ); const CassError err = cass_future_error_code( connect_future ); cass_future_free( connect_future ); if ( err != CASS_OK ) throw std::logic_error( cass_error_desc( err ) ); const CassPrepared *prepared = nullptr; if ( PrepareQuery( session, "INSERT INTO prun.jobs (job_id, job_descr) VALUES (?, ?);", reinterpret_cast<const CassPrepared**>( &prepared ) ) != CASS_OK ) throw std::logic_error( cass_error_desc( err ) ); db_->SetPreparedInsert( prepared ); if ( PrepareQuery( session, "DELETE FROM prun.jobs WHERE job_id = ?;", reinterpret_cast<const CassPrepared**>( &prepared ) ) != CASS_OK ) throw std::logic_error( cass_error_desc( err ) ); db_->SetPreparedDelete( prepared ); }
static int cassandra_results_stream_end_of_stream(void* context) { cassandra_results_stream* scontext; scontext = (cassandra_results_stream*)context; if (scontext->at_end) { if (scontext->more_pages) { CassError rc; rc = cass_statement_set_paging_state(scontext->stmt, scontext->result); if (rc != CASS_OK) { fprintf(stderr, "Cassandra: %s\n", cass_error_desc(rc)); return -1; } cass_result_free(scontext->result); scontext->result = 0; CassFuture* future = cass_session_execute(scontext->cassandra_context->session, scontext->stmt); rc = cass_future_error_code(future); if (rc != CASS_OK) { fprintf(stderr, "Cassandra: %s\n", cass_error_desc(rc)); const char* msg; size_t msg_len; cass_future_error_message(future, &msg, &msg_len); fprintf(stderr, "Cassandra: %*s\n", msg_len, msg); cass_future_free(future); return -1; } scontext->result = cass_future_get_result(future); cass_future_free(future); scontext->iter = cass_iterator_from_result(scontext->result); scontext->more_pages = cass_result_has_more_pages(scontext->result); scontext->at_end = !cass_iterator_next(scontext->iter); } } return (scontext->at_end); }
/** * Perform query operations using each session in multiple threads * * @param sessions Session container for closing sessions */ void query_sessions(const SessionContainer& sessions) { //Query session in multiple threads unsigned int thread_count = sessions.count() * SESSION_STRESS_NUMBER_OF_SHARED_SESSION_THREADS; BOOST_TEST_MESSAGE("\t\tThreads: " << thread_count); std::vector<uv_thread_t> threads(thread_count); std::vector<QuerySession> queries(thread_count); for (unsigned int iterations = 0; iterations < SESSION_STRESS_NUMBER_OF_SHARED_SESSION_THREADS; ++iterations) { for (unsigned int n = 0; n < sessions.count(); ++n) { int thread_index = (sessions.count() * iterations) + n; queries.push_back(QuerySession(sessions.sessions[n].get())); uv_thread_create(&threads[thread_index], query_session, &queries.back()); } } //Ensure all threads have completed for (unsigned int n = 0; n < thread_count; ++n) { uv_thread_join(&threads[n]); } for (unsigned int n = 0; n < thread_count; ++n) { //Timeouts are OK (especially on the minor chaos test) CassError error_code = queries[n].error_code; if (error_code != CASS_OK && error_code != CASS_ERROR_LIB_REQUEST_TIMED_OUT) { BOOST_FAIL("Error occurred during query '" << std::string(cass_error_desc(error_code))); } } }
const CassResult* Connection::execute(CassStatement* statement) { this->log("debug", "Connection::execute"); CassFuture* result = cass_session_execute(this->_session, statement); CassError error = cass_future_error_code(result); if (error != CASS_OK) { CassString message = cass_future_error_message(result); cass_future_free(result); std::ostringstream out; out << cass_error_desc(error) << ": " << message.data; this->log("error", out.str()); throw Php::Exception(out.str()); return nullptr; } const CassResult* res = cass_future_get_result(result); if (res == nullptr) { throw Php::Exception("Error executing query, result is null"); } cass_future_free(result); return res; }
int load_trusted_cert_file(const char* file, CassSsl* ssl) { CassError rc; char* cert; long cert_size; size_t bytes_read; FILE *in = fopen(file, "rb"); if (in == NULL) { fprintf(stderr, "Error loading certificate file '%s'\n", file); return 0; } fseek(in, 0, SEEK_END); cert_size = ftell(in); rewind(in); cert = (char*)malloc(cert_size); bytes_read = fread(cert, 1, cert_size, in); fclose(in); if (bytes_read == (size_t) cert_size) { rc = cass_ssl_add_trusted_cert_n(ssl, cert, cert_size); if (rc != CASS_OK) { fprintf(stderr, "Error loading SSL certificate: %s\n", cass_error_desc(rc)); free(cert); return 0; } } free(cert); return 1; }
static int execute(CassSession* session, char* query, int ignore_error) { CassStatement* stmt = cass_statement_new(query, 0); CassFuture* future = cass_session_execute(session, stmt); cass_statement_free(stmt); CassError rc = cass_future_error_code(future); if (rc != CASS_OK) { if (ignore_error) { cass_future_free(future); return 0; } fprintf(stderr, "Cassandra error: %s\n", cass_error_desc(rc)); cass_future_free(future); return -1; } cass_future_free(future); return 0; }
/** * librdf_storage_cassandra_context_add_statement: * @storage: #librdf_storage object * @context_node: #librdf_node object * @statement: #librdf_statement statement to add * * Add a statement to a storage context. * * Return value: non 0 on failure **/ static int librdf_storage_cassandra_context_add_statement(librdf_storage* storage, librdf_node* context_node, librdf_statement* statement) { char* s; char* p; char* o; char* c; statement_helper(storage, statement, context_node, &s, &p, &o, &c); librdf_storage_cassandra_instance* context; context = (librdf_storage_cassandra_instance*)storage->instance; char* query = "BEGIN BATCH " " INSERT INTO rdf.spo (s, p, o) VALUES (?, ?, ?);" " INSERT INTO rdf.pos (s, p, o) VALUES (?, ?, ?);" " INSERT INTO rdf.osp (s, p, o) VALUES (?, ?, ?);" "APPLY BATCH;"; CassStatement* stmt = cass_statement_new(query, 9); cass_statement_bind_string(stmt, 0, s); cass_statement_bind_string(stmt, 1, p); cass_statement_bind_string(stmt, 2, o); cass_statement_bind_string(stmt, 3, s); cass_statement_bind_string(stmt, 4, p); cass_statement_bind_string(stmt, 5, o); cass_statement_bind_string(stmt, 6, s); cass_statement_bind_string(stmt, 7, p); cass_statement_bind_string(stmt, 8, o); if (s) free(s); if (p) free(p); if (o) free(o); CassFuture* future = cass_session_execute(context->session, stmt); cass_statement_free(stmt); CassError rc = cass_future_error_code(future); if (rc != CASS_OK) { fprintf(stderr, "Cassandra: %s\n", cass_error_desc(rc)); const char* msg; size_t msg_len; cass_future_error_message(future, &msg, &msg_len); fprintf(stderr, "Cassandra: %*s\n", msg_len, msg); cass_future_free(future); return -1; } cass_future_free(future); return 0; }
void DbCassandra::Delete( const std::string &key ) { DbPtr db = db_; if ( db ) { auto statement = cass_prepared_bind( db_->GetPreparedDelete() ); cass_statement_bind_string( statement, 0, key.c_str() ); auto query_future = cass_session_execute( db_->GetSession(), statement ); cass_statement_free( statement ); CassError err = cass_future_error_code( query_future ); cass_future_free( query_future ); if ( err != CASS_OK ) throw std::logic_error( cass_error_desc( err ) ); } }
/** * Create the session * * @param is_timeout True if for timeout tests; false otherwise */ void create_session(bool is_timeout = false) { close_session(); test_utils::CassSessionPtr session(cass_session_new()); test_utils::CassFuturePtr connect_future(cass_session_connect(session.get(), cluster_.get())); CassError error_code = test_utils::wait_and_return_error(connect_future.get()); session_ = test_utils::create_session(cluster_.get(), &error_code); if (error_code != CASS_OK) { if (is_timeout) { if (error_code == CASS_ERROR_LIB_NO_HOSTS_AVAILABLE) { return; } } CassString message; cass_future_error_message(connect_future.get(), &message.data, &message.length); BOOST_FAIL(std::string(message.data, message.length) << "' (" << cass_error_desc(error_code) << ")"); } }
static int librdf_storage_cassandra_size(librdf_storage* storage) { librdf_storage_cassandra_instance* context; context = (librdf_storage_cassandra_instance*)storage->instance; char* query = "SELECT count(s) FROM rdf.spo"; CassStatement* stmt = cass_statement_new(query, 0); CassFuture* future = cass_session_execute(context->session, stmt); cass_statement_free(stmt); CassError rc = cass_future_error_code(future); if (rc != CASS_OK) { fprintf(stderr, "Cassandra: %s\n", cass_error_desc(rc)); const char* msg; size_t msg_len; cass_future_error_message(future, &msg, &msg_len); fprintf(stderr, "Cassandra: %*s\n", msg_len, msg); cass_future_free(future); return 0; } const CassResult* result = cass_future_get_result(future); cass_future_free(future); const CassRow* row = cass_result_first_row(result); int64_t count; cass_value_get_int64(cass_row_get_column(row, 0), &count); cass_result_free(result); return count; }
void DbCassandra::GetAll( GetCallback callback ) { DbPtr db = db_; if ( db ) { auto statement = cass_statement_new( "SELECT * FROM prun.jobs;", 0 ); auto query_future = cass_session_execute( db_->GetSession(), statement ); cass_statement_free( statement ); CassError err = cass_future_error_code( query_future ); if ( err != CASS_OK ) { cass_future_free( query_future ); throw std::logic_error( cass_error_desc( err ) ); } auto result = cass_future_get_result( query_future ); cass_future_free( query_future ); auto iterator = cass_iterator_from_result( result ); while( cass_iterator_next( iterator ) ) { const CassRow *row = cass_iterator_get_row( iterator ); const char *job_id, *job_descr; size_t job_id_length, job_descr_length; cass_value_get_string( cass_row_get_column( row, 0 ), &job_id, &job_id_length ); cass_value_get_string( cass_row_get_column( row, 1 ), &job_descr, &job_descr_length ); callback( std::string( job_id, job_id_length ), std::string( job_descr, job_descr_length ) ); } cass_iterator_free( iterator ); cass_result_free( result ); } }
/** * Get the human readable description of the error code * * @return Error description */ const std::string error_description() { return std::string(cass_error_desc(error_code())); }
static int librdf_storage_cassandra_add_statements(librdf_storage* storage, librdf_stream* statement_stream) { librdf_storage_cassandra_instance* context; context = (librdf_storage_cassandra_instance*)storage->instance; CassBatch* batch = 0; const int batch_size = 10; int rows = 0; for(; !librdf_stream_end(statement_stream); librdf_stream_next(statement_stream)) { librdf_statement* statement; librdf_node* context_node; statement = librdf_stream_get_object(statement_stream); context_node = librdf_stream_get_context2(statement_stream); if(!statement) { break; } char* s; char* p; char* o; char* c; statement_helper(storage, statement, context_node, &s, &p, &o, &c); if (batch == 0) batch = cass_batch_new(CASS_BATCH_TYPE_LOGGED); char* query = "INSERT INTO rdf.spo (s, p, o) VALUES (?, ?, ?);"; CassStatement* stmt = cass_statement_new(query, 3); cass_statement_bind_string(stmt, 0, s); cass_statement_bind_string(stmt, 1, p); cass_statement_bind_string(stmt, 2, o); cass_batch_add_statement(batch, stmt); cass_statement_free(stmt); query = "INSERT INTO rdf.pos (s, p, o) VALUES (?, ?, ?);"; stmt = cass_statement_new(query, 3); cass_statement_bind_string(stmt, 0, s); cass_statement_bind_string(stmt, 1, p); cass_statement_bind_string(stmt, 2, o); cass_batch_add_statement(batch, stmt); cass_statement_free(stmt); query = "INSERT INTO rdf.osp (s, p, o) VALUES (?, ?, ?);"; stmt = cass_statement_new(query, 3); cass_statement_bind_string(stmt, 0, s); cass_statement_bind_string(stmt, 1, p); cass_statement_bind_string(stmt, 2, o); cass_batch_add_statement(batch, stmt); cass_statement_free(stmt); free(s); free(p); free(o); if (++rows > batch_size) { CassFuture* future = cass_session_execute_batch(context->session, batch); cass_batch_free(batch); CassError rc = cass_future_error_code(future); if (rc != CASS_OK) { fprintf(stderr, "Cassandra: %s\n", cass_error_desc(rc)); const char* msg; size_t msg_len; cass_future_error_message(future, &msg, &msg_len); fprintf(stderr, "Cassandra: %*s\n", msg_len, msg); cass_future_free(future); return -1; } cass_future_free(future); batch = 0; } } if (batch) { CassFuture* future = cass_session_execute_batch(context->session, batch); cass_batch_free(batch); CassError rc = cass_future_error_code(future); if (rc != CASS_OK) { fprintf(stderr, "Cassandra: %s\n", cass_error_desc(rc)); const char* msg; size_t msg_len; cass_future_error_message(future, &msg, &msg_len); fprintf(stderr, "Cassandra: %*s\n", msg_len, msg); cass_future_free(future); return -1; } cass_future_free(future); } return 0; }
/* functions implementing storage api */ static int librdf_storage_cassandra_init(librdf_storage* storage, const char *name, librdf_hash* options) { char *name_copy; librdf_storage_cassandra_instance* context; if(!name) { if(options) librdf_free_hash(options); return 1; } context = LIBRDF_CALLOC(librdf_storage_cassandra_instance*, 1, sizeof(*context)); if(!context) { if(options) librdf_free_hash(options); return 1; } librdf_storage_set_instance(storage, context); context->storage = storage; context->name_len = strlen(name); // context->transaction = 0; name_copy = LIBRDF_MALLOC(char*, context->name_len + 1); if(!name_copy) { if(options) librdf_free_hash(options); return 1; } strcpy(name_copy, name); context->name = name_copy; // Add options here. /* no more options, might as well free them now */ if(options) librdf_free_hash(options); // FIXME: Hard-coded; context->session = cass_session_new(); context->cluster = cass_cluster_new(); cass_cluster_set_contact_points(context->cluster, name); CassFuture* future = cass_session_connect(context->session, context->cluster); CassError rc = cass_future_error_code(future); if (rc != CASS_OK) { fprintf(stderr, "Cassandra: %s\n", cass_error_desc(rc)); cass_cluster_free(context->cluster); cass_session_free(context->session); free(context->name); free(context); return 1; } cass_future_free(future); return 0; }
/** * librdf_storage_cassandra_find_statements: * @storage: the storage * @statement: the statement to match * * . * * Return a stream of statements matching the given statement (or * all statements if NULL). Parts (subject, predicate, object) of the * statement can be empty in which case any statement part will match that. * Uses #librdf_statement_match to do the matching. * * Return value: a #librdf_stream or NULL on failure **/ static librdf_stream* librdf_storage_cassandra_find_statements(librdf_storage* storage, librdf_statement* statement) { librdf_storage_cassandra_instance* context; cassandra_results_stream* scontext; librdf_stream* stream; char* s; char* p; char* o; char* c; context = (librdf_storage_cassandra_instance*)storage->instance; scontext = LIBRDF_CALLOC(cassandra_results_stream*, 1, sizeof(*scontext)); if(!scontext) return NULL; scontext->storage = storage; librdf_storage_add_reference(scontext->storage); scontext->cassandra_context = context; statement_helper(storage, statement, 0, &s, &p, &o, &c); #ifdef DEBUG fprintf(stderr, "Query: "); if (s) fprintf(stderr, "s=%s ", s); if (p) fprintf(stderr, "p=%s ", p); if (o) fprintf(stderr, "o=%s ", o); fprintf(stderr, "\n"); #endif typedef CassStatement* (*query_function)(const char* s, const char* p, const char* o); query_function functions[8] = { &cassandra_query_, /* ??? */ &cassandra_query_s, /* S?? */ &cassandra_query_p, /* ?P? */ &cassandra_query_sp, /* SP? */ &cassandra_query_o, /* ??O */ &cassandra_query_so, /* S?O */ &cassandra_query_po, /* ?PO */ &cassandra_query_spo /* SPO */ }; /* This creates an index into the function table, depending on input terms. */ int num = 0; if (o) num += 4; if (p) num += 2; if (s) num++; index_type tp; query_function fn = functions[num]; CassStatement* stmt = (*fn)(s, p, o); cass_statement_set_paging_size(stmt, 1000); if (s) free(s); if (p) free(p); if (o) free(o); CassFuture* future = cass_session_execute(context->session, stmt); CassError rc = cass_future_error_code(future); if (rc != CASS_OK) { fprintf(stderr, "Cassandra: %s\n", cass_error_desc(rc)); const char* msg; size_t msg_len; cass_future_error_message(future, &msg, &msg_len); fprintf(stderr, "Cassandra: %*s\n", msg_len, msg); cass_future_free(future); return 0; } const CassResult* result = cass_future_get_result(future); cass_future_free(future); CassIterator* iter = cass_iterator_from_result(result); scontext->stmt = stmt; scontext->result = result; scontext->iter = iter; scontext->more_pages = cass_result_has_more_pages(result); scontext->at_end = !cass_iterator_next(scontext->iter); stream = librdf_new_stream(storage->world, (void*)scontext, &cassandra_results_stream_end_of_stream, &cassandra_results_stream_next_statement, &cassandra_results_stream_get_statement, &cassandra_results_stream_finished); if(!stream) { cassandra_results_stream_finished((void*)scontext); return NULL; } return stream; }
inline CassError CassandraClient::printError(CassError error) { logger.warning(cass_error_desc(error)); return error; }