void TableTailer::waitForEvents() { NdbEventOperation* op; LOG_INFO("create EventOperation for [" << mEventName << "]"); if ((op = mNdbConnection->createEventOperation(mEventName.c_str())) == NULL) LOG_NDB_API_ERROR(mNdbConnection->getNdbError()); NdbRecAttr * recAttr[mTable.mNoColumns]; NdbRecAttr * recAttrPre[mTable.mNoColumns]; // primary keys should always be a part of the result for (int i = 0; i < mTable.mNoColumns; i++) { recAttr[i] = op->getValue(mTable.mColumnNames[i].c_str()); recAttrPre[i] = op->getPreValue(mTable.mColumnNames[i].c_str()); } LOG_INFO("Execute"); // This starts changes to "start flowing" if (op->execute()) LOG_NDB_API_ERROR(op->getNdbError()); while (true) { int r = mNdbConnection->pollEvents2(mPollMaxTimeToWait); if (r > 0) { while ((op = mNdbConnection->nextEvent2())) { NdbDictionary::Event::TableEvent event = op->getEventType2(); if(event != NdbDictionary::Event::TE_EMPTY){ LOG_TRACE("Got Event [" << event << "," << getEventName(event) << "] Epoch " << op->getEpoch()); } switch (event) { case NdbDictionary::Event::TE_INSERT: case NdbDictionary::Event::TE_DELETE: case NdbDictionary::Event::TE_UPDATE: handleEvent(event, recAttrPre, recAttr); break; default: break; } } } //boost::this_thread::sleep(boost::posix_time::milliseconds(mPollMaxTimeToWait)); } }
static int copy_events(Ndb *ndb) { DBUG_ENTER("copy_events"); int r= 0; NdbDictionary::Dictionary * dict = ndb->getDictionary(); while (1) { int res= ndb->pollEvents(1000); // wait for event or 1000 ms DBUG_PRINT("info", ("pollEvents res=%d", res)); if (res <= 0) { break; } int error= 0; NdbEventOperation *pOp; while ((pOp= ndb->nextEvent(&error))) { char buf[1024]; sprintf(buf, "%s_SHADOW", pOp->getTable()->getName()); const NdbDictionary::Table *table= dict->getTable(buf); if (table == 0) { g_err << "unable to find table " << buf << endl; DBUG_RETURN(-1); } if (pOp->isOverrun()) { g_err << "buffer overrun\n"; DBUG_RETURN(-1); } r++; Uint32 gci= pOp->getGCI(); if (!pOp->isConsistent()) { g_err << "A node failure has occured and events might be missing\n"; DBUG_RETURN(-1); } int noRetries= 0; do { NdbTransaction *trans= ndb->startTransaction(); if (trans == 0) { g_err << "startTransaction failed " << ndb->getNdbError().code << " " << ndb->getNdbError().message << endl; DBUG_RETURN(-1); } NdbOperation *op= trans->getNdbOperation(table); if (op == 0) { g_err << "getNdbOperation failed " << trans->getNdbError().code << " " << trans->getNdbError().message << endl; DBUG_RETURN(-1); } switch (pOp->getEventType()) { case NdbDictionary::Event::TE_INSERT: if (op->insertTuple()) { g_err << "insertTuple " << op->getNdbError().code << " " << op->getNdbError().message << endl; DBUG_RETURN(-1); } break; case NdbDictionary::Event::TE_DELETE: if (op->deleteTuple()) { g_err << "deleteTuple " << op->getNdbError().code << " " << op->getNdbError().message << endl; DBUG_RETURN(-1); } break; case NdbDictionary::Event::TE_UPDATE: if (op->updateTuple()) { g_err << "updateTuple " << op->getNdbError().code << " " << op->getNdbError().message << endl; DBUG_RETURN(-1); } break; default: abort(); } { for (const NdbRecAttr *pk= pOp->getFirstPkAttr(); pk; pk= pk->next()) { if (pk->isNULL()) { g_err << "internal error: primary key isNull()=" << pk->isNULL() << endl; DBUG_RETURN(NDBT_FAILED); } if (op->equal(pk->getColumn()->getColumnNo(),pk->aRef())) { g_err << "equal " << pk->getColumn()->getColumnNo() << " " << op->getNdbError().code << " " << op->getNdbError().message << endl; DBUG_RETURN(NDBT_FAILED); } } } switch (pOp->getEventType()) { case NdbDictionary::Event::TE_INSERT: { for (const NdbRecAttr *data= pOp->getFirstDataAttr(); data; data= data->next()) { if (data->isNULL() < 0 || op->setValue(data->getColumn()->getColumnNo(), data->isNULL() ? 0:data->aRef())) { g_err << "setValue(insert) " << data->getColumn()->getColumnNo() << " " << op->getNdbError().code << " " << op->getNdbError().message << endl; DBUG_RETURN(-1); } } break; } case NdbDictionary::Event::TE_DELETE: break; case NdbDictionary::Event::TE_UPDATE: { for (const NdbRecAttr *data= pOp->getFirstDataAttr(); data; data= data->next()) { if (data->isNULL() >= 0 && op->setValue(data->getColumn()->getColumnNo(), data->isNULL() ? 0:data->aRef())) { g_err << "setValue(update) " << data->getColumn()->getColumnNo() << " " << op->getNdbError().code << " " << op->getNdbError().message << endl; DBUG_RETURN(NDBT_FAILED); } } break; } case NdbDictionary::Event::TE_ALL: abort(); } if (trans->execute(Commit) == 0) { trans->close(); // everything ok break; } if (noRetries++ == 10 || trans->getNdbError().status != NdbError::TemporaryError) { g_err << "execute " << r << " failed " << trans->getNdbError().code << " " << trans->getNdbError().message << endl; trans->close(); DBUG_RETURN(-1); } trans->close(); NdbSleep_MilliSleep(100); // sleep before retying } while(1); } // for if (error) { g_err << "nextEvent()\n"; DBUG_RETURN(-1); } } // while(1) DBUG_RETURN(r); }
int main(int argc, char** argv){ NDB_INIT(argv[0]); const char *load_default_groups[]= { "mysql_cluster",0 }; load_defaults("my",load_default_groups,&argc,&argv); int ho_error; #ifndef DBUG_OFF opt_debug= "d:t:O,/tmp/ndb_desc.trace"; #endif if ((ho_error=handle_options(&argc, &argv, my_long_options, ndb_std_get_one_option))) return NDBT_ProgramExit(NDBT_WRONGARGS); for (int i = 0; i<_loop; i++) { Ndb_cluster_connection con(opt_connect_str); if(con.connect(12, 5, 1) != 0) { ndbout << "Unable to connect to management server." << endl; return NDBT_ProgramExit(NDBT_FAILED); } if (con.wait_until_ready(30,30) != 0) { ndbout << "Cluster nodes not ready in 30 seconds." << endl; return NDBT_ProgramExit(NDBT_FAILED); } Ndb MyNdb(&con, "TEST_DB"); if(MyNdb.init() != 0){ ERR(MyNdb.getNdbError()); return NDBT_ProgramExit(NDBT_FAILED); } Vector<NdbEventOperation*> ops; const NdbDictionary::Dictionary * dict= MyNdb.getDictionary(); for (int j = 0; j < argc; j++) { const NdbDictionary::Table * pTab = dict->getTable(argv[j]); if (pTab == 0) { ndbout_c("Failed to retreive table: \"%s\"", argv[j]); } BaseString tmp; tmp.appfmt("EV-%s", argv[j]); NdbEventOperation* pOp = MyNdb.createEventOperation(tmp.c_str()); if ( pOp == NULL ) { ndbout << "Event operation creation failed: " << MyNdb.getNdbError() << endl; return NDBT_ProgramExit(NDBT_FAILED); } for (int a = 0; a < pTab->getNoOfColumns(); a++) { pOp->getValue(pTab->getColumn(a)->getName()); pOp->getPreValue(pTab->getColumn(a)->getName()); } if (pOp->execute()) { ndbout << "operation execution failed: " << pOp->getNdbError() << endl; return NDBT_ProgramExit(NDBT_FAILED); } ops.push_back(pOp); } if (_sleep) { NdbSleep_MilliSleep(10 + rand() % _sleep); } for (Uint32 i = 0; i<ops.size(); i++) { switch(_drop){ case 0: break; do_drop: case 1: if (MyNdb.dropEventOperation(ops[i])) { ndbout << "drop event operation failed " << MyNdb.getNdbError() << endl; return NDBT_ProgramExit(NDBT_FAILED); } break; default: if ((rand() % 100) > 50) goto do_drop; } } } return NDBT_ProgramExit(NDBT_OK); }
int runEventApplier(NDBT_Context* ctx, NDBT_Step* step) { DBUG_ENTER("runEventApplier"); int records = ctx->getNumRecords(); int loops = ctx->getNumLoops(); const NdbDictionary::Table * table= ctx->getTab(); char buf[1024]; sprintf(buf, "%s_SHADOW", table->getName()); const NdbDictionary::Table * table_shadow; if ((table_shadow = GETNDB(step)->getDictionary()->getTable(buf)) == 0) { g_err << "Unable to get table " << buf << endl; DBUG_RETURN(NDBT_FAILED); } sprintf(buf, "%s_EVENT", table->getName()); NdbEventOperation *pOp; pOp = GETNDB(step)->createEventOperation(buf, 10*records); if ( pOp == NULL ) { g_err << "Event operation creation failed on %s" << buf << endl; DBUG_RETURN(NDBT_FAILED); } int i; int n_columns= table->getNoOfColumns(); NdbRecAttr* recAttr[1024]; NdbRecAttr* recAttrPre[1024]; for (i = 0; i < n_columns; i++) { recAttr[i] = pOp->getValue(table->getColumn(i)->getName()); recAttrPre[i] = pOp->getPreValue(table->getColumn(i)->getName()); } if (pOp->execute()) { // This starts changes to "start flowing" g_err << "execute operation execution failed: \n"; g_err << pOp->getNdbError().code << " " << pOp->getNdbError().message << endl; DBUG_RETURN(NDBT_FAILED); } int r= 0; int res; while (r < 10*records){ //printf("now waiting for event...\n"); res= GETNDB(step)->pollEvents(1000); // wait for event or 1000 ms if (res <= 0) { ndbout_c("********************"); continue; } //printf("got data! %d\n", r); int overrun= 0; while (pOp->next(&overrun) > 0) { if (overrun) { g_err << "buffer overrun\n"; DBUG_RETURN(NDBT_FAILED); } r++; Uint32 gci= pOp->getGCI(); if (!pOp->isConsistent()) { g_err << "A node failure has occured and events might be missing\n"; DBUG_RETURN(NDBT_FAILED); } int noRetries= 0; do { NdbTransaction *trans= GETNDB(step)->startTransaction(); if (trans == 0) { g_err << "startTransaction failed " << GETNDB(step)->getNdbError().code << " " << GETNDB(step)->getNdbError().message << endl; DBUG_RETURN(NDBT_FAILED); } NdbOperation *op= trans->getNdbOperation(table_shadow); if (op == 0) { g_err << "getNdbOperation failed " << trans->getNdbError().code << " " << trans->getNdbError().message << endl; DBUG_RETURN(NDBT_FAILED); } switch (pOp->getEventType()) { case NdbDictionary::Event::TE_INSERT: if (op->insertTuple()) { g_err << "insertTuple " << op->getNdbError().code << " " << op->getNdbError().message << endl; DBUG_RETURN(NDBT_FAILED); } break; case NdbDictionary::Event::TE_DELETE: if (op->deleteTuple()) { g_err << "deleteTuple " << op->getNdbError().code << " " << op->getNdbError().message << endl; DBUG_RETURN(NDBT_FAILED); } break; case NdbDictionary::Event::TE_UPDATE: if (op->updateTuple()) { g_err << "updateTuple " << op->getNdbError().code << " " << op->getNdbError().message << endl; DBUG_RETURN(NDBT_FAILED); } break; default: abort(); } for (i= 0; i < n_columns; i++) { if (recAttr[i]->isNULL()) { if (table->getColumn(i)->getPrimaryKey()) { g_err << "internal error: primary key isNull()=" << recAttr[i]->isNULL() << endl; DBUG_RETURN(NDBT_FAILED); } switch (pOp->getEventType()) { case NdbDictionary::Event::TE_INSERT: if (recAttr[i]->isNULL() < 0) { g_err << "internal error: missing value for insert\n"; DBUG_RETURN(NDBT_FAILED); } break; case NdbDictionary::Event::TE_DELETE: break; case NdbDictionary::Event::TE_UPDATE: break; default: abort(); } } if (table->getColumn(i)->getPrimaryKey() && op->equal(i,recAttr[i]->aRef())) { g_err << "equal " << i << " " << op->getNdbError().code << " " << op->getNdbError().message << endl; DBUG_RETURN(NDBT_FAILED); } } switch (pOp->getEventType()) { case NdbDictionary::Event::TE_INSERT: for (i= 0; i < n_columns; i++) { if (!table->getColumn(i)->getPrimaryKey() && op->setValue(i,recAttr[i]->isNULL() ? 0:recAttr[i]->aRef())) { g_err << "setValue(insert) " << i << " " << op->getNdbError().code << " " << op->getNdbError().message << endl; DBUG_RETURN(NDBT_FAILED); } } break; case NdbDictionary::Event::TE_DELETE: break; case NdbDictionary::Event::TE_UPDATE: for (i= 0; i < n_columns; i++) { if (!table->getColumn(i)->getPrimaryKey() && recAttr[i]->isNULL() >= 0 && op->setValue(i,recAttr[i]->isNULL() ? 0:recAttr[i]->aRef())) { g_err << "setValue(update) " << i << " " << op->getNdbError().code << " " << op->getNdbError().message << endl; DBUG_RETURN(NDBT_FAILED); } } break; case NdbDictionary::Event::TE_ALL: abort(); } if (trans->execute(Commit) == 0) { trans->close(); // everything ok break; } if (noRetries++ == 10 || trans->getNdbError().status != NdbError::TemporaryError) { g_err << "execute " << r << " failed " << trans->getNdbError().code << " " << trans->getNdbError().message << endl; trans->close(); DBUG_RETURN(NDBT_FAILED); } trans->close(); NdbSleep_MilliSleep(100); // sleep before retying } while(1); } } if (GETNDB(step)->dropEventOperation(pOp)) { g_err << "dropEventOperation execution failed " << GETNDB(step)->getNdbError().code << " " << GETNDB(step)->getNdbError().message << endl; DBUG_RETURN(NDBT_FAILED); } DBUG_RETURN(NDBT_OK); }
int main(int argc, char** argv) { if (argc < 3) { std::cout << "Arguments are <connect_string cluster> <timeout> [m(merge events)|d(debug)].\n"; exit(-1); } const char *connectstring = argv[1]; int timeout = atoi(argv[2]); ndb_init(); bool merge_events = argc > 3 && strchr(argv[3], 'm') != 0; #ifdef VM_TRACE bool dbug = argc > 3 && strchr(argv[3], 'd') != 0; if (dbug) DBUG_PUSH("d:t:"); if (dbug) putenv("API_SIGNAL_LOG=-"); #endif Ndb_cluster_connection *cluster_connection= new Ndb_cluster_connection(connectstring); // Object representing the cluster int r= cluster_connection->connect(5 /* retries */, 3 /* delay between retries */, 1 /* verbose */); if (r > 0) { std::cout << "Cluster connect failed, possibly resolved with more retries.\n"; exit(-1); } else if (r < 0) { std::cout << "Cluster connect failed.\n"; exit(-1); } if (cluster_connection->wait_until_ready(30,30)) { std::cout << "Cluster was not ready within 30 secs." << std::endl; exit(-1); } Ndb* myNdb= new Ndb(cluster_connection, "TEST_DB"); // Object representing the database if (myNdb->init() == -1) APIERROR(myNdb->getNdbError()); const char *eventName= "CHNG_IN_t0"; const char *eventTableName= "t0"; const int noEventColumnName= 5; const char *eventColumnName[noEventColumnName]= {"c0", "c1", "c2", "c3", "c4" }; // Create events myCreateEvent(myNdb, eventName, eventTableName, eventColumnName, noEventColumnName, merge_events); // Normal values and blobs are unfortunately handled differently.. typedef union { NdbRecAttr* ra; NdbBlob* bh; } RA_BH; int i, j, k, l; j = 0; while (j < timeout) { // Start "transaction" for handling events NdbEventOperation* op; printf("create EventOperation\n"); if ((op = myNdb->createEventOperation(eventName)) == NULL) APIERROR(myNdb->getNdbError()); op->mergeEvents(merge_events); printf("get values\n"); RA_BH recAttr[noEventColumnName]; RA_BH recAttrPre[noEventColumnName]; // primary keys should always be a part of the result for (i = 0; i < noEventColumnName; i++) { if (i < 4) { recAttr[i].ra = op->getValue(eventColumnName[i]); recAttrPre[i].ra = op->getPreValue(eventColumnName[i]); } else if (merge_events) { recAttr[i].bh = op->getBlobHandle(eventColumnName[i]); recAttrPre[i].bh = op->getPreBlobHandle(eventColumnName[i]); } } // set up the callbacks printf("execute\n"); // This starts changes to "start flowing" if (op->execute()) APIERROR(op->getNdbError()); NdbEventOperation* the_op = op; i= 0; while (i < timeout) { // printf("now waiting for event...\n"); int r = myNdb->pollEvents(1000); // wait for event or 1000 ms if (r > 0) { // printf("got data! %d\n", r); while ((op= myNdb->nextEvent())) { assert(the_op == op); i++; switch (op->getEventType()) { case NdbDictionary::Event::TE_INSERT: printf("%u INSERT", i); break; case NdbDictionary::Event::TE_DELETE: printf("%u DELETE", i); break; case NdbDictionary::Event::TE_UPDATE: printf("%u UPDATE", i); break; default: abort(); // should not happen } printf(" gci=%d\n", (int)op->getGCI()); for (k = 0; k <= 1; k++) { printf(k == 0 ? "post: " : "pre : "); for (l = 0; l < noEventColumnName; l++) { if (l < 4) { NdbRecAttr* ra = k == 0 ? recAttr[l].ra : recAttrPre[l].ra; if (ra->isNULL() >= 0) { // we have a value if (ra->isNULL() == 0) { // we have a non-null value if (l < 2) printf("%-5u", ra->u_32_value()); else printf("%-5.4s", ra->aRef()); } else printf("%-5s", "NULL"); } else printf("%-5s", "-"); // no value } else if (merge_events) { int isNull; NdbBlob* bh = k == 0 ? recAttr[l].bh : recAttrPre[l].bh; bh->getDefined(isNull); if (isNull >= 0) { // we have a value if (! isNull) { // we have a non-null value Uint64 length = 0; bh->getLength(length); // read into buffer unsigned char* buf = new unsigned char [length]; memset(buf, 'X', length); Uint32 n = length; bh->readData(buf, n); // n is in/out assert(n == length); // pretty-print bool first = true; Uint32 i = 0; while (i < n) { unsigned char c = buf[i++]; Uint32 m = 1; while (i < n && buf[i] == c) i++, m++; if (! first) printf("+"); printf("%u%c", m, c); first = false; } printf("[%u]", n); delete [] buf; } else printf("%-5s", "NULL"); } else printf("%-5s", "-"); // no value } } printf("\n"); } } } else printf("timed out (%i)\n", timeout); } // don't want to listen to events anymore if (myNdb->dropEventOperation(the_op)) APIERROR(myNdb->getNdbError()); the_op = 0; j++; } { NdbDictionary::Dictionary *myDict = myNdb->getDictionary(); if (!myDict) APIERROR(myNdb->getNdbError()); // remove event from database if (myDict->dropEvent(eventName)) APIERROR(myDict->getNdbError()); } delete myNdb; delete cluster_connection; ndb_end(0); return 0; }
int main(int argc, const char** argv){ ndb_init(); int _help = 0; const char* db = 0; const char* connectstring1 = 0; const char* connectstring2 = 0; struct getargs args[] = { { "connectstring1", 'c', arg_string, &connectstring1, "connectstring1", "" }, { "connectstring2", 'C', arg_string, &connectstring2, "connectstring2", "" }, { "database", 'd', arg_string, &db, "Database", "" }, { "usage", '?', arg_flag, &_help, "Print help", "" } }; int num_args = sizeof(args) / sizeof(args[0]); int optind = 0, i; char desc[] = "<tabname>+ \nThis program listen to events on specified tables\n"; if(getarg(args, num_args, argc, argv, &optind) || argv[optind] == NULL || _help) { arg_printusage(args, num_args, argv[0], desc); return NDBT_ProgramExit(NDBT_WRONGARGS); } // Connect to Ndb Ndb_cluster_connection con(connectstring1); if(con.connect(12, 5, 1) != 0) { return NDBT_ProgramExit(NDBT_FAILED); } Ndb MyNdb( &con, db ? db : "TEST_DB" ); if(MyNdb.init() != 0){ ERR(MyNdb.getNdbError()); return NDBT_ProgramExit(NDBT_FAILED); } // Connect to Ndb and wait for it to become ready while(MyNdb.waitUntilReady() != 0) ndbout << "Waiting for ndb to become ready..." << endl; Ndb_cluster_connection *con2 = NULL; Ndb *ndb2 = NULL; if (connectstring2) { con2 = new Ndb_cluster_connection(connectstring2); if(con2->connect(12, 5, 1) != 0) { return NDBT_ProgramExit(NDBT_FAILED); } ndb2 = new Ndb( con2, db ? db : "TEST_DB" ); if(ndb2->init() != 0){ ERR(ndb2->getNdbError()); return NDBT_ProgramExit(NDBT_FAILED); } // Connect to Ndb and wait for it to become ready while(ndb2->waitUntilReady() != 0) ndbout << "Waiting for ndb to become ready..." << endl; } int result = 0; NdbDictionary::Dictionary *myDict = MyNdb.getDictionary(); Vector<NdbDictionary::Event*> events; Vector<NdbEventOperation*> event_ops; int sz = 0; for(i= optind; i<argc; i++) { const NdbDictionary::Table* table= myDict->getTable(argv[i]); if(!table) { ndbout_c("Could not find table: %s, skipping", argv[i]); continue; } BaseString name; name.appfmt("EV-%s", argv[i]); NdbDictionary::Event *myEvent= new NdbDictionary::Event(name.c_str()); myEvent->setTable(table->getName()); myEvent->addTableEvent(NdbDictionary::Event::TE_ALL); for(int a = 0; a < table->getNoOfColumns(); a++){ myEvent->addEventColumn(a); } if (myDict->createEvent(* myEvent)) { if(myDict->getNdbError().classification == NdbError::SchemaObjectExists) { g_info << "Event creation failed event exists. Removing...\n"; if (myDict->dropEvent(name.c_str())) { g_err << "Failed to drop event: " << myDict->getNdbError() << endl; result = 1; goto end; } // try again if (myDict->createEvent(* myEvent)) { g_err << "Failed to create event: " << myDict->getNdbError() << endl; result = 1; goto end; } } else { g_err << "Failed to create event: " << myDict->getNdbError() << endl; result = 1; goto end; } } events.push_back(myEvent); NdbEventOperation* pOp = MyNdb.createEventOperation(name.c_str()); if ( pOp == NULL ) { g_err << "Event operation creation failed" << endl; result = 1; goto end; } event_values.push_back(Vector<NdbRecAttr *>()); event_pre_values.push_back(Vector<NdbRecAttr *>()); for (int a = 0; a < table->getNoOfColumns(); a++) { event_values[sz]. push_back(pOp->getValue(table->getColumn(a)->getName())); event_pre_values[sz]. push_back(pOp->getPreValue(table->getColumn(a)->getName())); } event_ops.push_back(pOp); { struct Table_info ti; ti.id = sz; table_infos.push_back(ti); } pOp->setCustomData((void *)&table_infos[sz]); sz++; } for(i= 0; i<(int)event_ops.size(); i++) { if (event_ops[i]->execute()) { g_err << "operation execution failed: " << event_ops[i]->getNdbError() << endl; result = 1; goto end; } } struct Trans_arg trans_arg; while(true) { while(MyNdb.pollEvents(100) == 0); NdbEventOperation* pOp= MyNdb.nextEvent(); while(pOp) { Uint64 gci= pOp->getGCI(); Uint64 cnt_i= 0, cnt_u= 0, cnt_d= 0; if (ndb2) do_begin(ndb2, trans_arg); do { switch(pOp->getEventType()) { case NdbDictionary::Event::TE_INSERT: cnt_i++; if (ndb2) do_insert(trans_arg, pOp); break; case NdbDictionary::Event::TE_DELETE: cnt_d++; if (ndb2) do_delete(trans_arg, pOp); break; case NdbDictionary::Event::TE_UPDATE: cnt_u++; if (ndb2) do_update(trans_arg, pOp); break; case NdbDictionary::Event::TE_CLUSTER_FAILURE: break; case NdbDictionary::Event::TE_ALTER: break; case NdbDictionary::Event::TE_DROP: break; case NdbDictionary::Event::TE_NODE_FAILURE: break; case NdbDictionary::Event::TE_SUBSCRIBE: case NdbDictionary::Event::TE_UNSUBSCRIBE: break; default: /* We should REALLY never get here. */ ndbout_c("Error: unknown event type: %u", (Uint32)pOp->getEventType()); abort(); } } while ((pOp= MyNdb.nextEvent()) && gci == pOp->getGCI()); if (ndb2) do_commit(trans_arg); ndbout_c("GCI: %lld events: %lld(I) %lld(U) %lld(D)", gci, cnt_i, cnt_u, cnt_d); } } end: for(i= 0; i<(int)event_ops.size(); i++) MyNdb.dropEventOperation(event_ops[i]); if (ndb2) delete ndb2; if (con2) delete con2; return NDBT_ProgramExit(NDBT_OK); }