MySQL NDB Cluster 8.1 手冊
MySQL NDB Cluster 8.0 手冊
NDB Cluster 內部手冊
本節中重製的檔案 timestamp2.cpp
提供在 NDB API 應用程式中使用支援小數秒的 「新」 MySQL 時間資料類型的範例。
如需在 NDB API 中使用 MySQL 時間和其他資料類型的詳細資訊,請參閱第 2.1.3.2 節「NDB API 處理 MySQL 資料類型」。
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <NdbApi.hpp>
#include <string>
#include <unistd.h>
//no binlog value
#define NDB_ANYVALUE_FOR_NOLOGGING 0x8000007f
using namespace std;
int setTimestamp(NdbOperation* op,
const NdbDictionary::Column* col,
unsigned int value)
{
if (col->getType() == NDB_TYPE_TIMESTAMP)
{
/* Set as 32-bit int in host layout */
return op->setValue(col->getName(), value);
}
else if (col->getType() == NDB_TYPE_TIMESTAMP2)
{
/* Set as 64 bit big-endian value */
//assert(col->getPrecision() == 0);
Uint64 ts = 0;
unsigned char* bytes = (unsigned char*) &ts;
bytes[0] = value >> 24 & 0xff;
bytes[1] = value >> 16 & 0xff;
bytes[2] = value >> 8 & 0xff;
bytes[3] = value & 0xff;
return op->setValue(col->getName(), ts);
}
else
{
cout << "Bad type for column " << col->getType()
<< std::endl;
exit(1);
}
}
unsigned int readTimestamp(NdbRecAttr* recAttr)
{
if (recAttr->getType() == NDB_TYPE_TIMESTAMP)
{
/* Timestamp is in native 32 bit layout */
return recAttr->u_32_value();
}
else if (recAttr->getType() == NDB_TYPE_TIMESTAMP2)
{
/* Timestamp is in big-endian layout */
//assert(recAttr->getColumn()->getPrecision() == 0);
Uint64 ts2 = recAttr->u_64_value();
const unsigned char* bytes = (const unsigned char*) &ts2;
const unsigned int ts =
(Uint64(bytes[0]) << 24) +
(Uint64(bytes[1]) << 16) +
(Uint64(bytes[2]) << 8) +
(Uint64(bytes[3]));
return ts;
}
else
{
cout << "Error with timestamp column type : "
<< recAttr->getType()
<< endl;
exit(1);
}
}
void insert(string connectString)
{
Ndb_cluster_connection *cluster_connection = new Ndb_cluster_connection(connectString.c_str());
if(cluster_connection->connect(5,5,1)) {
cout << "Cannot connect to Cluster using connectstring: "<< connectString << endl;
exit(1);
}
if(cluster_connection->wait_until_ready(30,0) < 0) {
cout << "Cluster was not ready within 30 seconds" << endl;
}
Ndb *myNdb = new Ndb(cluster_connection, "myndb_user_data");
if(myNdb->init(1024) == -1){
cout << "Error: Cannot initialize NDB object" << endl;
exit(-1);
}
const NdbDictionary::Dictionary *dict = myNdb->getDictionary();
if (dict == NULL) {
cout << "Error: Cannot fetch NndDictionary" << endl;
exit(0);
}
const NdbDictionary::Table *timestampTable = dict->getTable("TIMESTAMP_TEST");
if (timestampTable == NULL) {
cout << "Error: Cannot fetch MYNDB table" << endl;
exit(0);
}
NdbTransaction *trans = myNdb->startTransaction();
if (trans == NULL) {
cout << "Error: Cannot start new transaction" << endl;
exit(1);
}
NdbOperation *myOperation = trans->getNdbOperation(timestampTable);
if ( myOperation == NULL) {
cout << "Error: Cannot get new operation" << endl;
exit(1);
}
myOperation->insertTuple();
Uint64 value;
myNdb->getAutoIncrementValue(timestampTable, value, (Uint32)32);
myOperation->setValue("KEY_COL", value);
time_t timestamp= time(NULL);
setTimestamp(myOperation,
timestampTable->getColumn("createTimestamp"),
timestamp);
setTimestamp(myOperation,
timestampTable->getColumn("modifyTimestamp"),
timestamp);
//disable binlogging
myOperation->setAnyValue(NDB_ANYVALUE_FOR_NOLOGGING);
if(trans->execute(NdbTransaction::Commit) != 0) {
cout << "Error: " << trans->getNdbError().message << endl;
exit(1);
}
myNdb->closeTransaction(trans);
delete myNdb;
delete cluster_connection;
}
void fetch_from_database(string connectString)
{
Ndb_cluster_connection *cluster_connection = new Ndb_cluster_connection(connectString.c_str());
if(cluster_connection->connect(5,5,1)) {
cout << "Cannot connect to Cluster using connectstring: "<< connectString << endl;
exit(1);
}
if(cluster_connection->wait_until_ready(30,0) < 0) {
cout << "Cluster was not ready within 30 seconds" << endl;
}
Ndb *myNdb = new Ndb(cluster_connection, "myndb_user_data");
if(myNdb->init(1024) == -1){
cout << "Error: Cannot initialize NDB object" << endl;
exit(-1);
}
const NdbDictionary::Dictionary *dict = myNdb->getDictionary();
if (dict == NULL) {
cout << "Error: Cannot fetch NndDictionary" << endl;
exit(0);
}
const NdbDictionary::Table *timestampTable = dict->getTable("TIMESTAMP_TEST");
if (timestampTable == NULL) {
cout << "Error: Cannot fetch MYNDB table" << endl;
exit(0);
}
NdbTransaction *trans = myNdb->startTransaction();
if (trans == NULL) {
cout << "Error: Cannot start new transaction" << endl;
exit(1);
}
NdbScanOperation *myOperation = trans->getNdbScanOperation(timestampTable);
if ( myOperation == NULL) {
cout << "Error: Cannot get new operation" << endl;
exit(1);
}
if (myOperation->readTuples(NdbOperation::LM_Exclusive) == -1){
cout << "Error: " << trans->getNdbError().message << endl;
exit(0);
}
NdbRecAttr *recAttrs[3];
recAttrs[0] = myOperation->getValue("KEY_COL");
recAttrs[1] = myOperation->getValue("createTimestamp");
recAttrs[2] = myOperation->getValue("modifyTimestamp");
if (recAttrs[0] == NULL || recAttrs[1] == NULL || recAttrs[2] == NULL) {
cout << "Error: " << trans->getNdbError().message << endl;
exit(0);
}
if(trans->execute(NdbTransaction::NoCommit) != 0) {
cout << "Error: " << trans->getNdbError().message << endl;
exit(1);
}
int check;
while((check = myOperation->nextResult(true)) == 0){
do {
cout << recAttrs[0]->u_32_value() << "\t";
cout << readTimestamp(recAttrs[1]) << "\t";
cout << readTimestamp(recAttrs[2]) << std::endl;
} while((check = myOperation->nextResult(false)) == 0);
}
myNdb->closeTransaction(trans);
delete myNdb;
delete cluster_connection;
}
int main(int argc, char **argv) {
cout << "Timestamp test application!!!!" << endl;
//fetch parameters
string connectString;
if (argc < 2) {
cout<<"Please provide connect string for PLDB"<<endl;
exit(1);
}
connectString = argv[1];
ndb_init();
insert(connectString);
fetch_from_database(connectString);
ndb_end(0);
return EXIT_SUCCESS;
}