本节中复制的文件timestamp2.cpp
提供了一个在 NDB API 应用程序中使用支持小数秒的“新” MySQL 时间数据类型的示例,这些数据类型在 MySQL 5.6、NDB 7.3 和 NDB 7.4 中实现。
有关在 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;
}