MySQL NDB Cluster 8.1 手册
MySQL NDB Cluster 8.0 手册
NDB 集群内部机制手册
此示例说明了使用 NdbRecord
接口和 NdbScanOperation
从 NDB
表中检索一行或多行。我们假设您已经创建并填充了 basic
表,也许使用之前显示的行插入示例(参见 第 2.5.1.2 节,“NDB API 基本插入示例”)。
您也可以在文件 storage/ndb/ndbapi-examples/ndbapi_basic/ndbapi_basic_read.cpp
中找到此示例的源代码。
Press CTRL+C to copy#include <iostream> #include <cstdlib> #include <string> #include <iterator> #include <NdbApi.hpp> class BasicRead { public: BasicRead(const char *connectstring) : m_connection(connectstring), m_ndb(&m_connection, "ndbapi_examples") {} bool init(); bool do_read(); private: Ndb_cluster_connection m_connection; Ndb m_ndb; struct BasicRow { int attr1, attr2; }; inline bool on_error(const struct NdbError &error, const std::string &explanation) { // prints error in format: // ERROR <NdbErrorCode>: <NdbError message> // explanation what went wrong on higher level (in the example code) std::cout << "ERROR "<< error.code << ": " << error.message << std::endl; std::cout << explanation << std::endl; return false; } }; int main(int argc, char **argv) { if (argc != 2) { std::cout << "Usage: ndb_ndbapi_basic_read <connectstring>" << std::endl; return EXIT_FAILURE; } const char *connectstring = argv[1]; ndb_init(); { BasicRead example(connectstring); if (!example.init()) return EXIT_FAILURE; // Let's verify reads if (!example.do_read()) return EXIT_FAILURE; } ndb_end(0); return EXIT_SUCCESS; } bool BasicRead::do_read() { NdbDictionary::Dictionary *dict = m_ndb.getDictionary(); const NdbDictionary::Table *table = dict->getTable("basic"); if (table == nullptr) return on_error(dict->getNdbError(), "Cannot access table 'ndbapi_examples.basic'"); // Prepare record specification, // this will allow us later to access rows in the table // using our structure BasicRow NdbRecord* record; NdbDictionary::RecordSpecification record_spec[] = { { table->getColumn("ATTR1"), offsetof(BasicRow, attr1), 0, 0, 0 }, { table->getColumn("ATTR2"), offsetof(BasicRow, attr2), 0, 0, 0 } }; record = dict->createRecord(table, record_spec, std::size(record_spec), sizeof(record_spec[0])); if (record == nullptr) return on_error(dict->getNdbError(), "Failed to create record"); // All reads will be performed within single transaction NdbTransaction *transaction = m_ndb.startTransaction(table); if(transaction == nullptr) return on_error(m_ndb.getNdbError(), "Failed to start transaction"); // Note the usage of NdbScanOperation instead of regular NdbOperation NdbScanOperation *operation = transaction->scanTable(record); if(operation == nullptr) return on_error(transaction->getNdbError(), "Failed to start scanTable operation"); // Note the usage of NoCommit flag, as we are only reading the tuples if (transaction->execute(NdbTransaction::NoCommit) != 0) return on_error(transaction->getNdbError(), "Failed to execute transaction"); const BasicRow *row_ptr; int rc; std::cout << "ATTR1" << "\t" << "ATTR2" << std::endl; // Loop over all read results to print them while ((rc = operation->nextResult(reinterpret_cast<const char **>(&row_ptr), true, false)) == 0) std::cout << row_ptr->attr1 << "\t" << row_ptr->attr2 << std::endl; if (rc == -1) return on_error(transaction->getNdbError(), "Failed to read tuple"); operation->close(); m_ndb.closeTransaction(transaction); dict->releaseRecord(record); return true; } bool BasicRead::init() { if (m_connection.connect() != 0) { std::cout << "Cannot connect to cluster management server" << std::endl; return false; } if (m_connection.wait_until_ready(30, 0) != 0) { std::cout << "Cluster was not ready within 30 secs" << std::endl; return false; } if (m_ndb.init() != 0) return on_error(m_ndb.getNdbError(), "Failed to initialize ndb object"); return true; }