diff options
author | unknown <stewart@mysql.com> | 2005-01-07 12:06:57 +1100 |
---|---|---|
committer | unknown <stewart@mysql.com> | 2005-01-07 12:06:57 +1100 |
commit | ccbadbc94af2f64b1261c13400fa3bf8299a42cd (patch) | |
tree | 78f7114c2aa35ea2d98a814b71dc6136cec8dbe0 | |
parent | 5de7459359fb6871c281624c693bf15f4765ca64 (diff) | |
parent | d42ff5df42e3acd43f7512b6f6fc1f2e9980e355 (diff) | |
download | mariadb-git-ccbadbc94af2f64b1261c13400fa3bf8299a42cd.tar.gz |
Merge mysql.com:/home/stewart/Documents/MySQL/5.0/ndb
into mysql.com:/home/stewart/Documents/MySQL/5.0/ndb-dynamic-ports-impl3
50 files changed, 1268 insertions, 1280 deletions
diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 2b3339e59d3..04e18ab8892 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -96,6 +96,7 @@ jcole@tetra.spaceapes.com jimw@mysql.com joerg@mysql.com jon@gigan. +jonas@mysql.com joreland@bk-internal.mysql.com joreland@mysql.com jorge@linux.jorge.mysql.com diff --git a/configure.in b/configure.in index c307cd03da9..47ac06706b2 100644 --- a/configure.in +++ b/configure.in @@ -1770,6 +1770,7 @@ examine config.log for possible errors. If you want to report this, use 'scripts/mysqlbug' and include at least the last 20 rows from config.log!]) fi AC_CHECK_SIZEOF(char*, 4) +AC_CHECK_SIZEOF(short, 2) AC_CHECK_SIZEOF(int, 4) if test "$ac_cv_sizeof_int" -eq 0 then @@ -2723,11 +2724,26 @@ then fi AC_SUBST([ndb_bin_am_ldflags]) AC_SUBST([ndb_opt_subdirs]) + +NDB_SIZEOF_CHARP="$ac_cv_sizeof_charp" +NDB_SIZEOF_CHAR="$ac_cv_sizeof_char" +NDB_SIZEOF_SHORT="$ac_cv_sizeof_short" +NDB_SIZEOF_INT="$ac_cv_sizeof_int" +NDB_SIZEOF_LONG="$ac_cv_sizeof_long" +NDB_SIZEOF_LONG_LONG="$ac_cv_sizeof_long_long" +AC_SUBST([NDB_SIZEOF_CHARP]) +AC_SUBST([NDB_SIZEOF_CHAR]) +AC_SUBST([NDB_SIZEOF_SHORT]) +AC_SUBST([NDB_SIZEOF_INT]) +AC_SUBST([NDB_SIZEOF_LONG]) +AC_SUBST([NDB_SIZEOF_LONG_LONG]) + AC_CONFIG_FILES(ndb/Makefile ndb/include/Makefile dnl ndb/src/Makefile ndb/src/common/Makefile dnl ndb/docs/Makefile dnl ndb/tools/Makefile dnl - ndb/src/common/debugger/Makefile ndb/src/common/debugger/signaldata/Makefile dnl + ndb/src/common/debugger/Makefile dnl + ndb/src/common/debugger/signaldata/Makefile dnl ndb/src/common/portlib/Makefile dnl ndb/src/common/util/Makefile dnl ndb/src/common/logger/Makefile dnl @@ -2766,6 +2782,7 @@ AC_CONFIG_FILES(ndb/Makefile ndb/include/Makefile dnl ndb/test/tools/Makefile dnl ndb/test/run-test/Makefile mysql-test/ndb/Makefile dnl ndb/include/ndb_version.h ndb/include/ndb_global.h dnl + ndb/include/ndb_types.h dnl ) fi diff --git a/ndb/examples/Makefile b/ndb/examples/Makefile index d533c4ff422..87a821773ec 100644 --- a/ndb/examples/Makefile +++ b/ndb/examples/Makefile @@ -1,5 +1,10 @@ -BIN_DIRS := ndbapi_example1 ndbapi_example3 ndbapi_example4 \ - ndbapi_example5 ndbapi_scan_example +BIN_DIRS := ndbapi_simple_example \ + ndbapi_async_example \ + ndbapi_async_example1 \ + ndbapi_retries_example \ + ndbapi_simple_index_example \ + ndbapi_event_example \ + ndbapi_scan_example bins: $(patsubst %, _bins_%, $(BIN_DIRS)) diff --git a/ndb/examples/ndbapi_async_example/Makefile b/ndb/examples/ndbapi_async_example/Makefile index f30398f9587..4df9367fc29 100644 --- a/ndb/examples/ndbapi_async_example/Makefile +++ b/ndb/examples/ndbapi_async_example/Makefile @@ -1,34 +1,23 @@ --include .defs.mk -#NDB_OS = OS_YOU_ARE_RUNNING_ON -#NDB_OS = LINUX -#You need to set the NDB_OS variable here (LINUX, SOLARIS, MACOSX) TARGET = ndbapi_async -SRCS = ndbapi_async.cpp -OBJS = ndbapi_async.o -CC = g++ -CFLAGS = -c -Wall -fno-rtti -D$(NDB_OS) +SRCS = $(TARGET).cpp +OBJS = $(TARGET).o +CXX = g++ +CFLAGS = -g -c -Wall -fno-rtti -fno-exceptions +CXXFLAGS = -g DEBUG = LFLAGS = -Wall -INCLUDE_DIR = ../../include -LIB_DIR = ../../lib -ifeq ($(NDB_OS), SOLARIS) -# Here is the definition of system libraries necessary for Solaris 7 -SYS_LIB = -lpthread -lsocket -lnsl -lrt -endif -ifeq ($(NDB_OS), LINUX) -# Here is the definition of system libraries necessary for Linux 2.4 -SYS_LIB = -lpthread -endif -ifeq ($(NDB_OS), MACOSX) -# Here is the definition of system libraries necessary for Mac OS X +TOP_SRCDIR = ../../.. +INCLUDE_DIR = $(TOP_SRCDIR) +LIB_DIR = -L$(TOP_SRCDIR)/ndb/src/.libs \ + -L$(TOP_SRCDIR)/libmysql_r/.libs \ + -L$(TOP_SRCDIR)/mysys SYS_LIB = -endif $(TARGET): $(OBJS) - $(CC) $(LFLAGS) -L$(LIB_DIR) -lNDB_API $(OBJS) $(SYS_LIB) -o $(TARGET) + $(CXX) $(CXXFLAGS) $(LFLAGS) $(LIB_DIR) $(OBJS) -lndbclient -lmysqlclient_r -lmysys -lz $(SYS_LIB) -o $(TARGET) $(TARGET).o: $(SRCS) - $(CC) $(CFLAGS) -I$(INCLUDE_DIR) -I$(INCLUDE_DIR)/ndbapi $(SRCS) + $(CXX) $(CFLAGS) -I$(INCLUDE_DIR)/include -I$(INCLUDE_DIR)/extra -I$(INCLUDE_DIR)/ndb/include -I$(INCLUDE_DIR)/ndb/include/ndbapi $(SRCS) clean: rm -f *.o $(TARGET) diff --git a/ndb/examples/ndbapi_async_example/ndbapi_async.cpp b/ndb/examples/ndbapi_async_example/ndbapi_async.cpp index 76ce1a8efe3..c11b6e849e4 100644 --- a/ndb/examples/ndbapi_async_example/ndbapi_async.cpp +++ b/ndb/examples/ndbapi_async_example/ndbapi_async.cpp @@ -24,10 +24,12 @@ * * Classes and methods in NDBAPI used in this example: * + * Ndb_cluster_connection + * connect() + * wait_until_ready() + * * Ndb * init() - * waitUntilRead() - * getDictionary() * startTransaction() * closeTransaction() * sendPollNdb() @@ -38,23 +40,6 @@ * executeAsynchPrepare() * getNdbError() * - * NdbDictionary::Dictionary - * getTable() - * dropTable() - * createTable() - * getNdbError() - * - * NdbDictionary::Column - * setName() - * setType() - * setLength() - * setPrimaryKey() - * setNullable() - * - * NdbDictionary::Table - * setName() - * addColumn() - * * NdbOperation * insertTuple() * equal() @@ -63,10 +48,10 @@ */ -#include <ndb_global.h> - +#include <mysql.h> +#include <mysqld_error.h> #include <NdbApi.hpp> -#include <NdbScanFilter.hpp> + #include <iostream> // Used for cout /** @@ -85,11 +70,16 @@ milliSleep(int milliseconds){ /** * error printout macro */ -#define APIERROR(error) \ - { std::cout << "Error in " << __FILE__ << ", line:" << __LINE__ << ", code:" \ - << error.code << ", msg: " << error.message << "." << std::endl; \ - exit(-1); } - +#define PRINT_ERROR(code,msg) \ + std::cout << "Error in " << __FILE__ << ", line: " << __LINE__ \ + << ", code: " << code \ + << ", msg: " << msg << "." << std::endl +#define MYSQLERROR(mysql) { \ + PRINT_ERROR(mysql_errno(&mysql),mysql_error(&mysql)); \ + exit(-1); } +#define APIERROR(error) { \ + PRINT_ERROR(error.code,error.message); \ + exit(-1); } #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL /** @@ -106,10 +96,10 @@ typedef struct { } async_callback_t; /** - * Structure used in "free list" to a NdbConnection + * Structure used in "free list" to a NdbTransaction */ typedef struct { - NdbConnection* conn; + NdbTransaction* conn; int used; } transaction_t; @@ -132,7 +122,7 @@ int populate(Ndb * myNdb, int data, async_callback_t * cbData); /** * Error handler. */ -bool asynchErrorHandler(NdbConnection * trans, Ndb* ndb); +bool asynchErrorHandler(NdbTransaction * trans, Ndb* ndb); /** * Exit function @@ -171,7 +161,7 @@ closeTransaction(Ndb * ndb , async_callback_t * cb) * Callback executed when transaction has return from NDB */ static void -callback(int result, NdbConnection* trans, void* aObject) +callback(int result, NdbTransaction* trans, void* aObject) { async_callback_t * cbData = (async_callback_t *)aObject; if (result<0) @@ -207,61 +197,26 @@ callback(int result, NdbConnection* trans, void* aObject) /** * Create table "GARAGE" */ -int create_table(Ndb * myNdb) +int create_table(MYSQL &mysql) { - NdbDictionary::Table myTable; - NdbDictionary::Column myColumn; - - NdbDictionary::Dictionary* myDict = myNdb->getDictionary(); - - /********************************************************* - * Create a table named GARAGE if it does not exist * - *********************************************************/ - if (myDict->getTable("GARAGE") != NULL) + while (mysql_query(&mysql, + "CREATE TABLE" + " GARAGE" + " (REG_NO INT UNSIGNED NOT NULL," + " BRAND CHAR(20) NOT NULL," + " COLOR CHAR(20) NOT NULL," + " PRIMARY KEY USING HASH (REG_NO))" + " ENGINE=NDB")) { - std::cout << "NDB already has example table: GARAGE. " + if (mysql_errno(&mysql) != ER_TABLE_EXISTS_ERROR) + MYSQLERROR(mysql); + std::cout << "MySQL Cluster already has example table: GARAGE. " << "Dropping it..." << std::endl; - if(myDict->dropTable("GARAGE") == -1) - { - std::cout << "Failed to drop: GARAGE." << std::endl; - exit(1); - } - } - - myTable.setName("GARAGE"); - -/** - * Column REG_NO - */ - myColumn.setName("REG_NO"); - myColumn.setType(NdbDictionary::Column::Unsigned); - myColumn.setLength(1); - myColumn.setPrimaryKey(true); - myColumn.setNullable(false); - myTable.addColumn(myColumn); - -/** - * Column BRAND - */ - myColumn.setName("BRAND"); - myColumn.setType(NdbDictionary::Column::Char); - myColumn.setLength(20); - myColumn.setPrimaryKey(false); - myColumn.setNullable(false); - myTable.addColumn(myColumn); - -/** - * Column COLOR - */ - myColumn.setName("COLOR"); - myColumn.setType(NdbDictionary::Column::Char); - myColumn.setLength(20); - myColumn.setPrimaryKey(false); - myColumn.setNullable(false); - myTable.addColumn(myColumn); - - if (myDict->createTable(myTable) == -1) { - APIERROR(myDict->getNdbError()); + /************** + * Drop table * + **************/ + if (mysql_query(&mysql, "DROP TABLE GARAGE")) + MYSQLERROR(mysql); } return 1; } @@ -276,7 +231,7 @@ void asynchExitHandler(Ndb * m_ndb) /* returns true if is recoverable (temporary), * false if it is an error that is permanent. */ -bool asynchErrorHandler(NdbConnection * trans, Ndb* ndb) +bool asynchErrorHandler(NdbTransaction * trans, Ndb* ndb) { NdbError error = trans->getNdbError(); switch(error.status) @@ -426,7 +381,7 @@ int populate(Ndb * myNdb, int data, async_callback_t * cbData) } /*Prepare transaction (the transaction is NOT yet sent to NDB)*/ - transaction[current].conn->executeAsynchPrepare(Commit, + transaction[current].conn->executeAsynchPrepare(NdbTransaction::Commit, &callback, cb); /** @@ -455,22 +410,48 @@ int populate(Ndb * myNdb, int data, async_callback_t * cbData) int main() { ndb_init(); - Ndb* myNdb = new Ndb( "TEST_DB" ); // Object representing the database - - /******************************************* - * Initialize NDB and wait until its ready * - *******************************************/ - if (myNdb->init(1024) == -1) { // Set max 1024 parallel transactions - APIERROR(myNdb->getNdbError()); + MYSQL mysql; + + /************************************************************** + * Connect to mysql server and create table * + **************************************************************/ + { + if ( !mysql_init(&mysql) ) { + std::cout << "mysql_init failed\n"; + exit(-1); + } + if ( !mysql_real_connect(&mysql, "localhost", "root", "", "", + 3306, "/tmp/mysql.sock", 0) ) + MYSQLERROR(mysql); + + mysql_query(&mysql, "CREATE DATABASE TEST_DB"); + if (mysql_query(&mysql, "USE TEST_DB") != 0) MYSQLERROR(mysql); + + create_table(mysql); } - if (myNdb->waitUntilReady(30) != 0) { - std::cout << "NDB was not ready within 30 secs." << std::endl; + /************************************************************** + * Connect to ndb cluster * + **************************************************************/ + Ndb_cluster_connection cluster_connection; + if (cluster_connection.connect(4, 5, 1)) + { + std::cout << "Unable to connect to cluster within 30 secs." << std::endl; + exit(-1); + } + // Optionally connect and wait for the storage nodes (ndbd's) + if (cluster_connection.wait_until_ready(30,0) < 0) + { + std::cout << "Cluster was not ready within 30 secs.\n"; exit(-1); } - create_table(myNdb); - + Ndb* myNdb = new Ndb( &cluster_connection, + "TEST_DB" ); // Object representing the database + if (myNdb->init(1024) == -1) { // Set max 1024 parallel transactions + APIERROR(myNdb->getNdbError()); + } + /** * Initialise transaction array */ diff --git a/ndb/examples/ndbapi_example3/Makefile b/ndb/examples/ndbapi_async_example1/Makefile index d7355650ada..b6fc31a00e5 100644 --- a/ndb/examples/ndbapi_example3/Makefile +++ b/ndb/examples/ndbapi_async_example1/Makefile @@ -1,6 +1,6 @@ -TARGET = ndbapi_example3 -SRCS = ndbapi_example3.cpp -OBJS = ndbapi_example3.o +TARGET = ndbapi_async1 +SRCS = ndbapi_async1.cpp +OBJS = ndbapi_async1.o CXX = g++ CFLAGS = -c -Wall -fno-rtti -fno-exceptions DEBUG = diff --git a/ndb/examples/ndbapi_example2/ndbapi_example2.cpp b/ndb/examples/ndbapi_async_example1/ndbapi_async1.cpp index de19cb19584..fb806a5bbb5 100644 --- a/ndb/examples/ndbapi_example2/ndbapi_example2.cpp +++ b/ndb/examples/ndbapi_async_example1/ndbapi_async1.cpp @@ -15,7 +15,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // -// ndbapi_example2.cpp: Using asynchronous transactions in NDB API +// ndbapi_async1.cpp: Using asynchronous transactions in NDB API // // Execute ndbapi_example1 to create the table "MYTABLENAME" // before executing this program. @@ -99,7 +99,8 @@ int main() myNdbOperation->setValue("ATTR2", 20 + i); // Prepare transaction (the transaction is NOT yet sent to NDB) - myNdbTransaction[i]->executeAsynchPrepare(Commit, &callback, NULL); + myNdbTransaction[i]->executeAsynchPrepare(NdbTransaction::Commit, + &callback, NULL); } // Send all transactions to NDB diff --git a/ndb/examples/ndbapi_example5/Makefile b/ndb/examples/ndbapi_event_example/Makefile index 67460402210..07d244c9346 100644 --- a/ndb/examples/ndbapi_example5/Makefile +++ b/ndb/examples/ndbapi_event_example/Makefile @@ -1,6 +1,6 @@ -TARGET = ndbapi_example5 -SRCS = ndbapi_example5.cpp -OBJS = ndbapi_example5.o +TARGET = ndbapi_event +SRCS = ndbapi_event.cpp +OBJS = ndbapi_event.o CXX = g++ CFLAGS = -c -Wall -fno-rtti -fno-exceptions CXXFLAGS = diff --git a/ndb/examples/ndbapi_example5/ndbapi_example5.cpp b/ndb/examples/ndbapi_event_example/ndbapi_event.cpp index e2e29e2d62c..1c2c9ab5ac4 100644 --- a/ndb/examples/ndbapi_example5/ndbapi_example5.cpp +++ b/ndb/examples/ndbapi_event_example/ndbapi_event.cpp @@ -15,7 +15,38 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** - * ndbapi_example5.cpp: Using API level events in NDB API + * ndbapi_event.cpp: Using API level events in NDB API + * + * Classes and methods used in this example: + * + * Ndb_cluster_connection + * connect() + * wait_until_ready() + * + * Ndb + * init() + * getDictionary() + * createEventOperation() + * dropEventOperation() + * pollEvents() + * + * NdbDictionary + * createEvent() + * dropEvent() + * + * NdbDictionary::Event + * setTable() + * addTableEvent() + * addEventColumn() + * + * NdbEventOperation + * getValue() + * getPreValue() + * execute() + * next() + * isConsistent() + * getEventType() + * */ #include <NdbApi.hpp> @@ -32,12 +63,12 @@ * another process (e.g. flexBench -l 0 -stdtables). * We want to monitor what happens with columns COL0, COL2, COL11 * - * or together with the mysqlcluster client; + * or together with the mysql client; * - * shell> mysqlcluster -u root + * shell> mysql -u root * mysql> create database TEST_DB; * mysql> use TEST_DB; - * mysql> create table TAB0 (COL0 int primary key, COL1 int, COL11 int); + * mysql> create table TAB0 (COL0 int primary key, COL1 int, COL11 int) engine=ndb; * * In another window start ndbapi_example5, wait until properly started * @@ -168,7 +199,7 @@ int main() printf("NULL"); } if (recAttrPre[i]->isNULL() >= 0) { // we have a value - printf(" post[%u]=", i); + printf(" pre[%u]=", i); if (recAttrPre[i]->isNULL() == 0) // we have a non-null value printf("%u", recAttrPre[i]->u_32_value()); else // we have a null value @@ -181,7 +212,7 @@ int main() ;//printf("timed out\n"); } // don't want to listen to events anymore - myNdb->dropEventOperation(op); + if (myNdb->dropEventOperation(op)) APIERROR(myNdb->getNdbError()); j++; } @@ -189,7 +220,8 @@ int main() { NdbDictionary::Dictionary *myDict = myNdb->getDictionary(); if (!myDict) APIERROR(myNdb->getNdbError()); - myDict->dropEvent(eventName); // remove event from database + // remove event from database + if (myDict->dropEvent(eventName)) APIERROR(myDict->getNdbError()); } delete myNdb; @@ -201,8 +233,8 @@ int main() int myCreateEvent(Ndb* myNdb, const char *eventName, const char *eventTableName, - const char **eventColumnName, - const int noEventColumnName) + const char **eventColumnNames, + const int noEventColumnNames) { NdbDictionary::Dictionary *myDict= myNdb->getDictionary(); if (!myDict) APIERROR(myNdb->getNdbError()); @@ -214,24 +246,20 @@ int myCreateEvent(Ndb* myNdb, // myEvent.addTableEvent(NdbDictionary::Event::TE_UPDATE); // myEvent.addTableEvent(NdbDictionary::Event::TE_DELETE); - for (int i = 0; i < noEventColumnName; i++) - myEvent.addEventColumn(eventColumnName[i]); + myEvent.addEventColumns(noEventColumnNames, eventColumnNames); - int res = myDict->createEvent(myEvent); // Add event to database - - if (res == 0) + // Add event to database + if (myDict->createEvent(myEvent) == 0) myEvent.print(); - else { - printf("Event creation failed\n"); - printf("trying drop Event, maybe event exists\n"); - res = myDict->dropEvent(eventName); - if (res) - exit(-1); + else if (myDict->getNdbError().code == 4709) { + printf("Event creation failed, event exists\n"); + printf("dropping Event...\n"); + if (myDict->dropEvent(eventName)) APIERROR(myDict->getNdbError()); // try again - res = myDict->createEvent(myEvent); // Add event to database - if (res) - exit(-1); - } + // Add event to database + if ( myDict->createEvent(myEvent)) APIERROR(myDict->getNdbError()); + } else + APIERROR(myDict->getNdbError()); - return res; + return 0; } diff --git a/ndb/examples/ndbapi_example4/Makefile b/ndb/examples/ndbapi_example4/Makefile deleted file mode 100644 index e4e5320a02c..00000000000 --- a/ndb/examples/ndbapi_example4/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -TARGET = ndbapi_example4 -SRCS = ndbapi_example4.cpp -OBJS = ndbapi_example4.o -CXX = g++ -CFLAGS = -c -Wall -fno-rtti -fno-exceptions -DEBUG = -LFLAGS = -Wall -INCLUDE_DIR = ../../include -LIB_DIR = -L../../src/.libs \ - -L../../../libmysql_r/.libs \ - -L../../../mysys -SYS_LIB = - -$(TARGET): $(OBJS) - $(CXX) $(LFLAGS) $(LIB_DIR) $(OBJS) -lndbclient -lmysqlclient_r -lmysys -lz $(SYS_LIB) -o $(TARGET) - -$(TARGET).o: $(SRCS) - $(CXX) $(CFLAGS) -I$(INCLUDE_DIR) -I$(INCLUDE_DIR)/ndbapi $(SRCS) - -clean: - rm -f *.o $(TARGET) diff --git a/ndb/examples/ndbapi_example4/ndbapi_example4.cpp b/ndb/examples/ndbapi_example4/ndbapi_example4.cpp deleted file mode 100644 index 121a2e05f4b..00000000000 --- a/ndb/examples/ndbapi_example4/ndbapi_example4.cpp +++ /dev/null @@ -1,276 +0,0 @@ -/* Copyright (C) 2003 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -// -// ndbapi_example4.cpp: Using secondary indexes in NDB API -// -// Correct output from this program is: -// -// ATTR1 ATTR2 -// 0 10 -// 1 1 -// 2 12 -// Detected that deleted tuple doesn't exist! -// 4 14 -// 5 5 -// 6 16 -// 7 7 -// 8 18 -// 9 9 - -#include <NdbApi.hpp> - -// Used for cout -#include <stdio.h> -#include <iostream> - -#define APIERROR(error) \ - { std::cout << "Error in " << __FILE__ << ", line:" << __LINE__ << ", code:" \ - << error.code << ", msg: " << error.message << "." << std::endl; \ - exit(-1); } - -int main() -{ - ndb_init(); - - Ndb_cluster_connection *cluster_connection= - new Ndb_cluster_connection(); // 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_1" ); // Object representing the database - NdbDictionary::Table myTable; - NdbDictionary::Column myColumn; - NdbDictionary::Index myIndex; - - NdbTransaction *myTransaction; // For transactions - NdbOperation *myOperation; // For primary key operations - NdbIndexOperation *myIndexOperation; // For index operations - NdbRecAttr *myRecAttr; // Result of reading attribute value - - if (myNdb->init() == -1) { - APIERROR(myNdb->getNdbError()); - exit(-1); - } - - /********************************************************* - * Create a table named MYTABLENAME if it does not exist * - *********************************************************/ - NdbDictionary::Dictionary* myDict = myNdb->getDictionary(); - if (myDict->getTable("MYTABLENAME") != NULL) { - std::cout << "NDB already has example table: MYTABLENAME." << std::endl; - exit(-1); - } - - myTable.setName("MYTABLENAME"); - - myColumn.setName("ATTR1"); - myColumn.setType(NdbDictionary::Column::Unsigned); - myColumn.setLength(1); - myColumn.setPrimaryKey(true); - myColumn.setNullable(false); - myTable.addColumn(myColumn); - - myColumn.setName("ATTR2"); - myColumn.setType(NdbDictionary::Column::Unsigned); - myColumn.setLength(1); - myColumn.setPrimaryKey(false); - myColumn.setNullable(false); - myTable.addColumn(myColumn); - - if (myDict->createTable(myTable) == -1) - APIERROR(myDict->getNdbError()); - - - /********************************************************** - * Create an index named MYINDEXNAME if it does not exist * - **********************************************************/ - if (myDict->getIndex("MYINDEXNAME", "MYTABLENAME") != NULL) { - std::cout << "NDB already has example index: MYINDEXNAME." << std::endl; - exit(-1); - } - - myIndex.setName("MYINDEXNAME"); - myIndex.setTable("MYTABLENAME"); - myIndex.setType(NdbDictionary::Index::UniqueHashIndex); - const char* attr_arr[] = {"ATTR2"}; - myIndex.addIndexColumns(1, attr_arr); - - if (myDict->createIndex(myIndex) == -1) - APIERROR(myDict->getNdbError()); - - - /************************************************************************** - * Using 5 transactions, insert 10 tuples in table: (0,0),(1,1),...,(9,9) * - **************************************************************************/ - for (int i = 0; i < 5; i++) { - myTransaction = myNdb->startTransaction(); - if (myTransaction == NULL) APIERROR(myNdb->getNdbError()); - - myOperation = myTransaction->getNdbOperation("MYTABLENAME"); - if (myOperation == NULL) APIERROR(myTransaction->getNdbError()); - - myOperation->insertTuple(); - myOperation->equal("ATTR1", i); - myOperation->setValue("ATTR2", i); - - myOperation = myTransaction->getNdbOperation("MYTABLENAME"); - if (myOperation == NULL) APIERROR(myTransaction->getNdbError()); - - myOperation->insertTuple(); - myOperation->equal("ATTR1", i+5); - myOperation->setValue("ATTR2", i+5); - - if (myTransaction->execute( Commit ) == -1) - APIERROR(myTransaction->getNdbError()); - - myNdb->closeTransaction(myTransaction); - } - - /***************************************** - * Read and print all tuples using index * - *****************************************/ - std::cout << "ATTR1 ATTR2" << std::endl; - - for (int i = 0; i < 10; i++) { - myTransaction = myNdb->startTransaction(); - if (myTransaction == NULL) APIERROR(myNdb->getNdbError()); - - myIndexOperation = myTransaction->getNdbIndexOperation("MYINDEXNAME", - "MYTABLENAME"); - if (myIndexOperation == NULL) APIERROR(myTransaction->getNdbError()); - - myIndexOperation->readTuple(); - myIndexOperation->equal("ATTR2", i); - - myRecAttr = myIndexOperation->getValue("ATTR1", NULL); - if (myRecAttr == NULL) APIERROR(myTransaction->getNdbError()); - - if(myTransaction->execute( Commit ) != -1) - printf(" %2d %2d\n", myRecAttr->u_32_value(), i); - } - myNdb->closeTransaction(myTransaction); - - /***************************************************************** - * Update the second attribute in half of the tuples (adding 10) * - *****************************************************************/ - for (int i = 0; i < 10; i+=2) { - myTransaction = myNdb->startTransaction(); - if (myTransaction == NULL) APIERROR(myNdb->getNdbError()); - - myIndexOperation = myTransaction->getNdbIndexOperation("MYINDEXNAME", - "MYTABLENAME"); - if (myIndexOperation == NULL) APIERROR(myTransaction->getNdbError()); - - myIndexOperation->updateTuple(); - myIndexOperation->equal( "ATTR2", i ); - myIndexOperation->setValue( "ATTR2", i+10); - - if( myTransaction->execute( Commit ) == -1 ) - APIERROR(myTransaction->getNdbError()); - - myNdb->closeTransaction(myTransaction); - } - - /************************************************* - * Delete one tuple (the one with primary key 3) * - *************************************************/ - myTransaction = myNdb->startTransaction(); - if (myTransaction == NULL) APIERROR(myNdb->getNdbError()); - - myIndexOperation = myTransaction->getNdbIndexOperation("MYINDEXNAME", - "MYTABLENAME"); - if (myIndexOperation == NULL) - APIERROR(myTransaction->getNdbError()); - - myIndexOperation->deleteTuple(); - myIndexOperation->equal( "ATTR2", 3 ); - - if (myTransaction->execute(Commit) == -1) - APIERROR(myTransaction->getNdbError()); - - myNdb->closeTransaction(myTransaction); - - /***************************** - * Read and print all tuples * - *****************************/ - std::cout << "ATTR1 ATTR2" << std::endl; - - for (int i = 0; i < 10; i++) { - myTransaction = myNdb->startTransaction(); - if (myTransaction == NULL) APIERROR(myNdb->getNdbError()); - - myOperation = myTransaction->getNdbOperation("MYTABLENAME"); - if (myOperation == NULL) APIERROR(myTransaction->getNdbError()); - - myOperation->readTuple(); - myOperation->equal("ATTR1", i); - - myRecAttr = myOperation->getValue("ATTR2", NULL); - if (myRecAttr == NULL) APIERROR(myTransaction->getNdbError()); - - if(myTransaction->execute( Commit ) == -1) - if (i == 3) { - std::cout << "Detected that deleted tuple doesn't exist!" << std::endl; - } else { - APIERROR(myTransaction->getNdbError()); - } - - if (i != 3) { - printf(" %2d %2d\n", i, myRecAttr->u_32_value()); - } - myNdb->closeTransaction(myTransaction); - } - - /************** - * Drop index * - **************/ - if (myDict->dropIndex("MYINDEXNAME", "MYTABLENAME") == -1) - APIERROR(myDict->getNdbError()); - - /************** - * Drop table * - **************/ - if (myDict->dropTable("MYTABLENAME") == -1) - APIERROR(myDict->getNdbError()); - - delete myNdb; - delete cluster_connection; - - ndb_end(0); - return 0; -} diff --git a/ndb/examples/ndbapi_example2/Makefile b/ndb/examples/ndbapi_retries_example/Makefile index 53dfb047beb..c7a8946cd9a 100644 --- a/ndb/examples/ndbapi_example2/Makefile +++ b/ndb/examples/ndbapi_retries_example/Makefile @@ -1,6 +1,6 @@ -TARGET = ndbapi_example2 -SRCS = ndbapi_example2.cpp -OBJS = ndbapi_example2.o +TARGET = ndbapi_retries +SRCS = ndbapi_retries.cpp +OBJS = ndbapi_retries.o CXX = g++ CFLAGS = -c -Wall -fno-rtti -fno-exceptions DEBUG = diff --git a/ndb/examples/ndbapi_example3/ndbapi_example3.cpp b/ndb/examples/ndbapi_retries_example/ndbapi_retries.cpp index 9d2014c4eb4..d14e0cf4553 100644 --- a/ndb/examples/ndbapi_example3/ndbapi_example3.cpp +++ b/ndb/examples/ndbapi_retries_example/ndbapi_retries.cpp @@ -15,9 +15,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // -// ndbapi_example3.cpp: Error handling and transaction retries +// ndbapi_retries.cpp: Error handling and transaction retries // -// Execute ndbapi_example1 to create the table "MYTABLENAME" +// Execute ndbapi_simple to create the table "MYTABLENAME" // before executing this program. // // There are many ways to program using the NDB API. In this example @@ -104,7 +104,7 @@ int insert(int transactionId, NdbTransaction* myTransaction) { exit(-1); } - return myTransaction->execute(NoCommit); + return myTransaction->execute(NdbTransaction::NoCommit); } @@ -131,7 +131,7 @@ int executeInsertTransaction(int transactionId, Ndb* myNdb) { result = -1; // Failure } else if (insert(transactionId, myTransaction) || insert(10000+transactionId, myTransaction) || - myTransaction->execute(Commit)) { + myTransaction->execute(NdbTransaction::Commit)) { TRANSERROR(myTransaction); ndberror = myTransaction->getNdbError(); result = -1; // Failure diff --git a/ndb/examples/ndbapi_scan_example/Makefile b/ndb/examples/ndbapi_scan_example/Makefile index 778acab33c7..c5883757e5e 100644 --- a/ndb/examples/ndbapi_scan_example/Makefile +++ b/ndb/examples/ndbapi_scan_example/Makefile @@ -1,13 +1,13 @@ TARGET = ndbapi_scan -SRCS = ndbapi_scan.cpp -OBJS = ndbapi_scan.o +SRCS = $(TARGET).cpp +OBJS = $(TARGET).o CXX = g++ -CFLAGS = -c -Wall -fno-rtti -fno-exceptions -CXXFLAGS = +CFLAGS = -g -c -Wall -fno-rtti -fno-exceptions +CXXFLAGS = -g DEBUG = LFLAGS = -Wall TOP_SRCDIR = ../../.. -INCLUDE_DIR = $(TOP_SRCDIR)/ndb/include +INCLUDE_DIR = $(TOP_SRCDIR) LIB_DIR = -L$(TOP_SRCDIR)/ndb/src/.libs \ -L$(TOP_SRCDIR)/libmysql_r/.libs \ -L$(TOP_SRCDIR)/mysys @@ -17,7 +17,7 @@ $(TARGET): $(OBJS) $(CXX) $(CXXFLAGS) $(LFLAGS) $(LIB_DIR) $(OBJS) -lndbclient -lmysqlclient_r -lmysys -lz $(SYS_LIB) -o $(TARGET) $(TARGET).o: $(SRCS) - $(CXX) $(CFLAGS) -I$(INCLUDE_DIR) -I$(INCLUDE_DIR)/ndbapi $(SRCS) + $(CXX) $(CFLAGS) -I$(INCLUDE_DIR)/include -I$(INCLUDE_DIR)/extra -I$(INCLUDE_DIR)/ndb/include -I$(INCLUDE_DIR)/ndb/include/ndbapi $(SRCS) clean: rm -f *.o $(TARGET) diff --git a/ndb/examples/ndbapi_scan_example/ndbapi_scan.cpp b/ndb/examples/ndbapi_scan_example/ndbapi_scan.cpp index bcbde228895..183dd69f648 100644 --- a/ndb/examples/ndbapi_scan_example/ndbapi_scan.cpp +++ b/ndb/examples/ndbapi_scan_example/ndbapi_scan.cpp @@ -38,8 +38,6 @@ * getNdbScanOperation() * execute() * - * NdbResultSet - * * NdbScanOperation * getValue() * readTuples() @@ -47,21 +45,14 @@ * deleteCurrentTuple() * updateCurrentTuple() * - * NdbDictionary::Dictionary + * const NdbDictionary::Dictionary * getTable() - * dropTable() - * createTable() * - * NdbDictionary::Column - * setName() - * setType() - * setLength() - * setPrimaryKey() - * setNullable() + * const NdbDictionary::Table + * getColumn() * - * NdbDictionary::Table - * setName() - * addColumn() + * const NdbDictionary::Column + * getLength() * * NdbOperation * insertTuple() @@ -76,6 +67,8 @@ */ +#include <mysql.h> +#include <mysqld_error.h> #include <NdbApi.hpp> // Used for cout #include <iostream> @@ -97,10 +90,16 @@ milliSleep(int milliseconds){ /** * Helper sleep function */ -#define APIERROR(error) \ - { std::cout << "Error in " << __FILE__ << ", line:" << __LINE__ << ", code:" \ - << error.code << ", msg: " << error.message << "." << std::endl; \ - exit(-1); } +#define PRINT_ERROR(code,msg) \ + std::cout << "Error in " << __FILE__ << ", line: " << __LINE__ \ + << ", code: " << code \ + << ", msg: " << msg << "." << std::endl +#define MYSQLERROR(mysql) { \ + PRINT_ERROR(mysql_errno(&mysql),mysql_error(&mysql)); \ + exit(-1); } +#define APIERROR(error) { \ + PRINT_ERROR(error.code,error.message); \ + exit(-1); } struct Car { @@ -112,55 +111,26 @@ struct Car /** * Function to create table */ -int create_table(Ndb * myNdb) +int create_table(MYSQL &mysql) { - NdbDictionary::Table myTable; - NdbDictionary::Column myColumn; - - NdbDictionary::Dictionary* myDict = myNdb->getDictionary(); - - /********************************************************* - * Create a table named GARAGE if it does not exist * - *********************************************************/ - if (myDict->getTable("GARAGE") != NULL) { - std::cout << "NDB already has example table: GARAGE. " + while (mysql_query(&mysql, + "CREATE TABLE" + " GARAGE" + " (REG_NO INT UNSIGNED NOT NULL," + " BRAND CHAR(20) NOT NULL," + " COLOR CHAR(20) NOT NULL," + " PRIMARY KEY USING HASH (REG_NO))" + " ENGINE=NDB")) + { + if (mysql_errno(&mysql) != ER_TABLE_EXISTS_ERROR) + MYSQLERROR(mysql); + std::cout << "MySQL Cluster already has example table: GARAGE. " << "Dropping it..." << std::endl; - if(myDict->dropTable("GARAGE") == -1) - { - std::cout << "Failed to drop: GARAGE." << std::endl; - exit(1); - } - } - - Car car; - - myTable.setName("GARAGE"); - - myColumn.setName("REG_NO"); - myColumn.setType(NdbDictionary::Column::Unsigned); - myColumn.setLength(1); - myColumn.setPrimaryKey(true); - myColumn.setNullable(false); - myTable.addColumn(myColumn); - - myColumn.setName("BRAND"); - myColumn.setType(NdbDictionary::Column::Char); - myColumn.setLength(sizeof(car.brand)); - myColumn.setPrimaryKey(false); - myColumn.setNullable(false); - myTable.addColumn(myColumn); - - - myColumn.setName("COLOR"); - myColumn.setType(NdbDictionary::Column::Char); - myColumn.setLength(sizeof(car.color)); - myColumn.setPrimaryKey(false); - myColumn.setNullable(false); - myTable.addColumn(myColumn); - - if (myDict->createTable(myTable) == -1) { - APIERROR(myDict->getNdbError()); - return -1; + /************** + * Drop table * + **************/ + if (mysql_query(&mysql, "DROP TABLE GARAGE")) + MYSQLERROR(mysql); } return 1; } @@ -217,7 +187,7 @@ int populate(Ndb * myNdb) myNdbOperation->setValue("COLOR", cars[i].color); } - int check = myTrans->execute(Commit); + int check = myTrans->execute(NdbTransaction::Commit); myTrans->close(); @@ -310,7 +280,7 @@ int scan_delete(Ndb* myNdb, /** * Start scan (NoCommit since we are only reading at this stage); */ - if(myTrans->execute(NoCommit) != 0){ + if(myTrans->execute(NdbTransaction::NoCommit) != 0){ err = myTrans->getNdbError(); if(err.status == NdbError::TemporaryError){ std::cout << myTrans->getNdbError().message << std::endl; @@ -352,7 +322,7 @@ int scan_delete(Ndb* myNdb, */ if(check != -1) { - check = myTrans->execute(Commit); + check = myTrans->execute(NdbTransaction::Commit); } if(check == -1) @@ -460,7 +430,7 @@ int scan_update(Ndb* myNdb, /** * Define a result set for the scan. */ - if( myScanOp->readTuplesExclusive(NdbOperation::LM_Exclusive) ) + if( myScanOp->readTuples(NdbOperation::LM_Exclusive) ) { std::cout << myTrans->getNdbError().message << std::endl; myNdb->closeTransaction(myTrans); @@ -483,7 +453,7 @@ int scan_update(Ndb* myNdb, /** * Start scan (NoCommit since we are only reading at this stage); */ - if(myTrans->execute(NoCommit) != 0) + if(myTrans->execute(NdbTransaction::NoCommit) != 0) { err = myTrans->getNdbError(); if(err.status == NdbError::TemporaryError){ @@ -531,7 +501,7 @@ int scan_update(Ndb* myNdb, */ if(check != -1) { - check = myTrans->execute(NoCommit); + check = myTrans->execute(NdbTransaction::NoCommit); } /** @@ -555,7 +525,7 @@ int scan_update(Ndb* myNdb, /** * Commit all prepared operations */ - if(myTrans->execute(Commit) == -1) + if(myTrans->execute(NdbTransaction::Commit) == -1) { if(err.status == NdbError::TemporaryError){ std::cout << myTrans->getNdbError().message << std::endl; @@ -670,7 +640,7 @@ int scan_print(Ndb * myNdb) /** * Start scan (NoCommit since we are only reading at this stage); */ - if(myTrans->execute(NoCommit) != 0){ + if(myTrans->execute(NdbTransaction::NoCommit) != 0){ err = myTrans->getNdbError(); if(err.status == NdbError::TemporaryError){ std::cout << myTrans->getNdbError().message << std::endl; @@ -726,36 +696,67 @@ int scan_print(Ndb * myNdb) int main() { ndb_init(); + MYSQL mysql; - Ndb_cluster_connection cluster_connection; + /************************************************************** + * Connect to mysql server and create table * + **************************************************************/ + { + if ( !mysql_init(&mysql) ) { + std::cout << "mysql_init failed\n"; + exit(-1); + } + if ( !mysql_real_connect(&mysql, "localhost", "root", "", "", + 3306, "/tmp/mysql.sock", 0) ) + MYSQLERROR(mysql); + + mysql_query(&mysql, "CREATE DATABASE TEST_DB"); + if (mysql_query(&mysql, "USE TEST_DB") != 0) MYSQLERROR(mysql); - if (cluster_connection.connect(12, 5, 1)) + create_table(mysql); + } + + /************************************************************** + * Connect to ndb cluster * + **************************************************************/ + + Ndb_cluster_connection cluster_connection; + if (cluster_connection.connect(4, 5, 1)) { std::cout << "Unable to connect to cluster within 30 secs." << std::endl; exit(-1); } - - if (cluster_connection.wait_until_ready(30,30)) + // Optionally connect and wait for the storage nodes (ndbd's) + if (cluster_connection.wait_until_ready(30,0) < 0) { - std::cout << "Cluster was not ready within 30 secs." << std::endl; + std::cout << "Cluster was not ready within 30 secs.\n"; exit(-1); } - - Ndb myNdb(&cluster_connection,"TEST_DB" ); - - /******************************************* - * Initialize NDB and wait until its ready * - *******************************************/ - if (myNdb.init(1024) == -1) { // Set max 1024 parallel transactions + + Ndb myNdb(&cluster_connection,"TEST_DB"); + if (myNdb.init(1024) == -1) { // Set max 1024 parallel transactions APIERROR(myNdb.getNdbError()); exit(-1); } - create_table(&myNdb); - - NdbDictionary::Dictionary* myDict = myNdb.getDictionary(); - int column_color = myDict->getTable("GARAGE")->getColumn("COLOR")->getColumnNo(); - + /******************************************* + * Check table definition * + *******************************************/ + int column_color; + { + const NdbDictionary::Dictionary* myDict= myNdb.getDictionary(); + const NdbDictionary::Table *t= myDict->getTable("GARAGE"); + + Car car; + if (t->getColumn("COLOR")->getLength() != sizeof(car.color) || + t->getColumn("BRAND")->getLength() != sizeof(car.brand)) + { + std::cout << "Wrong table definition" << std::endl; + exit(-1); + } + column_color= t->getColumn("COLOR")->getColumnNo(); + } + if(populate(&myNdb) > 0) std::cout << "populate: Success!" << std::endl; @@ -789,4 +790,6 @@ int main() } if(scan_print(&myNdb) > 0) std::cout << "scan_print: Success!" << std::endl << std::endl; + + return 0; } diff --git a/ndb/examples/ndbapi_example1/Makefile b/ndb/examples/ndbapi_simple_example/Makefile index 8b17700d2e2..99d4bfe68a6 100644 --- a/ndb/examples/ndbapi_example1/Makefile +++ b/ndb/examples/ndbapi_simple_example/Makefile @@ -1,4 +1,4 @@ -TARGET = ndbapi_example1 +TARGET = ndbapi_simple SRCS = $(TARGET).cpp OBJS = $(TARGET).o CXX = g++ diff --git a/ndb/examples/ndbapi_example1/ndbapi_example1.cpp b/ndb/examples/ndbapi_simple_example/ndbapi_simple.cpp index 5e42c09c0a9..82b7abc16eb 100644 --- a/ndb/examples/ndbapi_example1/ndbapi_example1.cpp +++ b/ndb/examples/ndbapi_simple_example/ndbapi_simple.cpp @@ -15,7 +15,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* - * ndbapi_example1.cpp: Using synchronous transactions in NDB API + * ndbapi_simple.cpp: Using synchronous transactions in NDB API * * Correct output from this program is: * @@ -72,7 +72,7 @@ int main() } // Optionally connect and wait for the storage nodes (ndbd's) - if (cluster_connection.wait_until_ready(30,30)) + if (cluster_connection.wait_until_ready(30,0) < 0) { std::cout << "Cluster was not ready within 30 secs.\n"; exit(-1); @@ -92,7 +92,6 @@ int main() run_application(mysql, cluster_connection); } - // ndb_end should not be called until all "Ndb" objects are deleted ndb_end(0); std::cout << "\nTo drop created table use:\n" @@ -141,8 +140,8 @@ static void create_table(MYSQL &mysql) if (mysql_query(&mysql, "CREATE TABLE" " MYTABLENAME" - " (ATTR1 INT UNSIGNED PRIMARY KEY," - " ATTR2 INT UNSIGNED)" + " (ATTR1 INT UNSIGNED NOT NULL PRIMARY KEY," + " ATTR2 INT UNSIGNED NOT NULL)" " ENGINE=NDB")) MYSQLERROR(mysql); } @@ -170,7 +169,7 @@ static void do_insert(Ndb &myNdb) myOperation->equal("ATTR1", i+5); myOperation->setValue("ATTR2", i+5); - if (myTransaction->execute( Commit ) == -1) + if (myTransaction->execute( NdbTransaction::Commit ) == -1) APIERROR(myTransaction->getNdbError()); myNdb.closeTransaction(myTransaction); @@ -193,7 +192,7 @@ static void do_update(Ndb &myNdb) myOperation->equal( "ATTR1", i ); myOperation->setValue( "ATTR2", i+10); - if( myTransaction->execute( Commit ) == -1 ) + if( myTransaction->execute( NdbTransaction::Commit ) == -1 ) APIERROR(myTransaction->getNdbError()); myNdb.closeTransaction(myTransaction); @@ -214,7 +213,7 @@ static void do_delete(Ndb &myNdb) myOperation->deleteTuple(); myOperation->equal( "ATTR1", 3 ); - if (myTransaction->execute(Commit) == -1) + if (myTransaction->execute(NdbTransaction::Commit) == -1) APIERROR(myTransaction->getNdbError()); myNdb.closeTransaction(myTransaction); @@ -234,13 +233,13 @@ static void do_read(Ndb &myNdb) NdbOperation *myOperation= myTransaction->getNdbOperation("MYTABLENAME"); if (myOperation == NULL) APIERROR(myTransaction->getNdbError()); - myOperation->readTuple(); + myOperation->readTuple(NdbOperation::LM_Read); myOperation->equal("ATTR1", i); NdbRecAttr *myRecAttr= myOperation->getValue("ATTR2", NULL); if (myRecAttr == NULL) APIERROR(myTransaction->getNdbError()); - if(myTransaction->execute( Commit ) == -1) + if(myTransaction->execute( NdbTransaction::Commit ) == -1) if (i == 3) { std::cout << "Detected that deleted tuple doesn't exist!" << std::endl; } else { diff --git a/ndb/examples/ndbapi_simple_index_example/Makefile b/ndb/examples/ndbapi_simple_index_example/Makefile new file mode 100644 index 00000000000..dc17ff0eeaa --- /dev/null +++ b/ndb/examples/ndbapi_simple_index_example/Makefile @@ -0,0 +1,23 @@ +TARGET = ndbapi_simple_index +SRCS = $(TARGET).cpp +OBJS = $(TARGET).o +CXX = g++ +CFLAGS = -c -Wall -fno-rtti -fno-exceptions +CXXFLAGS = +DEBUG = +LFLAGS = -Wall +TOP_SRCDIR = ../../.. +INCLUDE_DIR = $(TOP_SRCDIR) +LIB_DIR = -L$(TOP_SRCDIR)/ndb/src/.libs \ + -L$(TOP_SRCDIR)/libmysql_r/.libs \ + -L$(TOP_SRCDIR)/mysys +SYS_LIB = + +$(TARGET): $(OBJS) + $(CXX) $(CXXFLAGS) $(LFLAGS) $(LIB_DIR) $(OBJS) -lndbclient -lmysqlclient_r -lmysys -lz $(SYS_LIB) -o $(TARGET) + +$(TARGET).o: $(SRCS) + $(CXX) $(CFLAGS) -I$(INCLUDE_DIR)/include -I$(INCLUDE_DIR)/ndb/include -I$(INCLUDE_DIR)/ndb/include/ndbapi $(SRCS) + +clean: + rm -f *.o $(TARGET) diff --git a/ndb/examples/ndbapi_simple_index_example/ndbapi_simple_index.cpp b/ndb/examples/ndbapi_simple_index_example/ndbapi_simple_index.cpp new file mode 100644 index 00000000000..7d70dc723f8 --- /dev/null +++ b/ndb/examples/ndbapi_simple_index_example/ndbapi_simple_index.cpp @@ -0,0 +1,246 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +// +// ndbapi_simple_index.cpp: Using secondary indexes in NDB API +// +// Correct output from this program is: +// +// ATTR1 ATTR2 +// 0 10 +// 1 1 +// 2 12 +// Detected that deleted tuple doesn't exist! +// 4 14 +// 5 5 +// 6 16 +// 7 7 +// 8 18 +// 9 9 + +#include <mysql.h> +#include <NdbApi.hpp> + +// Used for cout +#include <stdio.h> +#include <iostream> + +#define PRINT_ERROR(code,msg) \ + std::cout << "Error in " << __FILE__ << ", line: " << __LINE__ \ + << ", code: " << code \ + << ", msg: " << msg << "." << std::endl +#define MYSQLERROR(mysql) { \ + PRINT_ERROR(mysql_errno(&mysql),mysql_error(&mysql)); \ + exit(-1); } +#define APIERROR(error) { \ + PRINT_ERROR(error.code,error.message); \ + exit(-1); } + +int main() +{ + ndb_init(); + MYSQL mysql; + + /************************************************************** + * Connect to mysql server and create table * + **************************************************************/ + { + if ( !mysql_init(&mysql) ) { + std::cout << "mysql_init failed\n"; + exit(-1); + } + if ( !mysql_real_connect(&mysql, "localhost", "root", "", "", + 3306, "/tmp/mysql.sock", 0) ) + MYSQLERROR(mysql); + + mysql_query(&mysql, "CREATE DATABASE TEST_DB_1"); + if (mysql_query(&mysql, "USE TEST_DB_1") != 0) MYSQLERROR(mysql); + + if (mysql_query(&mysql, + "CREATE TABLE" + " MYTABLENAME" + " (ATTR1 INT UNSIGNED," + " ATTR2 INT UNSIGNED NOT NULL," + " PRIMARY KEY USING HASH (ATTR1)," + " UNIQUE MYINDEXNAME USING HASH (ATTR2))" + " ENGINE=NDB")) + MYSQLERROR(mysql); + } + + /************************************************************** + * Connect to ndb cluster * + **************************************************************/ + + Ndb_cluster_connection *cluster_connection= + new Ndb_cluster_connection(); // Object representing the cluster + + if (cluster_connection->connect(5,3,1)) + { + std::cout << "Connect to cluster management server failed.\n"; + exit(-1); + } + + if (cluster_connection->wait_until_ready(30,30)) + { + std::cout << "Cluster was not ready within 30 secs.\n"; + exit(-1); + } + + Ndb* myNdb = new Ndb( cluster_connection, + "TEST_DB_1" ); // Object representing the database + if (myNdb->init() == -1) { + APIERROR(myNdb->getNdbError()); + exit(-1); + } + + /************************************************************************** + * Using 5 transactions, insert 10 tuples in table: (0,0),(1,1),...,(9,9) * + **************************************************************************/ + for (int i = 0; i < 5; i++) { + NdbTransaction *myTransaction= myNdb->startTransaction(); + if (myTransaction == NULL) APIERROR(myNdb->getNdbError()); + + NdbOperation *myOperation= myTransaction->getNdbOperation("MYTABLENAME"); + if (myOperation == NULL) APIERROR(myTransaction->getNdbError()); + + myOperation->insertTuple(); + myOperation->equal("ATTR1", i); + myOperation->setValue("ATTR2", i); + + myOperation = myTransaction->getNdbOperation("MYTABLENAME"); + if (myOperation == NULL) APIERROR(myTransaction->getNdbError()); + + myOperation->insertTuple(); + myOperation->equal("ATTR1", i+5); + myOperation->setValue("ATTR2", i+5); + + if (myTransaction->execute( NdbTransaction::Commit ) == -1) + APIERROR(myTransaction->getNdbError()); + + myNdb->closeTransaction(myTransaction); + } + + /***************************************** + * Read and print all tuples using index * + *****************************************/ + std::cout << "ATTR1 ATTR2" << std::endl; + + for (int i = 0; i < 10; i++) { + NdbTransaction *myTransaction= myNdb->startTransaction(); + if (myTransaction == NULL) APIERROR(myNdb->getNdbError()); + + NdbIndexOperation *myIndexOperation= + myTransaction->getNdbIndexOperation("MYINDEXNAME","MYTABLENAME"); + if (myIndexOperation == NULL) APIERROR(myTransaction->getNdbError()); + + myIndexOperation->readTuple(NdbOperation::LM_Read); + myIndexOperation->equal("ATTR2", i); + + NdbRecAttr *myRecAttr= myIndexOperation->getValue("ATTR1", NULL); + if (myRecAttr == NULL) APIERROR(myTransaction->getNdbError()); + + if(myTransaction->execute( NdbTransaction::Commit ) != -1) + printf(" %2d %2d\n", myRecAttr->u_32_value(), i); + + myNdb->closeTransaction(myTransaction); + } + + /***************************************************************** + * Update the second attribute in half of the tuples (adding 10) * + *****************************************************************/ + for (int i = 0; i < 10; i+=2) { + NdbTransaction *myTransaction= myNdb->startTransaction(); + if (myTransaction == NULL) APIERROR(myNdb->getNdbError()); + + NdbIndexOperation *myIndexOperation= + myTransaction->getNdbIndexOperation("MYINDEXNAME", "MYTABLENAME"); + if (myIndexOperation == NULL) APIERROR(myTransaction->getNdbError()); + + myIndexOperation->updateTuple(); + myIndexOperation->equal( "ATTR2", i ); + myIndexOperation->setValue( "ATTR2", i+10); + + if( myTransaction->execute( NdbTransaction::Commit ) == -1 ) + APIERROR(myTransaction->getNdbError()); + + myNdb->closeTransaction(myTransaction); + } + + /************************************************* + * Delete one tuple (the one with primary key 3) * + *************************************************/ + { + NdbTransaction *myTransaction= myNdb->startTransaction(); + if (myTransaction == NULL) APIERROR(myNdb->getNdbError()); + + NdbIndexOperation *myIndexOperation= + myTransaction->getNdbIndexOperation("MYINDEXNAME", "MYTABLENAME"); + if (myIndexOperation == NULL) APIERROR(myTransaction->getNdbError()); + + myIndexOperation->deleteTuple(); + myIndexOperation->equal( "ATTR2", 3 ); + + if (myTransaction->execute(NdbTransaction::Commit) == -1) + APIERROR(myTransaction->getNdbError()); + + myNdb->closeTransaction(myTransaction); + } + + /***************************** + * Read and print all tuples * + *****************************/ + { + std::cout << "ATTR1 ATTR2" << std::endl; + + for (int i = 0; i < 10; i++) { + NdbTransaction *myTransaction= myNdb->startTransaction(); + if (myTransaction == NULL) APIERROR(myNdb->getNdbError()); + + NdbOperation *myOperation= myTransaction->getNdbOperation("MYTABLENAME"); + if (myOperation == NULL) APIERROR(myTransaction->getNdbError()); + + myOperation->readTuple(NdbOperation::LM_Read); + myOperation->equal("ATTR1", i); + + NdbRecAttr *myRecAttr= myOperation->getValue("ATTR2", NULL); + if (myRecAttr == NULL) APIERROR(myTransaction->getNdbError()); + + if(myTransaction->execute( NdbTransaction::Commit ) == -1) + if (i == 3) { + std::cout << "Detected that deleted tuple doesn't exist!\n"; + } else { + APIERROR(myTransaction->getNdbError()); + } + + if (i != 3) { + printf(" %2d %2d\n", i, myRecAttr->u_32_value()); + } + myNdb->closeTransaction(myTransaction); + } + } + + /************** + * Drop table * + **************/ + if (mysql_query(&mysql, "DROP TABLE MYTABLENAME")) + MYSQLERROR(mysql); + + delete myNdb; + delete cluster_connection; + + ndb_end(0); + return 0; +} diff --git a/ndb/examples/select_all/Makefile b/ndb/examples/select_all/Makefile deleted file mode 100644 index 2bec205fa99..00000000000 --- a/ndb/examples/select_all/Makefile +++ /dev/null @@ -1,33 +0,0 @@ --include .defs.mk -#NDB_OS = OS_YOU_ARE_RUNNING_ON -#You need to set the NDB_OS variable here -TARGET = select_all -SRCS = select_all.cpp -OBJS = select_all.o -CXX = g++ -CFLAGS = -c -Wall -fno-rtti -fno-exceptions -DEBUG = -LFLAGS = -Wall -INCLUDE_DIR = ../../include -LIB_DIR = ../../lib -ifeq ($(NDB_OS), SOLARIS) -# Here is the definition of system libraries necessary for Solaris 7 -SYS_LIB = -endif -ifeq ($(NDB_OS), LINUX) -# Here is the definition of system libraries necessary for Linux 2.4 -SYS_LIB = -endif -ifeq ($(NDB_OS), MACOSX) -# Here is the definition of system libraries necessary for Mac OS X -SYS_LIB = -endif - -$(TARGET): $(OBJS) - $(CXX) $(LFLAGS) -L$(LIB_DIR) $(OBJS) -lNDB_API $(SYS_LIB) -o $(TARGET) - -$(TARGET).o: $(SRCS) - $(CXX) $(CFLAGS) -I$(INCLUDE_DIR) -I$(INCLUDE_DIR)/ndbapi $(SRCS) - -clean: - rm -f *.o $(TARGET) diff --git a/ndb/examples/select_all/select_all.cpp b/ndb/examples/select_all/select_all.cpp deleted file mode 100644 index 24bb1214bd2..00000000000 --- a/ndb/examples/select_all/select_all.cpp +++ /dev/null @@ -1,259 +0,0 @@ -/* Copyright (C) 2003 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -// -// select_all.cpp: Prints all rows of a table -// -// Usage: select_all <table_name>+ - -#include <NdbApi.hpp> - -// Used for cout -#include <iostream> -using namespace std; -#include <stdio.h> -#include <string.h> - -#define APIERROR(error) \ - { cout << "Error in " << __FILE__ << ", line:" << __LINE__ << ", code:" \ - << error.code << ", msg: " << error.message << "." << endl; \ - exit(-1); } - -void usage(const char* prg) { - cout << "Usage: " << prg << " <table name>" << endl; - cout << "Prints all rows of table named <table name>" << endl; - exit(0); -} - -/***************************************************************************** - *************************** Result Set Container **************************** - *****************************************************************************/ - -/* - * Container of NdbRecAttr objects. - * (NdbRecAttr objects are database rows read by a scan operation.) - */ -class ResultSetContainer { -public: - /** - * Initialize ResultSetContainer object for table named <tableName> - * - Allocates memory - * - Fetches attribute names from NDB Cluster - */ - void init(NdbDictionary::Dictionary* dict, const char* tableName); - - /** - * Get no of attributes for stored NdbRecAttr objects - */ - int getNoOfAttributes() const; - - /** - * Get NdbRecAttr object no i - */ - NdbRecAttr* & getAttrStore(int i); - - /** - * Get attribute name of attribute no i - */ - const char* getAttrName(int i) const; - - /** - * Print header of rows - */ - void header() const; - -private: - int m_cols; // No of attributes for stored NdbRecAttr objects - char **m_names; // Names of attributes - NdbRecAttr **m_data; // The actual stored NdbRecAttr objects -}; - -void ResultSetContainer::init(NdbDictionary::Dictionary * dict, - const char* tableName) -{ - // Get Table object from NDB (this contains metadata about all tables) - const NdbDictionary::Table * tab = dict->getTable(tableName); - - // Get table id of the table we are interested in - if (tab == 0) APIERROR(dict->getNdbError()); // E.g. table didn't exist - - // Get no of attributes and allocate memory - m_cols = tab->getNoOfColumns(); - m_names = new char* [m_cols]; - m_data = new NdbRecAttr* [m_cols]; - - // Store all attribute names for the table - for (int i = 0; i < m_cols; i++) { - m_names[i] = new char[255]; - BaseString::snprintf(m_names[i], 255, "%s", tab->getColumn(i)->getName()); - } -} - -int ResultSetContainer::getNoOfAttributes() const {return m_cols;} -NdbRecAttr*& ResultSetContainer::getAttrStore(int i) {return m_data[i];} -const char* ResultSetContainer::getAttrName(int i) const {return m_names[i];} - -/***************************************************************************** - ********************************** MAIN *********************************** - *****************************************************************************/ - -int main(int argc, const char** argv) -{ - ndb_init(); - Ndb* myNdb = new Ndb("ndbapi_example4"); // Object representing the database - NdbConnection* myNdbConnection; // For transactions - NdbOperation* myNdbOperation; // For operations - int check; - - if (argc != 2) { - usage(argv[0]); - exit(0); - } - const char* tableName = argv[1]; - - /******************************************* - * Initialize NDB and wait until its ready * - *******************************************/ - if (myNdb->init() == -1) { - APIERROR(myNdb->getNdbError()); - exit(-1); - } - - if (myNdb->waitUntilReady(30) != 0) { - cout << "NDB was not ready within 30 secs." << endl; - exit(-1); - } - - /*************************** - * Define and execute scan * - ***************************/ - cout << "Select * from " << tableName << endl; - - ResultSetContainer * container = new ResultSetContainer; - container->init(myNdb->getDictionary(), tableName); - - myNdbConnection = myNdb->startTransaction(); - if (myNdbConnection == NULL) APIERROR(myNdb->getNdbError()); - - myNdbOperation = myNdbConnection->getNdbOperation(tableName); - if (myNdbOperation == NULL) APIERROR(myNdbConnection->getNdbError()); - - // Define the operation to be an 'openScanRead' operation. - check = myNdbOperation->openScanRead(1); - if (check == -1) APIERROR(myNdbConnection->getNdbError()); - - // Set interpreted program to just be the single instruction - // 'interpret_exit_ok'. (This approves all rows of the table.) - if (myNdbOperation->interpret_exit_ok() == -1) - APIERROR(myNdbConnection->getNdbError()); - - // Get all attribute values of the row - for(int i = 0; i < container->getNoOfAttributes(); i++){ - if((container->getAttrStore(i) = - myNdbOperation->getValue(container->getAttrName(i))) == 0) - APIERROR(myNdbConnection->getNdbError()); - } - - // Execute scan operation - check = myNdbConnection->executeScan(); - if (check == -1) APIERROR(myNdbConnection->getNdbError()); - - /**************** - * Print header * - ****************/ - for (int i = 0; i < container->getNoOfAttributes(); i++) - cout << container->getAttrName(i) << "\t"; - - cout << endl; - for (int i = 0; i < container->getNoOfAttributes(); i++) { - for (int j = strlen(container->getAttrName(i)); j > 0; j--) - cout << "-"; - cout << "\t"; - } - cout << "\n"; - - /************** - * Scan table * - **************/ - int eof; - int rows = 0; - - // Print all rows of table - while ((eof = myNdbConnection->nextScanResult()) == 0) { - rows++; - - for (int i = 0; i < container->getNoOfAttributes(); i++) { - if (container->getAttrStore(i)->isNULL()) { - cout << "NULL"; - } else { - - // Element size of value (No of bits per element in attribute value) - const int size = container->getAttrStore(i)->attrSize(); - - // No of elements in an array attribute (Is 1 if non-array attribute) - const int aSize = container->getAttrStore(i)->arraySize(); - - switch(container->getAttrStore(i)->attrType()){ - case UnSigned: - switch(size) { - case 8: cout << container->getAttrStore(i)->u_64_value(); break; - case 4: cout << container->getAttrStore(i)->u_32_value(); break; - case 2: cout << container->getAttrStore(i)->u_short_value(); break; - case 1: cout << (unsigned) container->getAttrStore(i)->u_char_value(); - break; - default: cout << "Unknown size" << endl; - } - break; - - case Signed: - switch(size) { - case 8: cout << container->getAttrStore(i)->int64_value(); break; - case 4: cout << container->getAttrStore(i)->int32_value(); break; - case 2: cout << container->getAttrStore(i)->short_value(); break; - case 1: cout << (int) container->getAttrStore(i)->char_value(); break; - default: cout << "Unknown size" << endl; - } - break; - - case String: - { - char* buf = new char[aSize+1]; - memcpy(buf, container->getAttrStore(i)->aRef(), aSize); - buf[aSize] = 0; - cout << buf; - delete [] buf; - } - break; - - case Float: - cout << container->getAttrStore(i)->float_value(); - break; - - default: - cout << "Unknown"; - break; - } - } - cout << "\t"; - } - cout << endl; - } - if (eof == -1) APIERROR(myNdbConnection->getNdbError()); - - myNdb->closeTransaction(myNdbConnection); - - cout << "Selected " << rows << " rows." << endl; -} diff --git a/ndb/include/kernel/signaldata/CreateEvnt.hpp b/ndb/include/kernel/signaldata/CreateEvnt.hpp index e911fa36ce6..c381377c54f 100644 --- a/ndb/include/kernel/signaldata/CreateEvnt.hpp +++ b/ndb/include/kernel/signaldata/CreateEvnt.hpp @@ -101,7 +101,7 @@ public: Busy = 701, NotMaster = 702, SeizeError = 703, - EventNotFound = 4238, + EventNotFound = 4710, EventNameTooLong = 4241, TooManyEvents = 4242, BadRequestType = 4247, @@ -363,11 +363,10 @@ struct CreateEvntRef { Busy = 701, NotMaster = 702, SeizeError = 703, - EventNotFound = 4238, - EventExists = 4239, - EventNameTooLong = 4241, - TooManyEvents = 4242, - // EventExists = 4244, + TooManyEvents = 4707, + EventNameTooLong = 4708, + EventExists = 4709, + EventNotFound = 4731, AttributeNotStored = 4245, AttributeNullable = 4246, BadRequestType = 4247, @@ -376,7 +375,7 @@ struct CreateEvntRef { InvalidEventType = 4250, NotUnique = 4251, AllocationError = 4252, - CreateEventTableFailed = 4253, + CreateEventTableFailed = 4711, InvalidAttributeOrder = 4255, Temporary = 0x1 << 16 }; diff --git a/ndb/include/ndb_global.h.in b/ndb/include/ndb_global.h.in index d7a5cb1b1cf..dd1d1c05db8 100644 --- a/ndb/include/ndb_global.h.in +++ b/ndb/include/ndb_global.h.in @@ -14,8 +14,8 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef NDBGLOBAL_H -#define NDBGLOBAL_H +#ifndef NDB_GLOBAL_H +#define NDB_GLOBAL_H #include <ndb_types.h> @@ -31,45 +31,22 @@ #define HAVE_STRCASECMP #define strcasecmp _strcmpi #pragma warning(disable: 4503 4786) -typedef unsigned __int64 Uint64; -typedef signed __int64 Int64; #else #undef NDB_WIN32 #define DIR_SEPARATOR "/" -typedef unsigned long long Uint64; -typedef signed long long Int64; #endif #include <my_global.h> -typedef signed char Int8; -typedef unsigned char Uint8; -typedef signed short Int16; -typedef unsigned short Uint16; -typedef signed int Int32; -typedef unsigned int Uint32; - -typedef unsigned int UintR; - -#ifdef __SIZE_TYPE__ -typedef __SIZE_TYPE__ UintPtr; -#elif SIZEOF_CHARP == 4 -typedef Uint32 UintPtr; -#elif SIZEOF_CHARP == 8 -typedef Uint64 UintPtr; -#else -#error "Unknown size of (char *)" -#endif - -#if ! (SIZEOF_CHAR == 1) +#if ! (NDB_SIZEOF_CHAR == SIZEOF_CHAR) #error "Invalid define for Uint8" #endif -#if ! (SIZEOF_INT == 4) +#if ! (NDB_SIZEOF_INT == SIZEOF_INT) #error "Invalid define for Uint32" #endif -#if ! (SIZEOF_LONG_LONG == 8) +#if ! (NDB_SIZEOF_LONG_LONG == SIZEOF_LONG_LONG) #error "Invalid define for Uint64" #endif diff --git a/ndb/include/ndb_types.h b/ndb/include/ndb_types.h deleted file mode 100644 index 300765cb775..00000000000 --- a/ndb/include/ndb_types.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright (C) 2003 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/** - * @file ndb_types.h - */ - -#ifndef NDB_TYPES_H -#define NDB_TYPES_H - -#include "ndb_global.h" -#include "ndb_constants.h" - -#endif diff --git a/ndb/include/ndb_types.h.in b/ndb/include/ndb_types.h.in new file mode 100644 index 00000000000..2a5d576ffea --- /dev/null +++ b/ndb/include/ndb_types.h.in @@ -0,0 +1,81 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/** + * @file ndb_types.h + */ + +#ifndef NDB_TYPES_H +#define NDB_TYPES_H + +#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(_WIN64) +#define NDB_SIZEOF_CHARP SIZEOF_CHARP +#define NDB_SIZEOF_CHAR SIZEOF_CHAR +#define NDB_SIZEOF_SHORT 2 +#define NDB_SIZEOF_INT SIZEOF_INT +#define NDB_SIZEOF_LONG SIZEOF_LONG +#define NDB_SIZEOF_LONG_LONG SIZEOF_LONG_LONG +typedef unsigned __int64 Uint64; +typedef signed __int64 Int64; +#else +#define NDB_SIZEOF_CHARP @NDB_SIZEOF_CHARP@ +#define NDB_SIZEOF_CHAR @NDB_SIZEOF_CHAR@ +#define NDB_SIZEOF_INT @NDB_SIZEOF_INT@ +#define NDB_SIZEOF_SHORT @NDB_SIZEOF_SHORT@ +#define NDB_SIZEOF_LONG @NDB_SIZEOF_LONG@ +#define NDB_SIZEOF_LONG_LONG @NDB_SIZEOF_LONG_LONG@ +typedef unsigned long long Uint64; +typedef signed long long Int64; +#endif + +typedef signed char Int8; +typedef unsigned char Uint8; +typedef signed short Int16; +typedef unsigned short Uint16; +typedef signed int Int32; +typedef unsigned int Uint32; + +typedef unsigned int UintR; + +#ifdef __SIZE_TYPE__ + typedef __SIZE_TYPE__ UintPtr; +#elif NDB_SIZEOF_CHARP == 4 + typedef Uint32 UintPtr; +#elif NDB_SIZEOF_CHARP == 8 + typedef Uint64 UintPtr; +#else + #error "Unknown size of (char *)" +#endif + +#if ! (NDB_SIZEOF_CHAR == 1) +#error "Invalid define for Uint8" +#endif + +#if ! (NDB_SIZEOF_SHORT == 2) +#error "Invalid define for Uint16" +#endif + +#if ! (NDB_SIZEOF_INT == 4) +#error "Invalid define for Uint32" +#endif + +#if ! (NDB_SIZEOF_LONG_LONG == 8) +#error "Invalid define for Uint64" +#endif + +#include "ndb_constants.h" + +#endif diff --git a/ndb/include/ndbapi/Ndb.hpp b/ndb/include/ndbapi/Ndb.hpp index 97e869baf9b..dcde0a66872 100644 --- a/ndb/include/ndbapi/Ndb.hpp +++ b/ndb/include/ndbapi/Ndb.hpp @@ -25,7 +25,7 @@ that implements transactions. The NDB API consists of the following fundamental classes: - Ndb_cluster_connection, representing a connection to a cluster, - - Ndb is the main class, representing the database, + - Ndb is the main class, representing a connection to a database, - NdbTransaction represents a transaction, - NdbOperation represents an operation using a primary key, - NdbScanOperation represents an operation performing a full table scan. @@ -44,15 +44,15 @@ The main structure of an application program is as follows: -# Construct and connect to a cluster using the Ndb_cluster_connection object. - -# Construct and initialize Ndb object(s). - -# Define and execute transactions using NdbTransaction and Ndb*Operation. - -# Delete Ndb objects - -# Delete cluster connection + -# Construct and initialize Ndb object(s) to connect to a database. + -# Define and execute transactions using NdbTransaction. + -# Delete Ndb objects. + -# Delete cluster connection. The main structure of a transaction is as follows: -# Start transaction (an NdbTransaction) -# Add and define operations associated with the transaction using - Ndb*Operation + NdbOperation, NdbScanOperation, NdbIndexOperation, NdbIndexScanOperation -# Execute transaction The execution can be of two different types, @@ -65,8 +65,9 @@ for later execution. If the execute is of type <var>Commit</var>, then the transaction is - committed, and no further addition or definition of operations - is allowed. + committed. The transaction <em>must</em> be closed after it has been + commited (event if commit fails), and no further addition or definition of + operations is allowed. @section secSync Synchronous Transactions @@ -78,14 +79,18 @@ (typically created using Ndb::startTransaction()). At this point, the transaction is only being defined, and is not yet sent to the NDB kernel. - -# Define operations and add them to the transaction, - using NdbTransaction::getNdb*Operation() and - methods of the Ndb*Operation class. + -# Define operations and add them to the transaction, using + NdbTransaction::getNdbOperation(), + NdbTransaction::getNdbScanOperation(), + NdbTransaction::getNdbIndexOperation(), or + NdbTransaction::getNdbIndexScanOperation(), + and methods of the respective NdbOperation class. Note that the transaction has still not yet been sent to the NDB kernel. -# Execute the transaction, using the NdbTransaction::execute() method. -# Close the transaction (using Ndb::closeTransaction()). - For an example of this process, see the program listing in @ref ndbapi_example1.cpp. + For an example of this process, see the program listing in + @ref ndbapi_simple.cpp. To execute several parallel synchronous transactions, one can either use multiple Ndb objects in several threads, or start multiple @@ -93,9 +98,9 @@ @section secNdbOperations Operations - Each NdbTransaction - consists of a list of operations which are represented by instances - of Ndb*Operation. + Each NdbTransaction consists of a list of operations which are represented + by instances of NdbOperation, NdbScanOperation, NdbIndexOperation, and/or + NdbIndexScanOperation. <h3>Single row operations</h3> After the operation is created using NdbTransaction::getNdbOperation() @@ -105,8 +110,8 @@ -# Specify search conditions, using NdbOperation::equal() -# Specify attribute actions, using NdbOperation::getValue() - Here are two brief examples illustrating this process. For the sake of brevity, - we omit error-handling. + Here are two brief examples illustrating this process. For the sake of + brevity, we omit error-handling. This first example uses an NdbOperation: @code @@ -122,12 +127,12 @@ // 4. Attribute Actions MyRecAttr= MyOperation->getValue("ATTR2", NULL); @endcode - For additional examples of this sort, see @ref ndbapi_example1.cpp. + For additional examples of this sort, see @ref ndbapi_simple.cpp. The second example uses an NdbIndexOperation: @code // 1. Create - MyOperation= MyTransaction->getNdbIndexOperation("MYINDEX", "MYTABLENAME"); + MyOperation= MyTransaction->getNdbIndexOperation("MYINDEX","MYTABLENAME"); // 2. Define type of operation and lock mode MyOperation->readTuple(NdbOperation::LM_Read); @@ -138,10 +143,11 @@ // 4. Attribute Actions MyRecAttr = MyOperation->getValue("ATTR2", NULL); @endcode - Another example of this second type can be found in @ref ndbapi_example4.cpp. + Another example of this second type can be found in + @ref ndbapi_simple_index.cpp. - We will now discuss in somewhat greater detail each step involved in the creation - and use of synchronous transactions. + We will now discuss in somewhat greater detail each step involved in the + creation and use of synchronous transactions. <h4>Step 1: Define single row operation type</h4> The following types of operations exist: @@ -162,18 +168,11 @@ operate on a defined unique hash index.) @note If you want to define multiple operations within the same transaction, - then you need to call NdbTransaction::getNdb*Operation for each - operation. + then you need to call NdbTransaction::getNdbOperation() or + NdbTransaction::getNdbIndexOperation() for each operation. <h4>Step 2: Specify Search Conditions</h4> - The search condition is used to select tuples. - - For NdbOperation::insertTuple it is also allowed to define the - search key by using NdbOperation::setValue. - The NDB API will automatically detect that it is - supposed to use NdbOperation::equal instead. - For NdbOperation::insertTuple it is not necessary to use - NdbOperation::setValue on key attributes before other attributes. + The search condition is used to select tuples using NdbOperation::equal() <h4>Step 3: Specify Attribute Actions</h4> Now it is time to define which attributes should be read or updated. @@ -183,21 +182,21 @@ also possible to use the attribute identity to define the attribute. - NdbOperation::getValue returns an NdbRecAttr object + NdbOperation::getValue() returns an NdbRecAttr object containing the read value. To get the value, there is actually two methods. The application can either - use its own memory (passed through a pointer aValue) to - NdbOperation::getValue, or + NdbOperation::getValue(), or - receive the attribute value in an NdbRecAttr object allocated by the NDB API. - The NdbRecAttr object is released when Ndb::closeTransaction + The NdbRecAttr object is released when Ndb::closeTransaction() is called. Thus, the application can not reference this object after - Ndb::closeTransaction have been called. + Ndb::closeTransaction() have been called. The result of reading data from an NdbRecAttr object before - calling NdbTransaction::execute is undefined. + calling NdbTransaction::execute() is undefined. @subsection secScan Scan Operations @@ -214,16 +213,17 @@ - They can operate on several nodes in parallell After the operation is created using NdbTransaction::getNdbScanOperation() - (or NdbTransaction::getNdbIndexScanOperation()), it is defined in the following - three steps: + (or NdbTransaction::getNdbIndexScanOperation()), + it is defined in the following three steps: -# Define the standard operation type, using NdbScanOperation::readTuples() - -# Specify search conditions, using @ref NdbScanFilter and/or @ref NdbIndexScanOperation::setBound + -# Specify search conditions, using @ref NdbScanFilter and/or + @ref NdbIndexScanOperation::setBound() -# Specify attribute actions, using NdbOperation::getValue() -# Executing the transaction, using NdbTransaction::execute() - -# Iterating through the result set using NdbScanOperation::nextResult + -# Iterating through the result set using NdbScanOperation::nextResult() - Here are two brief examples illustrating this process. For the sake of brevity, - we omit error-handling. + Here are two brief examples illustrating this process. For the sake of + brevity, we omit error-handling. This first example uses an NdbScanOperation: @code @@ -262,11 +262,14 @@ @endcode <h4>Step 1: Define scan operation operation type</h4> - Scan operations only support 1 operation, @ref NdbScanOperation::readTuples or @ref NdbIndexScanOperation::readTuples + Scan operations only support 1 operation, + @ref NdbScanOperation::readTuples() + or @ref NdbIndexScanOperation::readTuples() - @note If you want to define multiple scan operations within the same transaction, - then you need to call NdbTransaction::getNdb*ScanOperation for each - operation. + @note If you want to define multiple scan operations within the same + transaction, then you need to call + NdbTransaction::getNdbScanOperation() or + NdbTransaction::getNdbIndexScanOperation() for each operation. <h4>Step 2: Specify Search Conditions</h4> The search condition is used to select tuples. @@ -288,33 +291,32 @@ also possible to use the attribute identity to define the attribute. - NdbOperation::getValue returns an NdbRecAttr object + NdbOperation::getValue() returns an NdbRecAttr object containing the read value. To get the value, there is actually two methods. The application can either - use its own memory (passed through a pointer aValue) to - NdbOperation::getValue, or + NdbOperation::getValue(), or - receive the attribute value in an NdbRecAttr object allocated by the NDB API. - The NdbRecAttr object is released when Ndb::closeTransaction - is called. - Thus, the application can not reference this object after - Ndb::closeTransaction have been called. + The NdbRecAttr object is released when Ndb::closeTransaction() + is called. Thus, the application can not reference this object after + Ndb::closeTransaction() have been called. The result of reading data from an NdbRecAttr object before - calling NdbTransaction::execute is undefined. + calling NdbTransaction::execute() is undefined. <h3> Using Scan to update/delete </h3> Scanning can also be used to update/delete rows. This is performed by -# Scan using exclusive locks, NdbOperation::LM_Exclusive -# When iterating through the result set, for each row optionally call - either NdbScanOperation::updateCurrentTuple or - NdbScanOperation::deleteCurrentTuple - -# If performing NdbScanOperation::updateCurrentTuple, - set new values on record using ordinary @ref NdbOperation::setValue. - NdbOperation::equal should _not_ be called as the primary key is - retreived from the scan. + either NdbScanOperation::updateCurrentTuple() or + NdbScanOperation::deleteCurrentTuple() + -# If performing NdbScanOperation::updateCurrentTuple(), + set new values on record using ordinary @ref NdbOperation::setValue(). + NdbOperation::equal() should <em>not</em> be called as the primary + key is retreived from the scan. @note that the actual update/delete will not be performed until next NdbTransaction::execute (as with single row operations), @@ -323,13 +325,16 @@ <h4> Index scans specific features </h4> The following features are available when performing an index scan - - Scan subset of table using @ref NdbIndexScanOperation::setBound - - Ordering result set ascending or descending, @ref NdbIndexScanOperation::readTuples - - When using NdbIndexScanOperation::BoundEQ on distribution key - only fragment containing rows will be scanned. + - Scan subset of table using @ref NdbIndexScanOperation::setBound() + - Ordering result set ascending or descending, + @ref NdbIndexScanOperation::readTuples() + - When using NdbIndexScanOperation::BoundEQ on partition key + only fragments containing rows will be scanned. Rows are returned unordered unless sorted is set to true. - @note When performing sorted scan, parameter parallelism to readTuples will + + @note When performing sorted scan, parameter parallelism to + NdbIndexScanOperation::readTuples() will be ignored and max parallelism will be used instead. @subsection secScanLocks Lock handling with scans @@ -339,11 +344,11 @@ But Ndb will only lock a batch of rows per fragment at a time. How many rows will be locked per fragment is controlled by the - batch parameter to @ref NdbScanOperation::readTuples. + batch parameter to NdbScanOperation::readTuples(). To let the application handle how locks are released - @ref NdbScanOperation::nextResult have a parameter fetch_allow. - If NdbScanOperation::nextResult is called with fetch_allow = false, no + NdbScanOperation::nextResult() have a parameter fetch_allow. + If NdbScanOperation::nextResult() is called with fetch_allow = false, no locks may be released as result of the function call. Otherwise the locks for the current batch may be released. @@ -376,11 +381,12 @@ One recommended way to handle a transaction failure (i.e. an error is reported) is to: - -# Rollback transaction (NdbTransaction::execute with a special parameter) + -# Rollback transaction (NdbTransaction::execute() with a special parameter) -# Close transaction -# Restart transaction (if the error was temporary) - @note Transaction are not automatically closed when an error occur. + @note Transactions are not automatically closed when an error occur. Call + Ndb::closeTransaction() to close. Several errors can occur when a transaction holds multiple operations which are simultaneously executed. @@ -388,9 +394,9 @@ objects and query for their NdbError objects to find out what really happened. - NdbTransaction::getNdbErrorOperation returns a reference to the + NdbTransaction::getNdbErrorOperation() returns a reference to the operation causing the latest error. - NdbTransaction::getNdbErrorLine delivers the method number of the + NdbTransaction::getNdbErrorLine() delivers the method number of the erroneous method in the operation. @code @@ -413,35 +419,35 @@ Getting errorLine == 0 means that the error occurred when executing the operations. Here errorOperation will be a pointer to the theOperation object. - NdbTransaction::getNdbError will return the NdbError object + NdbTransaction::getNdbError() will return the NdbError object including holding information about the error. Since errors could have occurred even when a commit was reported, - there is also a special method, NdbTransaction::commitStatus, + there is also a special method, NdbTransaction::commitStatus(), to check the commit status of the transaction. -*******************************************************************************/ +******************************************************************************/ /** - * @page ndbapi_example1.cpp ndbapi_example1.cpp - * @include ndbapi_example1.cpp + * @page ndbapi_simple.cpp ndbapi_simple.cpp + * @include ndbapi_simple.cpp */ #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL /** - * @page ndbapi_example2.cpp ndbapi_example2.cpp - * @include ndbapi_example2.cpp + * @page ndbapi_async1.cpp ndbapi_async1.cpp + * @include ndbapi_async1.cpp */ #endif /** - * @page ndbapi_example3.cpp ndbapi_example3.cpp - * @include ndbapi_example3.cpp + * @page ndbapi_retries.cpp ndbapi_retries.cpp + * @include ndbapi_retries.cpp */ /** - * @page ndbapi_example4.cpp ndbapi_example4.cpp - * @include ndbapi_example4.cpp + * @page ndbapi_simple_index.cpp ndbapi_simple_index.cpp + * @include ndbapi_simple_index.cpp */ /** @@ -454,32 +460,14 @@ @page secAdapt Adaptive Send Algorithm At the time of "sending" the transaction - (using NdbTransaction::execute), the transactions + (using NdbTransaction::execute()), the transactions are in reality <em>not</em> immediately transfered to the NDB Kernel. Instead, the "sent" transactions are only kept in a special send list (buffer) in the Ndb object to which they belong. The adaptive send algorithm decides when transactions should be transfered to the NDB kernel. - For each of these "sent" transactions, there are three - possible states: - -# Waiting to be transferred to NDB Kernel. - -# Has been transferred to the NDB Kernel and is currently - being processed. - -# Has been transferred to the NDB Kernel and has - finished processing. - Now it is waiting for a call to a poll method. - (When the poll method is invoked, - then the transaction callback method will be executed.) - - The poll method invoked (either Ndb::pollNdb or Ndb::sendPollNdb) - will return when: - -# at least 'minNoOfEventsToWakeup' of the transactions - in the send list have transitioned to state 3 as described above, and - -# all of these transactions have executed their callback methods. - - - Since the NDB API is designed as a multi-threaded interface, + The NDB API is designed as a multi-threaded interface and it is desirable to transfer database operations from more than one thread at a time. The NDB API keeps track of which Ndb objects are active in transfering @@ -510,14 +498,36 @@ later releases of NDB Cluster. However, to support faster than 10 ms checks, there has to be support from the operating system. - -# When calling NdbTransaction::execute synchronously or calling any - of the poll-methods, there is a force parameter that overrides the - adaptive algorithm and forces the send to all nodes. + -# When methods that are affected by the adaptive send alorithm, + e.g. NdbTransaction::execute(), there is a force parameter + that overrides it forces the send to all nodes. - @note The times mentioned above are examples. These might + @note The reasons mentioned above are examples. These might change in later releases of NDB Cluster. */ +#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL +/** + + For each of these "sent" transactions, there are three + possible states: + -# Waiting to be transferred to NDB Kernel. + -# Has been transferred to the NDB Kernel and is currently + being processed. + -# Has been transferred to the NDB Kernel and has + finished processing. + Now it is waiting for a call to a poll method. + (When the poll method is invoked, + then the transaction callback method will be executed.) + + The poll method invoked (either Ndb::pollNdb() or Ndb::sendPollNdb()) + will return when: + -# at least 'minNoOfEventsToWakeup' of the transactions + in the send list have transitioned to state 3 as described above, and + -# all of these transactions have executed their callback methods. +*/ +#endif + /** @page secConcepts NDB Cluster Concepts @@ -559,14 +569,17 @@ The application programmer can however hint the NDB API which transaction coordinator to use - by providing a <em>distribution key</em> (usually the primary key). - By using the primary key as distribution key, + by providing a <em>partition key</em> (usually the primary key). + By using the primary key as partition key, the transaction will be placed on the node where the primary replica of that record resides. Note that this is only a hint, the system can be reconfigured and then the NDB API will choose a transaction coordinator without using the hint. - For more information, see NdbDictionary::Column::setDistributionKey. + For more information, see NdbDictionary::Column::getPartitionKey(), + Ndb::startTransaction(). The application programmer can specify + the partition key from SQL by using the construct, + "CREATE TABLE ... ENGINE=NDB PARTITION BY KEY (<attribute list>)". @section secRecordStruct Record Structure @@ -635,7 +648,7 @@ A simple example is an application that uses many simple updates where a transaction needs to update one record. This record has a 32 bit primary key, - which is also the distribution key. + which is also the partition key. Then the keyData will be the address of the integer of the primary key and keyLen will be 4. */ diff --git a/ndb/include/ndbapi/NdbBlob.hpp b/ndb/include/ndbapi/NdbBlob.hpp index c02e10b7b76..f9090cb91ba 100644 --- a/ndb/include/ndbapi/NdbBlob.hpp +++ b/ndb/include/ndbapi/NdbBlob.hpp @@ -309,8 +309,8 @@ private: int invokeActiveHook(); // blob handle maintenance int atPrepare(NdbTransaction* aCon, NdbOperation* anOp, const NdbColumnImpl* aColumn); - int preExecute(ExecType anExecType, bool& batch); - int postExecute(ExecType anExecType); + int preExecute(NdbTransaction::ExecType anExecType, bool& batch); + int postExecute(NdbTransaction::ExecType anExecType); int preCommit(); int atNextResult(); // errors diff --git a/ndb/include/ndbapi/NdbDictionary.hpp b/ndb/include/ndbapi/NdbDictionary.hpp index c495690a7dc..700591d6cdf 100644 --- a/ndb/include/ndbapi/NdbDictionary.hpp +++ b/ndb/include/ndbapi/NdbDictionary.hpp @@ -56,7 +56,7 @@ typedef struct charset_info_st CHARSET_INFO; * -# NdbDictionary::Column for creating table columns * -# NdbDictionary::Index for creating secondary indexes * - * See @ref ndbapi_example4.cpp for details of usage. + * See @ref ndbapi_simple_index.cpp for details of usage. */ class NdbDictionary { public: @@ -286,14 +286,14 @@ public: int getSize() const; /** - * Check if column is part of distribution key + * Check if column is part of partition key * - * A <em>distribution key</em> is a set of attributes which are used + * A <em>partition key</em> is a set of attributes which are used * to distribute the tuples onto the NDB nodes. - * The distribution key uses the NDB Cluster hashing function. + * The partition key uses the NDB Cluster hashing function. * * An example where this is useful is TPC-C where it might be - * good to use the warehouse id and district id as the distribution key. + * good to use the warehouse id and district id as the partition key. * This would place all data for a specific district and warehouse * in the same database node. * @@ -301,9 +301,12 @@ public: * will still be used with the hashing algorithm. * * @return true then the column is part of - * the distribution key. + * the partition key. */ - bool getDistributionKey() const; + bool getPartitionKey() const; +#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED + inline bool getDistributionKey() const { return getPartitionKey(); }; +#endif /** @} *******************************************************************/ @@ -401,13 +404,17 @@ public: void setStripeSize(int size); /** - * Set distribution key - * @see getDistributionKey + * Set partition key + * @see getPartitionKey * * @param enable If set to true, then the column will be part of - * the distribution key. + * the partition key. */ - void setDistributionKey(bool enable); + void setPartitionKey(bool enable); +#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED + inline void setDistributionKey(bool enable) + { setPartitionKey(enable); }; +#endif /** @} *******************************************************************/ @@ -691,7 +698,7 @@ public: /** @} *******************************************************************/ -#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED +#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL void setStoredTable(bool x) { setLogging(x); } bool getStoredTable() const { return getLogging(); } @@ -894,32 +901,80 @@ public: */ class Event : public Object { public: - enum TableEvent { TE_INSERT=1, TE_DELETE=2, TE_UPDATE=4, TE_ALL=7 }; + enum TableEvent { + TE_INSERT=1, ///< Insert event on table + TE_DELETE=2, ///< Delete event on table + TE_UPDATE=4, ///< Update event on table + TE_ALL=7 ///< Any/all event on table (not relevant when + ///< events are received) + }; enum EventDurability { - ED_UNDEFINED = 0, + ED_UNDEFINED +#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL + = 0 +#endif #if 0 // not supported - ED_SESSION = 1, + ,ED_SESSION = 1, // Only this API can use it // and it's deleted after api has disconnected or ndb has restarted - ED_TEMPORARY = 2, + ED_TEMPORARY = 2 // All API's can use it, // But's its removed when ndb is restarted -#endif - ED_PERMANENT = 3 - // All API's can use it, - // It's still defined after a restart +#endif + ,ED_PERMANENT ///< All API's can use it, + ///< It's still defined after a restart +#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL + = 3 +#endif }; Event(const char *name); virtual ~Event(); - void setName(const char *); - void setTable(const char *); - void addTableEvent(const TableEvent); - void setDurability(const EventDurability); + /** + * Set unique identifier for the event + */ + void setName(const char *name); + /** + * Set table for which events should be detected + */ + void setTable(const char *tableName); + /** + * Add type of event that should be detected + */ + void addTableEvent(const TableEvent te); + /** + * Set durability of the event + */ + void setDurability(const EventDurability ed); +#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL void addColumn(const Column &c); +#endif + /** + * Add a column on which events should be detected + * + * @param attrId Column id + * + * @note errors will mot be detected until createEvent() is called + */ void addEventColumn(unsigned attrId); + /** + * Add a column on which events should be detected + * + * @param columnName Column name + * + * @note errors will mot be detected until createEvent() is called + */ void addEventColumn(const char * columnName); + /** + * Add several columns on which events should be detected + * + * @param n Number of columns + * @param columnNames Column names + * + * @note errors will mot be detected until + * NdbDictionary::Dictionary::createEvent() is called + */ void addEventColumns(int n, const char ** columnNames); /** @@ -932,7 +987,9 @@ public: */ virtual int getObjectVersion() const; +#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL void print(); +#endif private: #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL @@ -1003,6 +1060,8 @@ public: * Fetch list of all objects, optionally restricted to given type. */ int listObjects(List & list, Object::Type type = Object::TypeUndefined); + int listObjects(List & list, + Object::Type type = Object::TypeUndefined) const; /** * Get the latest error @@ -1023,7 +1082,7 @@ public: * @param name Name of table to get * @return table if successful otherwise NULL. */ - const Table * getTable(const char * name); + const Table * getTable(const char * name) const; /** * Get index with given name, NULL if undefined @@ -1032,7 +1091,7 @@ public: * @return index if successful, otherwise 0. */ const Index * getIndex(const char * indexName, - const char * tableName); + const char * tableName) const; /** * Fetch list of indexes of given table. @@ -1041,6 +1100,7 @@ public: * @return 0 if successful, otherwise -1 */ int listIndexes(List & list, const char * tableName); + int listIndexes(List & list, const char * tableName) const; /** @} *******************************************************************/ /** @@ -1173,10 +1233,10 @@ public: class NdbDictionaryImpl & m_impl; Dictionary(NdbDictionaryImpl&); const Table * getIndexTable(const char * indexName, - const char * tableName); + const char * tableName) const; public: #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL - const Table * getTable(const char * name, void **data); + const Table * getTable(const char * name, void **data) const; void set_local_table_data_size(unsigned sz); #endif }; diff --git a/ndb/include/ndbapi/NdbError.hpp b/ndb/include/ndbapi/NdbError.hpp index 8cde2a8cf38..45dbd5d3995 100644 --- a/ndb/include/ndbapi/NdbError.hpp +++ b/ndb/include/ndbapi/NdbError.hpp @@ -41,7 +41,7 @@ * The <em>error messages</em> and <em>error details</em> may * change without notice. * - * For example of use, see @ref ndbapi_example3.cpp. + * For example of use, see @ref ndbapi_retries.cpp. */ struct NdbError { /** diff --git a/ndb/include/ndbapi/NdbEventOperation.hpp b/ndb/include/ndbapi/NdbEventOperation.hpp index dc02df7fa4a..8c2de36fc51 100644 --- a/ndb/include/ndbapi/NdbEventOperation.hpp +++ b/ndb/include/ndbapi/NdbEventOperation.hpp @@ -46,7 +46,7 @@ class NdbEventOperationImpl; * The instance is removed by Ndb::dropEventOperation * * For more info see: - * @ref ndbapi_example5.cpp + * @ref ndbapi_event.cpp * * Known limitations: * diff --git a/ndb/include/ndbapi/NdbIndexScanOperation.hpp b/ndb/include/ndbapi/NdbIndexScanOperation.hpp index 6fe4dc3df84..e1a646fa413 100644 --- a/ndb/include/ndbapi/NdbIndexScanOperation.hpp +++ b/ndb/include/ndbapi/NdbIndexScanOperation.hpp @@ -73,7 +73,7 @@ public: * * For equality, it is better to use BoundEQ instead of the equivalent * pair of BoundLE and BoundGE. This is especially true when table - * distribution key is an initial part of the index key. + * partition key is an initial part of the index key. * * The sets of lower and upper bounds must be on initial sequences of * index keys. All but possibly the last bound must be non-strict. diff --git a/ndb/include/ndbapi/NdbOperation.hpp b/ndb/include/ndbapi/NdbOperation.hpp index 4d7db773505..06715233726 100644 --- a/ndb/include/ndbapi/NdbOperation.hpp +++ b/ndb/include/ndbapi/NdbOperation.hpp @@ -59,10 +59,17 @@ public: */ enum LockMode { - LM_Read = 0, - LM_Exclusive = 1, - LM_CommittedRead = 2, + LM_Read ///< Read with shared lock #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL + = 0 +#endif + ,LM_Exclusive ///< Read with exclusive lock +#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL + = 1 +#endif + ,LM_CommittedRead ///< Ignore locks, read last committed value +#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL + = 2, LM_Dirty = 2 #endif }; @@ -237,10 +244,13 @@ public: * use several equals (then all of them must be satisfied for the * tuple to be selected). * - * @note There are 10 versions of NdbOperation::equal with + * @note For insertTuple() it is also allowed to define the + * search key by using setValue(). + * + * @note There are 10 versions of equal() with * slightly different parameters. * - * @note When using NdbOperation::equal with a string (char *) as + * @note When using equal() with a string (char *) as * second argument, the string needs to be padded with * zeros in the following sense: * @code @@ -248,6 +258,8 @@ public: * strncpy(buf, str, sizeof(buf)); * NdbOperation->equal("Attr1", buf); * @endcode + * + * * * @param anAttrName Attribute name * @param aValue Attribute value. @@ -328,6 +340,12 @@ public: * then the API will assume that the pointer * is correct and not bother with checking it. * + * @note For insertTuple() the NDB API will automatically detect that + * it is supposed to use equal() instead. + * + * @note For insertTuple() it is not necessary to use + * setValue() on key attributes before other attributes. + * * @note There are 14 versions of NdbOperation::setValue with * slightly different parameters. * @@ -720,7 +738,7 @@ public: void setAbortOption(Int8 ao) { m_abortOption = ao; } /** - * Set/get distribution/partition key + * Set/get partition key */ void setPartitionId(Uint32 id); void setPartitionHash(Uint32 key); diff --git a/ndb/include/ndbapi/NdbRecAttr.hpp b/ndb/include/ndbapi/NdbRecAttr.hpp index 3b596c60d09..86f891dca95 100644 --- a/ndb/include/ndbapi/NdbRecAttr.hpp +++ b/ndb/include/ndbapi/NdbRecAttr.hpp @@ -39,7 +39,7 @@ class NdbOperation; * ndbout << MyRecAttr->u_32_value(); * @endcode * For more examples, see - * @ref ndbapi_example1.cpp. + * @ref ndbapi_simple.cpp. * * @note The NdbRecAttr object is instantiated with its value when * NdbTransaction::execute is called. Before this, the value is diff --git a/ndb/include/ndbapi/NdbTransaction.hpp b/ndb/include/ndbapi/NdbTransaction.hpp index 10d641c022e..78724206b4f 100644 --- a/ndb/include/ndbapi/NdbTransaction.hpp +++ b/ndb/include/ndbapi/NdbTransaction.hpp @@ -42,72 +42,62 @@ class NdbBlob; typedef void (* NdbAsynchCallback)(int, NdbTransaction*, void*); #endif -/** - * Commit type of transaction - */ -enum AbortOption { #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL - CommitIfFailFree = 0, - CommitAsMuchAsPossible = 2, ///< Commit transaction with as many - TryCommit = 0, ///< <i>Missing explanation</i> -#endif - AbortOnError = 0, ///< Abort transaction on failed operation - AO_IgnoreError = 2 ///< Transaction continues on failed operation +enum AbortOption { + CommitIfFailFree= 0, + TryCommit= 0, + AbortOnError= 0, + CommitAsMuchAsPossible= 2, + AO_IgnoreError= 2 }; - -typedef AbortOption CommitType; - - -/** - * Execution type of transaction - */ enum ExecType { - NoExecTypeDef = -1, ///< Erroneous type (Used for debugging only) - Prepare, ///< <i>Missing explanation</i> - NoCommit, ///< Execute the transaction as far as it has - ///< been defined, but do not yet commit it - Commit, ///< Execute and try to commit the transaction - Rollback ///< Rollback transaction + NoExecTypeDef = -1, + Prepare, + NoCommit, + Commit, + Rollback }; - +#endif /** * @class NdbTransaction * @brief Represents a transaction. * * A transaction (represented by an NdbTransaction object) - * belongs to an Ndb object and is typically created using - * Ndb::startTransaction. + * belongs to an Ndb object and is created using + * Ndb::startTransaction(). * A transaction consists of a list of operations - * (represented by NdbOperation objects). + * (represented by NdbOperation, NdbScanOperation, NdbIndexOperation, + * and NdbIndexScanOperation objects). * Each operation access exactly one table. * * After getting the NdbTransaction object, - * the first step is to get (allocate) an operation given the table name. + * the first step is to get (allocate) an operation given the table name using + * one of the methods getNdbOperation(), getNdbScanOperation(), + * getNdbIndexOperation(), or getNdbIndexScanOperation(). * Then the operation is defined. - * Several operations can be defined in parallel on the same - * NdbTransaction object. - * When all operations are defined, the NdbTransaction::execute - * method sends them to the NDB kernel for execution. + * Several operations can be defined on the same + * NdbTransaction object, they will in that case be executed in parallell. + * When all operations are defined, the execute() + * method sends them to the NDB kernel for execution. * - * The NdbTransaction::execute method returns when the NDB kernel has + * The execute() method returns when the NDB kernel has * completed execution of all operations defined before the call to - * NdbTransaction::execute. - * All allocated operations should be properly defined - * before calling NdbTransaction::execute. + * execute(). All allocated operations should be properly defined + * before calling execute(). * - * A call to NdbTransaction::execute uses one out of three types of execution: - * -# ExecType::NoCommit Executes operations without committing them. - * -# ExecType::Commit Executes remaining operation and commits the + * A call to execute() uses one out of three types of execution: + * -# NdbTransaction::NoCommit Executes operations without committing them. + * -# NdbTransaction::Commit Executes remaining operation and commits the * complete transaction - * -# ExecType::Rollback Rollbacks the entire transaction. + * -# NdbTransaction::Rollback Rollbacks the entire transaction. * - * NdbTransaction::execute is equipped with an extra error handling parameter + * execute() is equipped with an extra error handling parameter. * There are two alternatives: - * -# AbortOption::AbortOnError (default). + * -# NdbTransaction::AbortOnError (default). * The transaction is aborted if there are any error during the * execution - * -# AbortOption::IgnoreError + * -# NdbTransaction::AO_IgnoreError * Continue execution of transaction even if operation fails * */ @@ -139,6 +129,7 @@ enum ExecType { * primary key since it came along from the scanned tuple. * */ + class NdbTransaction { #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL @@ -153,6 +144,44 @@ class NdbTransaction public: /** + * Commit type of transaction + */ + enum AbortOption { + AbortOnError= ///< Abort transaction on failed operation +#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL + ::AbortOnError +#endif + ,AO_IgnoreError= ///< Transaction continues on failed operation +#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL + ::AO_IgnoreError +#endif + }; + + /** + * Execution type of transaction + */ + enum ExecType { +#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL + NoExecTypeDef= + ::NoExecTypeDef, ///< Erroneous type (Used for debugging only) + Prepare= ::Prepare, ///< <i>Missing explanation</i> +#endif + NoCommit= ///< Execute the transaction as far as it has + ///< been defined, but do not yet commit it +#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL + ::NoCommit +#endif + ,Commit= ///< Execute and try to commit the transaction +#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL + ::Commit +#endif + ,Rollback ///< Rollback transaction +#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL + = ::Rollback +#endif + }; + + /** * Get an NdbOperation for a table. * Note that the operation has to be defined before it is executed. * @@ -279,9 +308,15 @@ public: * the send. * @return 0 if successful otherwise -1. */ - int execute(ExecType execType, + int execute(ExecType execType, AbortOption abortOption = AbortOnError, int force = 0 ); +#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED + int execute(::ExecType execType, + ::AbortOption abortOption = ::AbortOnError, + int force = 0 ) + { return execute ((ExecType)execType,(AbortOption)abortOption,force); } +#endif #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL // to be documented later @@ -298,7 +333,7 @@ public: * ExecType::Rollback rollbacks the entire transaction. * @param callback A callback method. This method gets * called when the transaction has been - * executed. See @ref ndbapi_example2.cpp + * executed. See @ref ndbapi_async1.cpp * for an example on how to specify and use * a callback method. * @param anyObject A void pointer. This pointer is forwarded to the @@ -312,6 +347,14 @@ public: NdbAsynchCallback callback, void* anyObject, AbortOption abortOption = AbortOnError); +#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED + void executeAsynchPrepare(::ExecType execType, + NdbAsynchCallback callback, + void* anyObject, + ::AbortOption abortOption = ::AbortOnError) + { executeAsynchPrepare((ExecType)execType, callback, anyObject, + (AbortOption)abortOption); } +#endif /** * Prepare and send an asynchronous transaction. @@ -330,6 +373,14 @@ public: NdbAsynchCallback aCallback, void* anyObject, AbortOption abortOption = AbortOnError); +#ifndef DOXYGEN_SHOULD_SKIP_DEPRECATED + void executeAsynch(::ExecType aTypeOfExec, + NdbAsynchCallback aCallback, + void* anyObject, + ::AbortOption abortOption= ::AbortOnError) + { executeAsynch((ExecType)aTypeOfExec, aCallback, anyObject, + (AbortOption)abortOption); } +#endif #endif /** * Refresh @@ -345,6 +396,8 @@ public: /** * Close transaction + * + * @note Equivalent to to calling Ndb::closeTransaction() */ #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL /** @@ -366,7 +419,13 @@ public: * Once a transaction has been completed successfully * it can be started again wo/ calling closeTransaction/startTransaction * - * Note this method also releases completed operations + * @note This method also releases completed operations + * + * @note This method does not close open scans, + * c.f. NdbScanOperation::close() + * + * @note This method can only be called _directly_ after commit + * and only if commit is successful */ int restart(); #endif @@ -409,10 +468,7 @@ public: Uint64 getTransactionId(); /** - * Returns the commit status of the transaction. - * - * @return The commit status of the transaction, i.e. one of - * { NotStarted, Started, TimeOut, Committed, Aborted, NeedAbort } + * The commit status of the transaction. */ enum CommitStatusType { NotStarted, ///< Transaction not yet started @@ -422,6 +478,11 @@ public: NeedAbort ///< <i>Missing explanation</i> }; + /** + * Get the commit status of the transaction. + * + * @return The commit status of the transaction + */ CommitStatusType commitStatus(); /** @} *********************************************************************/ @@ -443,7 +504,7 @@ public: * This method is used on the NdbTransaction object to find the * NdbOperation causing an error. * To find more information about the - * actual error, use method NdbOperation::getNdbError + * actual error, use method NdbOperation::getNdbError() * on the returned NdbOperation object. * * @return The NdbOperation causing the latest error. diff --git a/ndb/src/ndbapi/NdbBlob.cpp b/ndb/src/ndbapi/NdbBlob.cpp index 86b161e3b9b..0638f6e4c51 100644 --- a/ndb/src/ndbapi/NdbBlob.cpp +++ b/ndb/src/ndbapi/NdbBlob.cpp @@ -875,7 +875,7 @@ NdbBlob::readParts(char* buf, Uint32 part, Uint32 count) setErrorCode(tOp); return -1; } - tOp->m_abortOption = AbortOnError; + tOp->m_abortOption = NdbTransaction::AbortOnError; buf += thePartSize; n++; thePendingBlobOps |= (1 << NdbOperation::ReadRequest); @@ -898,7 +898,7 @@ NdbBlob::insertParts(const char* buf, Uint32 part, Uint32 count) setErrorCode(tOp); return -1; } - tOp->m_abortOption = AbortOnError; + tOp->m_abortOption = NdbTransaction::AbortOnError; buf += thePartSize; n++; thePendingBlobOps |= (1 << NdbOperation::InsertRequest); @@ -921,7 +921,7 @@ NdbBlob::updateParts(const char* buf, Uint32 part, Uint32 count) setErrorCode(tOp); return -1; } - tOp->m_abortOption = AbortOnError; + tOp->m_abortOption = NdbTransaction::AbortOnError; buf += thePartSize; n++; thePendingBlobOps |= (1 << NdbOperation::UpdateRequest); @@ -943,7 +943,7 @@ NdbBlob::deleteParts(Uint32 part, Uint32 count) setErrorCode(tOp); return -1; } - tOp->m_abortOption = AbortOnError; + tOp->m_abortOption = NdbTransaction::AbortOnError; n++; thePendingBlobOps |= (1 << NdbOperation::DeleteRequest); theNdbCon->thePendingBlobOps |= (1 << NdbOperation::DeleteRequest); @@ -976,11 +976,11 @@ NdbBlob::deletePartsUnknown(Uint32 part) setErrorCode(tOp); return -1; } - tOp->m_abortOption = AO_IgnoreError; + tOp->m_abortOption= NdbTransaction::AO_IgnoreError; n++; } DBG("deletePartsUnknown: executeNoBlobs [in] bat=" << bat); - if (theNdbCon->executeNoBlobs(NoCommit) == -1) + if (theNdbCon->executeNoBlobs(NdbTransaction::NoCommit) == -1) return -1; DBG("deletePartsUnknown: executeNoBlobs [out]"); n = 0; @@ -1012,7 +1012,7 @@ NdbBlob::executePendingBlobReads() Uint8 flags = (1 << NdbOperation::ReadRequest); if (thePendingBlobOps & flags) { DBG("executePendingBlobReads: executeNoBlobs [in]"); - if (theNdbCon->executeNoBlobs(NoCommit) == -1) + if (theNdbCon->executeNoBlobs(NdbTransaction::NoCommit) == -1) return -1; DBG("executePendingBlobReads: executeNoBlobs [out]"); thePendingBlobOps = 0; @@ -1027,7 +1027,7 @@ NdbBlob::executePendingBlobWrites() Uint8 flags = 0xFF & ~(1 << NdbOperation::ReadRequest); if (thePendingBlobOps & flags) { DBG("executePendingBlobWrites: executeNoBlobs [in]"); - if (theNdbCon->executeNoBlobs(NoCommit) == -1) + if (theNdbCon->executeNoBlobs(NdbTransaction::NoCommit) == -1) return -1; DBG("executePendingBlobWrites: executeNoBlobs [out]"); thePendingBlobOps = 0; @@ -1175,7 +1175,7 @@ NdbBlob::atPrepare(NdbTransaction* aCon, NdbOperation* anOp, const NdbColumnImpl * back after postExecute. */ int -NdbBlob::preExecute(ExecType anExecType, bool& batch) +NdbBlob::preExecute(NdbTransaction::ExecType anExecType, bool& batch) { DBG("preExecute [in]"); if (theState == Invalid) @@ -1224,7 +1224,7 @@ NdbBlob::preExecute(ExecType anExecType, bool& batch) return -1; } if (isWriteOp()) { - tOp->m_abortOption = AO_IgnoreError; + tOp->m_abortOption = NdbTransaction::AO_IgnoreError; } theHeadInlineReadOp = tOp; // execute immediately @@ -1270,7 +1270,7 @@ NdbBlob::preExecute(ExecType anExecType, bool& batch) return -1; } if (isWriteOp()) { - tOp->m_abortOption = AO_IgnoreError; + tOp->m_abortOption = NdbTransaction::AO_IgnoreError; } theHeadInlineReadOp = tOp; // execute immediately @@ -1316,18 +1316,18 @@ NdbBlob::preExecute(ExecType anExecType, bool& batch) * any remaining prepared operations. */ int -NdbBlob::postExecute(ExecType anExecType) +NdbBlob::postExecute(NdbTransaction::ExecType anExecType) { DBG("postExecute [in] type=" << anExecType); if (theState == Invalid) return -1; if (theState == Active) { - setState(anExecType == NoCommit ? Active : Closed); + setState(anExecType == NdbTransaction::NoCommit ? Active : Closed); DBG("postExecute [skip]"); return 0; } assert(theState == Prepared); - setState(anExecType == NoCommit ? Active : Closed); + setState(anExecType == NdbTransaction::NoCommit ? Active : Closed); assert(isKeyOp()); if (isIndexOp()) { NdbBlob* tFirstBlob = theNdbOp->theBlobList; @@ -1343,14 +1343,15 @@ NdbBlob::postExecute(ExecType anExecType) return -1; if (theGetFlag) { assert(theGetSetBytes == 0 || theGetBuf != 0); - assert(theGetSetBytes <= theInlineSize || anExecType == NoCommit); + assert(theGetSetBytes <= theInlineSize || + anExecType == NdbTransaction::NoCommit); Uint32 bytes = theGetSetBytes; if (readDataPrivate(theGetBuf, bytes) == -1) return -1; } } if (isUpdateOp()) { - assert(anExecType == NoCommit); + assert(anExecType == NdbTransaction::NoCommit); getHeadFromRecAttr(); if (theSetFlag) { // setValue overwrites everything @@ -1367,7 +1368,7 @@ NdbBlob::postExecute(ExecType anExecType) } } if (isWriteOp() && isTableOp()) { - assert(anExecType == NoCommit); + assert(anExecType == NdbTransaction::NoCommit); if (theHeadInlineReadOp->theError.code == 0) { int tNullFlag = theNullFlag; Uint64 tLength = theLength; @@ -1418,18 +1419,18 @@ NdbBlob::postExecute(ExecType anExecType) } } if (isDeleteOp()) { - assert(anExecType == NoCommit); + assert(anExecType == NdbTransaction::NoCommit); getHeadFromRecAttr(); if (deleteParts(0, getPartCount()) == -1) return -1; } - setState(anExecType == NoCommit ? Active : Closed); + setState(anExecType == NdbTransaction::NoCommit ? Active : Closed); // activation callback if (theActiveHook != NULL) { if (invokeActiveHook() == -1) return -1; } - if (anExecType == NoCommit && theHeadInlineUpdateFlag) { + if (anExecType == NdbTransaction::NoCommit && theHeadInlineUpdateFlag) { NdbOperation* tOp = theNdbCon->getNdbOperation(theTable); if (tOp == NULL || tOp->updateTuple() == -1 || @@ -1438,7 +1439,7 @@ NdbBlob::postExecute(ExecType anExecType) setErrorCode(NdbBlobImpl::ErrAbort); return -1; } - tOp->m_abortOption = AbortOnError; + tOp->m_abortOption = NdbTransaction::AbortOnError; DBG("added op to update head+inline"); } DBG("postExecute [out]"); @@ -1468,7 +1469,7 @@ NdbBlob::preCommit() setErrorCode(NdbBlobImpl::ErrAbort); return -1; } - tOp->m_abortOption = AbortOnError; + tOp->m_abortOption = NdbTransaction::AbortOnError; DBG("added op to update head+inline"); } } diff --git a/ndb/src/ndbapi/NdbDictionary.cpp b/ndb/src/ndbapi/NdbDictionary.cpp index 745a0635a81..f641b8cd5a0 100644 --- a/ndb/src/ndbapi/NdbDictionary.cpp +++ b/ndb/src/ndbapi/NdbDictionary.cpp @@ -177,12 +177,12 @@ NdbDictionary::Column::getPrimaryKey() const { } void -NdbDictionary::Column::setDistributionKey(bool val){ +NdbDictionary::Column::setPartitionKey(bool val){ m_impl.m_distributionKey = val; } bool -NdbDictionary::Column::getDistributionKey() const{ +NdbDictionary::Column::getPartitionKey() const{ return m_impl.m_distributionKey; } @@ -706,7 +706,8 @@ NdbDictionary::Dictionary::alterTable(const Table & t){ } const NdbDictionary::Table * -NdbDictionary::Dictionary::getTable(const char * name, void **data){ +NdbDictionary::Dictionary::getTable(const char * name, void **data) const +{ NdbTableImpl * t = m_impl.getTable(name, data); if(t) return t->m_facade; @@ -719,7 +720,8 @@ void NdbDictionary::Dictionary::set_local_table_data_size(unsigned sz) } const NdbDictionary::Table * -NdbDictionary::Dictionary::getTable(const char * name){ +NdbDictionary::Dictionary::getTable(const char * name) const +{ return getTable(name, 0); } @@ -752,7 +754,7 @@ NdbDictionary::Dictionary::dropIndex(const char * indexName, const NdbDictionary::Index * NdbDictionary::Dictionary::getIndex(const char * indexName, - const char * tableName) + const char * tableName) const { NdbIndexImpl * i = m_impl.getIndex(indexName, tableName); if(i) @@ -782,7 +784,7 @@ NdbDictionary::Dictionary::removeCachedIndex(const char * indexName, const NdbDictionary::Table * NdbDictionary::Dictionary::getIndexTable(const char * indexName, - const char * tableName) + const char * tableName) const { NdbIndexImpl * i = m_impl.getIndex(indexName, tableName); NdbTableImpl * t = m_impl.getTable(tableName); @@ -822,6 +824,12 @@ NdbDictionary::Dictionary::listObjects(List& list, Object::Type type) } int +NdbDictionary::Dictionary::listObjects(List& list, Object::Type type) const +{ + return m_impl.listObjects(list, type); +} + +int NdbDictionary::Dictionary::listIndexes(List& list, const char * tableName) { const NdbDictionary::Table* tab= getTable(tableName); @@ -832,6 +840,18 @@ NdbDictionary::Dictionary::listIndexes(List& list, const char * tableName) return m_impl.listIndexes(list, tab->getTableId()); } +int +NdbDictionary::Dictionary::listIndexes(List& list, + const char * tableName) const +{ + const NdbDictionary::Table* tab= getTable(tableName); + if(tab == 0) + { + return -1; + } + return m_impl.listIndexes(list, tab->getTableId()); +} + const struct NdbError & NdbDictionary::Dictionary::getNdbError() const { return m_impl.getNdbError(); diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp index 2d37c7883ec..9be4e8ef8cf 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp @@ -941,7 +941,7 @@ NdbDictInterface::dictSignal(NdbApiSignal* signal, for (int j=0; j < noerrcodes; j++) if(m_error.code == errcodes[j]) { doContinue = 1; - continue; + break; } if (doContinue) continue; @@ -1007,12 +1007,14 @@ NdbDictInterface::getTable(class NdbApiSignal * signal, Uint32 noOfSections, bool fullyQualifiedNames) { //GetTabInfoReq * const req = CAST_PTR(GetTabInfoReq, signal->getDataPtrSend()); + int errCodes[] = {GetTabInfoRef::Busy }; + int r = dictSignal(signal,ptr,noOfSections, 0/*do not use masternode id*/, 100, WAIT_GET_TAB_INFO_REQ, WAITFOR_RESPONSE_TIMEOUT, - NULL,0); + errCodes, 1); if (r) return 0; NdbTableImpl * rt = 0; @@ -2234,10 +2236,9 @@ NdbDictionaryImpl::createEvent(NdbEventImpl & evnt) NdbTableImpl* tab = getTable(evnt.getTable()); if(tab == 0){ - // m_error.code = 3249; - ndbout_c(":createEvent: table %s not found", evnt.getTable()); #ifdef EVENT_DEBUG - ndbout_c("NdbDictionaryImpl::createEvent: table not found: %s", evnt.getTable()); + ndbout_c("NdbDictionaryImpl::createEvent: table not found: %s", + evnt.getTable()); #endif return -1; } diff --git a/ndb/src/ndbapi/NdbRecAttr.cpp b/ndb/src/ndbapi/NdbRecAttr.cpp index e6e97ab60b1..37142c94f8f 100644 --- a/ndb/src/ndbapi/NdbRecAttr.cpp +++ b/ndb/src/ndbapi/NdbRecAttr.cpp @@ -15,17 +15,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/************************************************************************************************ -Name: NdbRecAttr.C -Include: -Link: -Author: UABRONM Mikael Ronström UAB/B/SD -Date: 971206 -Version: 0.1 -Description: Interface between TIS and NDB -Documentation: -Adjust: 971206 UABRONM First version -************************************************************************************************/ #include <ndb_global.h> #include <NdbOut.hpp> #include <NdbRecAttr.hpp> @@ -148,6 +137,39 @@ NdbRecAttr::receive_data(const Uint32 * data, Uint32 sz){ return false; } +static void +ndbrecattr_print_string(NdbOut& out, const char *type, + const char *ref, unsigned sz) +{ + int i, len, printable= 1; + // trailing zeroes are not printed + for (i=sz-1; i >= 0; i--) + if (ref[i] == 0) sz--; + else break; + if (sz == 0) return; // empty + + for (len=0; len < (int)sz && ref[i] != 0; len++) + if (printable && !isprint((int)ref[i])) + printable= 0; + + if (printable) + out.print("%.*s", len, ref); + else + { + out.print("0x"); + for (i=0; i < len; i++) + out.print("%02X", (int)ref[i]); + } + if (len != (int)sz) + { + out.print("["); + for (i= len+1; ref[i] != 0; i++) + out.print("%u]",len-i); + assert((int)sz > i); + ndbrecattr_print_string(out,type,ref+i,sz-i); + } +} + NdbOut& operator<<(NdbOut& out, const NdbRecAttr &r) { if (r.isNULL()) @@ -193,17 +215,19 @@ NdbOut& operator<<(NdbOut& out, const NdbRecAttr &r) case NdbDictionary::Column::Tinyint: out << (int) r.char_value(); break; + case NdbDictionary::Column::Binary: + ndbrecattr_print_string(out,"Binary",r.aRef(),r.arraySize()); + j = r.arraySize(); + break; case NdbDictionary::Column::Char: - out.print("%.*s", r.arraySize(), r.aRef()); + ndbrecattr_print_string(out,"Char",r.aRef(),r.arraySize()); j = r.arraySize(); break; case NdbDictionary::Column::Varchar: - { - short len = ntohs(r.u_short_value()); - out.print("%.*s", len, r.aRef()+2); - } + ndbrecattr_print_string(out,"Varchar", r.aRef()+ 2, + ntohs(r.u_short_value())); j = r.arraySize(); - break; + break; case NdbDictionary::Column::Float: out << r.float_value(); break; diff --git a/ndb/src/ndbapi/NdbTransaction.cpp b/ndb/src/ndbapi/NdbTransaction.cpp index 40a79421fdd..d010c0ae0d8 100644 --- a/ndb/src/ndbapi/NdbTransaction.cpp +++ b/ndb/src/ndbapi/NdbTransaction.cpp @@ -1076,15 +1076,15 @@ NdbTransaction::getNdbScanOperation(const char* aTableName) }//NdbTransaction::getNdbScanOperation() /***************************************************************************** -NdbScanOperation* getNdbScanOperation(const char* anIndexName, const char* aTableName); +NdbScanOperation* getNdbIndexScanOperation(const char* anIndexName, const char* aTableName); -Return Value Return a pointer to a NdbScanOperation object if getNdbScanOperation was succesful. +Return Value Return a pointer to a NdbIndexScanOperation object if getNdbIndexScanOperation was succesful. Return NULL : In all other case. Parameters: anIndexName : Name of the index to use. aTableName : Name of the database table. -Remark: Get an operation from NdbScanOperation idlelist and get the NdbTransaction object +Remark: Get an operation from NdbIndexScanOperation idlelist and get the NdbTransaction object who was fetch by startTransaction pointing to this operation - getOperation will set the theTableId in the NdbOperation object.synchronous + getOperation will set the theTableId in the NdbIndexScanOperation object.synchronous ******************************************************************************/ NdbIndexScanOperation* NdbTransaction::getNdbIndexScanOperation(const char* anIndexName, @@ -1134,12 +1134,12 @@ NdbTransaction::getNdbIndexScanOperation(const NdbDictionary::Index * index, /***************************************************************************** NdbScanOperation* getNdbScanOperation(int aTableId); -Return Value Return a pointer to a NdbOperation object if getNdbOperation was succesful. +Return Value Return a pointer to a NdbScanOperation object if getNdbScanOperation was succesful. Return NULL: In all other case. Parameters: tableId : Id of the database table beeing deleted. Remark: Get an operation from NdbScanOperation object idlelist and get the NdbTransaction object who was fetch by startTransaction pointing to this operation - getOperation will set the theTableId in the NdbOperation object, synchronous. + getOperation will set the theTableId in the NdbScanOperation object, synchronous. *****************************************************************************/ NdbIndexScanOperation* NdbTransaction::getNdbScanOperation(const NdbTableImpl * tab) @@ -1203,12 +1203,12 @@ NdbTransaction::getNdbScanOperation(const NdbDictionary::Table * table) NdbIndexOperation* getNdbIndexOperation(const char* anIndexName, const char* aTableName); -Return Value Return a pointer to a NdbOperation object if getNdbScanOperation was succesful. +Return Value Return a pointer to a NdbOperation object if getNdbIndexOperation was succesful. Return NULL : In all other case. Parameters: aTableName : Name of the database table. -Remark: Get an operation from NdbScanOperation idlelist and get the NdbTransaction object - who was fetch by startTransaction pointing to this operation - getOperation will set the theTableId in the NdbScanOperation object.synchronous +Remark: Get an operation from NdbIndexOperation idlelist and get the NdbTransaction object + who was fetch by startTransaction pointing to this operation + getOperation will set the theTableId in the NdbIndexOperation object.synchronous ******************************************************************************/ NdbIndexOperation* NdbTransaction::getNdbIndexOperation(const char* anIndexName, @@ -1216,8 +1216,21 @@ NdbTransaction::getNdbIndexOperation(const char* anIndexName, { if (theCommitStatus == Started) { NdbTableImpl * table = theNdb->theDictionary->getTable(aTableName); - NdbIndexImpl * index = theNdb->theDictionary->getIndex(anIndexName, - aTableName); + NdbIndexImpl * index; + + if (table->m_frm.get_data()) + { + // This unique index is defined from SQL level + static const char* uniqueSuffix= "$unique"; + char uniqueIndexName[MAX_TAB_NAME_SIZE]; + + strxnmov(uniqueIndexName, MAX_TAB_NAME_SIZE, anIndexName, uniqueSuffix, NullS); + index = theNdb->theDictionary->getIndex(uniqueIndexName, + aTableName); + } + else + index = theNdb->theDictionary->getIndex(anIndexName, + aTableName); if(table != 0 && index != 0){ return getNdbIndexOperation(index, table); } diff --git a/ndb/src/ndbapi/ndberror.c b/ndb/src/ndbapi/ndberror.c index dd4a1cf0b9e..d1e3b5efa2e 100644 --- a/ndb/src/ndbapi/ndberror.c +++ b/ndb/src/ndbapi/ndberror.c @@ -79,6 +79,7 @@ static const char* empty_string = ""; * 4400 - "" * 4500 - "" * 4600 - "" + * 4700 - "" Event * 5000 - Management server */ @@ -296,6 +297,22 @@ ErrorBundle ErrorCodes[] = { { 4232, AE, "Parallelism can only be between 1 and 240" }, { 290, AE, "Scan not started or has been closed by kernel due to timeout" }, + /** + * Event application errors + */ + + { 4707, AE, "Too many event have been defined"}, + { 4708, AE, "Event name is too long"}, + { 4709, AE, "Event already exists"}, + { 4710, AE, "Event not found"}, + { 4711, AE, "Creation of event failed"}, + + /** + * Event internal errors + */ + + { 4731, IE, "Event not found"}, + /** * SchemaError */ diff --git a/ndb/tools/delete_all.cpp b/ndb/tools/delete_all.cpp index 664fa616412..38a9cdd9354 100644 --- a/ndb/tools/delete_all.cpp +++ b/ndb/tools/delete_all.cpp @@ -80,19 +80,21 @@ int main(int argc, char** argv){ 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,0) < 0) + { + ndbout << "Cluster nodes not ready in 30 seconds." << endl; return NDBT_ProgramExit(NDBT_FAILED); } - Ndb MyNdb(&con, _dbname ); + Ndb MyNdb(&con, _dbname ); 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; - // Check if table exists in db int res = NDBT_OK; for(int i = 0; i<argc; i++){ @@ -119,7 +121,7 @@ int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab, int parallelism) const int retryMax = 10; int deletedRows = 0; int check; - NdbConnection *pTrans; + NdbTransaction *pTrans; NdbScanOperation *pOp; NdbError err; @@ -148,11 +150,11 @@ int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab, int parallelism) goto failed; } - if( pOp->readTuplesExclusive(par) ) { + if( pOp->readTuples(NdbOperation::LM_Exclusive,par) ) { goto failed; } - if(pTrans->execute(NoCommit) != 0){ + if(pTrans->execute(NdbTransaction::NoCommit) != 0){ err = pTrans->getNdbError(); if(err.status == NdbError::TemporaryError){ ERR(err); @@ -172,7 +174,7 @@ int clear_table(Ndb* pNdb, const NdbDictionary::Table* pTab, int parallelism) } while((check = pOp->nextResult(false)) == 0); if(check != -1){ - check = pTrans->execute(Commit); + check = pTrans->execute(NdbTransaction::Commit); pTrans->restart(); } diff --git a/ndb/tools/desc.cpp b/ndb/tools/desc.cpp index 8c84802ef51..b18f97a05b1 100644 --- a/ndb/tools/desc.cpp +++ b/ndb/tools/desc.cpp @@ -80,19 +80,22 @@ int main(int argc, char** argv){ 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); } - - Ndb* pMyNdb = new Ndb(&con, _dbname); - pMyNdb->init(); - - ndbout << "Waiting..."; - while (pMyNdb->waitUntilReady() != 0) { - ndbout << "..."; + if (con.wait_until_ready(30,0) < 0) + { + ndbout << "Cluster nodes not ready in 30 seconds." << endl; + return NDBT_ProgramExit(NDBT_FAILED); } - ndbout << endl; - NdbDictionary::Dictionary * dict = pMyNdb->getDictionary(); + Ndb MyNdb(&con, _dbname); + if(MyNdb.init() != 0){ + ERR(MyNdb.getNdbError()); + return NDBT_ProgramExit(NDBT_FAILED); + } + + const NdbDictionary::Dictionary * dict= MyNdb.getDictionary(); for (int i = 0; i < argc; i++) { NDBT_Table* pTab = (NDBT_Table*)dict->getTable(argv[i]); if (pTab != 0){ @@ -132,6 +135,5 @@ int main(int argc, char** argv){ ndbout << argv[i] << ": " << dict->getNdbError() << endl; } - delete pMyNdb; return NDBT_ProgramExit(NDBT_OK); } diff --git a/ndb/tools/drop_index.cpp b/ndb/tools/drop_index.cpp index cc0dd9a8be6..47baee0b66f 100644 --- a/ndb/tools/drop_index.cpp +++ b/ndb/tools/drop_index.cpp @@ -83,16 +83,18 @@ int main(int argc, char** argv){ { return NDBT_ProgramExit(NDBT_FAILED); } - Ndb MyNdb(&con, _dbname ); + if (con.wait_until_ready(30,0) < 0) + { + ndbout << "Cluster nodes not ready in 30 seconds." << endl; + return NDBT_ProgramExit(NDBT_FAILED); + } + Ndb MyNdb(&con, _dbname ); if(MyNdb.init() != 0){ ERR(MyNdb.getNdbError()); return NDBT_ProgramExit(NDBT_FAILED); } - while(MyNdb.waitUntilReady() != 0) - ndbout << "Waiting for ndb to become ready..." << endl; - int res = 0; for(int i = 0; i<argc; i++){ ndbout << "Dropping index " << argv[i] << "..."; diff --git a/ndb/tools/drop_tab.cpp b/ndb/tools/drop_tab.cpp index 81131c9060a..6d128321994 100644 --- a/ndb/tools/drop_tab.cpp +++ b/ndb/tools/drop_tab.cpp @@ -81,18 +81,21 @@ int main(int argc, char** argv){ 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,0) < 0) + { + ndbout << "Cluster nodes not ready in 30 seconds." << endl; return NDBT_ProgramExit(NDBT_FAILED); } - Ndb MyNdb(&con, _dbname ); + Ndb MyNdb(&con, _dbname ); if(MyNdb.init() != 0){ ERR(MyNdb.getNdbError()); return NDBT_ProgramExit(NDBT_FAILED); } - while(MyNdb.waitUntilReady() != 0) - ndbout << "Waiting for ndb to become ready..." << endl; - int res = 0; for(int i = 0; i<argc; i++){ ndbout << "Dropping table " << argv[i] << "..."; diff --git a/ndb/tools/listTables.cpp b/ndb/tools/listTables.cpp index 710af66f4de..e018bd6d9a5 100644 --- a/ndb/tools/listTables.cpp +++ b/ndb/tools/listTables.cpp @@ -29,7 +29,7 @@ static Ndb_cluster_connection *ndb_cluster_connection= 0; static Ndb* ndb = 0; -static NdbDictionary::Dictionary* dic = 0; +static const NdbDictionary::Dictionary * dic = 0; static int _unqualified = 0; static void @@ -233,16 +233,19 @@ int main(int argc, char** argv){ ndb_cluster_connection = new Ndb_cluster_connection(opt_connect_str); if (ndb_cluster_connection->connect(12,5,1)) - fatal("unable to connect"); + fatal("Unable to connect to management server."); + if (ndb_cluster_connection->wait_until_ready(30,0) < 0) + fatal("Cluster nodes not ready in 30 seconds."); + ndb = new Ndb(ndb_cluster_connection, _dbname); if (ndb->init() != 0) fatal("init"); - if (ndb->waitUntilReady(30) < 0) - fatal("waitUntilReady"); dic = ndb->getDictionary(); for (int i = 0; _loops == 0 || i < _loops; i++) { list(_tabname, (NdbDictionary::Object::Type)_type); } + delete ndb; + delete ndb_cluster_connection; return NDBT_ProgramExit(NDBT_OK); } diff --git a/ndb/tools/restore/consumer_restore.cpp b/ndb/tools/restore/consumer_restore.cpp index dce03ad38bf..d72b82569e2 100644 --- a/ndb/tools/restore/consumer_restore.cpp +++ b/ndb/tools/restore/consumer_restore.cpp @@ -21,7 +21,7 @@ extern FilteredNdbOut err; extern FilteredNdbOut info; extern FilteredNdbOut debug; -static void callback(int, NdbConnection*, void*); +static void callback(int, NdbTransaction*, void*); extern const char * g_connect_string; bool @@ -375,7 +375,8 @@ void BackupRestore::tuple_a(restore_callback_t *cb) } // Prepare transaction (the transaction is NOT yet sent to NDB) - cb->connection->executeAsynchPrepare(Commit, &callback, cb); + cb->connection->executeAsynchPrepare(NdbTransaction::Commit, + &callback, cb); m_transactions++; return; } @@ -492,7 +493,7 @@ BackupRestore::logEntry(const LogEntry & tup) if (!m_restore) return; - NdbConnection * trans = m_ndb->startTransaction(); + NdbTransaction * trans = m_ndb->startTransaction(); if (trans == NULL) { // Deep shit, TODO: handle the error @@ -543,7 +544,7 @@ BackupRestore::logEntry(const LogEntry & tup) op->setValue(attr->Desc->attrId, dataPtr, length); } - const int ret = trans->execute(Commit); + const int ret = trans->execute(NdbTransaction::Commit); if (ret != 0) { // Both insert update and delete can fail during log running @@ -584,12 +585,12 @@ BackupRestore::endOfLogEntrys() * * (This function must have three arguments: * - The result of the transaction, - * - The NdbConnection object, and + * - The NdbTransaction object, and * - A pointer to an arbitrary object.) */ static void -callback(int result, NdbConnection* trans, void* aObject) +callback(int result, NdbTransaction* trans, void* aObject) { restore_callback_t *cb = (restore_callback_t *)aObject; (cb->restore)->cback(result, cb); @@ -603,7 +604,7 @@ BackupRestore::tuple(const TupleS & tup) return; while (1) { - NdbConnection * trans = m_ndb->startTransaction(); + NdbTransaction * trans = m_ndb->startTransaction(); if (trans == NULL) { // Deep shit, TODO: handle the error @@ -654,7 +655,7 @@ BackupRestore::tuple(const TupleS & tup) else op->setValue(i, dataPtr, length); } - int ret = trans->execute(Commit); + int ret = trans->execute(NdbTransaction::Commit); if (ret != 0) { ndbout << "execute failed: "; diff --git a/ndb/tools/restore/consumer_restorem.cpp b/ndb/tools/restore/consumer_restorem.cpp index ce1738ea686..56179a60ab0 100644 --- a/ndb/tools/restore/consumer_restorem.cpp +++ b/ndb/tools/restore/consumer_restorem.cpp @@ -21,8 +21,8 @@ extern FilteredNdbOut err; extern FilteredNdbOut info; extern FilteredNdbOut debug; -static bool asynchErrorHandler(NdbConnection * trans, Ndb * ndb); -static void callback(int result, NdbConnection* trans, void* aObject); +static bool asynchErrorHandler(NdbTransaction * trans, Ndb * ndb); +static void callback(int result, NdbTransaction* trans, void* aObject); bool BackupRestore::init() @@ -371,7 +371,7 @@ BackupRestore::tuple(const TupleS & tup) return; while (1) { - NdbConnection * trans = m_ndb->startTransaction(); + NdbTransaction * trans = m_ndb->startTransaction(); if (trans == NULL) { // Deep shit, TODO: handle the error @@ -460,7 +460,7 @@ BackupRestore::logEntry(const LogEntry & tup) if (!m_restore) return; - NdbConnection * trans = m_ndb->startTransaction(); + NdbTransaction * trans = m_ndb->startTransaction(); if (trans == NULL) { // Deep shit, TODO: handle the error @@ -551,7 +551,7 @@ BackupRestore::endOfLogEntrys() * ******************************************/ static void restoreCallback(int result, // Result for transaction - NdbConnection *object, // Transaction object + NdbTransaction *object, // Transaction object void *anything) // Not used { static Uint32 counter = 0; @@ -593,12 +593,12 @@ static void restoreCallback(int result, // Result for transaction * * (This function must have three arguments: * - The result of the transaction, - * - The NdbConnection object, and + * - The NdbTransaction object, and * - A pointer to an arbitrary object.) */ static void -callback(int result, NdbConnection* trans, void* aObject) +callback(int result, NdbTransaction* trans, void* aObject) { restore_callback_t *cb = (restore_callback_t *)aObject; (cb->restore)->cback(result, cb); @@ -610,7 +610,7 @@ callback(int result, NdbConnection* trans, void* aObject) * false if it is an error that generates an abort. */ static -bool asynchErrorHandler(NdbConnection * trans, Ndb* ndb) +bool asynchErrorHandler(NdbTransaction * trans, Ndb* ndb) { NdbError error = trans->getNdbError(); ndb->closeTransaction(trans); diff --git a/ndb/tools/select_all.cpp b/ndb/tools/select_all.cpp index 1d8442335dd..ecb7db91060 100644 --- a/ndb/tools/select_all.cpp +++ b/ndb/tools/select_all.cpp @@ -24,7 +24,6 @@ #include <NdbMain.h> #include <NDBT.hpp> #include <NdbSleep.h> -#include <NdbScanFilter.hpp> int scanReadRecords(Ndb*, const NdbDictionary::Table*, @@ -127,19 +126,21 @@ int main(int argc, char** argv){ 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,0) < 0) + { + ndbout << "Cluster nodes not ready in 30 seconds." << endl; return NDBT_ProgramExit(NDBT_FAILED); } - Ndb MyNdb(&con, _dbname ); + Ndb MyNdb(&con, _dbname ); 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; - // Check if table exists in db const NdbDictionary::Table* pTab = NDBT_Table::discoverTableFromDb(&MyNdb, _tabname); const NdbDictionary::Index * pIdx = 0; @@ -194,7 +195,7 @@ int scanReadRecords(Ndb* pNdb, int retryAttempt = 0; const int retryMax = 100; int check; - NdbConnection *pTrans; + NdbTransaction *pTrans; NdbScanOperation *pOp; NdbIndexScanOperation * pIOp= 0; @@ -320,7 +321,7 @@ int scanReadRecords(Ndb* pNdb, } } - check = pTrans->execute(NoCommit); + check = pTrans->execute(NdbTransaction::NoCommit); if( check == -1 ) { const NdbError err = pTrans->getNdbError(); diff --git a/ndb/tools/select_count.cpp b/ndb/tools/select_count.cpp index 156d31f70fd..f2b78de4b37 100644 --- a/ndb/tools/select_count.cpp +++ b/ndb/tools/select_count.cpp @@ -100,19 +100,21 @@ int main(int argc, char** argv){ 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,0) < 0) + { + ndbout << "Cluster nodes not ready in 30 seconds." << endl; return NDBT_ProgramExit(NDBT_FAILED); } - Ndb MyNdb(&con, _dbname ); + Ndb MyNdb(&con, _dbname ); 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; - for(int i = 0; i<argc; i++){ // Check if table exists in db const NdbDictionary::Table * pTab = NDBT_Table::discoverTableFromDb(&MyNdb, argv[i]); @@ -141,7 +143,7 @@ select_count(Ndb* pNdb, const NdbDictionary::Table* pTab, int retryAttempt = 0; const int retryMax = 100; int check; - NdbConnection *pTrans; + NdbTransaction *pTrans; NdbScanOperation *pOp; while (true){ @@ -189,7 +191,7 @@ select_count(Ndb* pNdb, const NdbDictionary::Table* pTab, Uint32 row_size; pOp->getValue(NdbDictionary::Column::ROW_COUNT, (char*)&tmp); pOp->getValue(NdbDictionary::Column::ROW_SIZE, (char*)&row_size); - check = pTrans->execute(NoCommit); + check = pTrans->execute(NdbTransaction::NoCommit); if( check == -1 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 548981ddbad..3cd418b776a 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -154,47 +154,55 @@ static int ndb_to_mysql_error(const NdbError *err) inline -int execute_no_commit(ha_ndbcluster *h, NdbConnection *trans) +int execute_no_commit(ha_ndbcluster *h, NdbTransaction *trans) { int m_batch_execute= 0; #ifdef NOT_USED if (m_batch_execute) return 0; #endif - return trans->execute(NoCommit,AbortOnError,h->m_force_send); + return trans->execute(NdbTransaction::NoCommit, + NdbTransaction::AbortOnError, + h->m_force_send); } inline -int execute_commit(ha_ndbcluster *h, NdbConnection *trans) +int execute_commit(ha_ndbcluster *h, NdbTransaction *trans) { int m_batch_execute= 0; #ifdef NOT_USED if (m_batch_execute) return 0; #endif - return trans->execute(Commit,AbortOnError,h->m_force_send); + return trans->execute(NdbTransaction::Commit, + NdbTransaction::AbortOnError, + h->m_force_send); } inline -int execute_commit(THD *thd, NdbConnection *trans) +int execute_commit(THD *thd, NdbTransaction *trans) { int m_batch_execute= 0; #ifdef NOT_USED if (m_batch_execute) return 0; #endif - return trans->execute(Commit,AbortOnError,thd->variables.ndb_force_send); + return trans->execute(NdbTransaction::Commit, + NdbTransaction::AbortOnError, + thd->variables.ndb_force_send); } inline -int execute_no_commit_ie(ha_ndbcluster *h, NdbConnection *trans) +int execute_no_commit_ie(ha_ndbcluster *h, NdbTransaction *trans) { int m_batch_execute= 0; #ifdef NOT_USED if (m_batch_execute) return 0; #endif - return trans->execute(NoCommit,AO_IgnoreError,h->m_force_send); + return trans->execute(NdbTransaction::NoCommit, + NdbTransaction::AO_IgnoreError, + h->m_force_send); } /* @@ -330,7 +338,7 @@ void ha_ndbcluster::no_uncommitted_rows_reset(THD *thd) */ -int ha_ndbcluster::ndb_err(NdbConnection *trans) +int ha_ndbcluster::ndb_err(NdbTransaction *trans) { int res; const NdbError err= trans->getNdbError(); @@ -1091,7 +1099,7 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf) DBUG_PRINT("enter", ("key_len: %u", key_len)); DBUG_DUMP("key", (char*)key, key_len); uint no_fields= table->fields, i; - NdbConnection *trans= m_active_trans; + NdbTransaction *trans= m_active_trans; NdbOperation *op; THD *thd= current_thd; @@ -1141,7 +1149,7 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf) int ha_ndbcluster::complemented_pk_read(const byte *old_data, byte *new_data) { uint no_fields= table->fields, i; - NdbConnection *trans= m_active_trans; + NdbTransaction *trans= m_active_trans; NdbOperation *op; THD *thd= current_thd; DBUG_ENTER("complemented_pk_read"); @@ -1204,7 +1212,7 @@ int ha_ndbcluster::complemented_pk_read(const byte *old_data, byte *new_data) int ha_ndbcluster::peek_row() { - NdbConnection *trans= m_active_trans; + NdbTransaction *trans= m_active_trans; NdbOperation *op; THD *thd= current_thd; DBUG_ENTER("peek_row"); @@ -1235,7 +1243,7 @@ int ha_ndbcluster::unique_index_read(const byte *key, uint key_len, byte *buf) { int res; - NdbConnection *trans= m_active_trans; + NdbTransaction *trans= m_active_trans; NdbIndexOperation *op; DBUG_ENTER("ha_ndbcluster::unique_index_read"); DBUG_PRINT("enter", ("key_len: %u, index: %u", key_len, active_index)); @@ -1271,7 +1279,7 @@ inline int ha_ndbcluster::fetch_next(NdbScanOperation* cursor) { DBUG_ENTER("fetch_next"); int check; - NdbConnection *trans= m_active_trans; + NdbTransaction *trans= m_active_trans; bool contact_ndb= m_lock.type < TL_WRITE_ALLOW_WRITE; do { @@ -1551,7 +1559,7 @@ int ha_ndbcluster::define_read_attrs(byte* buf, NdbOperation* op) { uint i; THD *thd= current_thd; - NdbConnection *trans= m_active_trans; + NdbTransaction *trans= m_active_trans; DBUG_ENTER("define_read_attrs"); @@ -1598,7 +1606,7 @@ int ha_ndbcluster::ordered_index_scan(const key_range *start_key, { int res; bool restart; - NdbConnection *trans= m_active_trans; + NdbTransaction *trans= m_active_trans; NdbIndexScanOperation *op; DBUG_ENTER("ha_ndbcluster::ordered_index_scan"); @@ -1668,7 +1676,7 @@ int ha_ndbcluster::filtered_scan(const byte *key, uint key_len, enum ha_rkey_function find_flag) { int res; - NdbConnection *trans= m_active_trans; + NdbTransaction *trans= m_active_trans; NdbScanOperation *op; DBUG_ENTER("filtered_scan"); @@ -1748,7 +1756,7 @@ int ha_ndbcluster::full_table_scan(byte *buf) uint i; int res; NdbScanOperation *op; - NdbConnection *trans= m_active_trans; + NdbTransaction *trans= m_active_trans; DBUG_ENTER("full_table_scan"); DBUG_PRINT("enter", ("Starting new scan on %s", m_tabname)); @@ -1776,7 +1784,7 @@ int ha_ndbcluster::write_row(byte *record) { bool has_auto_increment; uint i; - NdbConnection *trans= m_active_trans; + NdbTransaction *trans= m_active_trans; NdbOperation *op; int res; THD *thd= current_thd; @@ -1945,7 +1953,7 @@ int ha_ndbcluster::key_cmp(uint keynr, const byte * old_row, int ha_ndbcluster::update_row(const byte *old_data, byte *new_data) { THD *thd= current_thd; - NdbConnection *trans= m_active_trans; + NdbTransaction *trans= m_active_trans; NdbScanOperation* cursor= m_active_cursor; NdbOperation *op; uint i; @@ -2063,7 +2071,7 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data) int ha_ndbcluster::delete_row(const byte *record) { THD *thd= current_thd; - NdbConnection *trans= m_active_trans; + NdbTransaction *trans= m_active_trans; NdbScanOperation* cursor= m_active_cursor; NdbOperation *op; DBUG_ENTER("delete_row"); @@ -2635,7 +2643,7 @@ int ha_ndbcluster::rnd_init(bool scan) int ha_ndbcluster::close_scan() { - NdbConnection *trans= m_active_trans; + NdbTransaction *trans= m_active_trans; DBUG_ENTER("close_scan"); m_multi_cursor= 0; @@ -2983,7 +2991,7 @@ int ha_ndbcluster::end_bulk_insert() // Check if last inserts need to be flushed if (m_bulk_insert_not_flushed) { - NdbConnection *trans= m_active_trans; + NdbTransaction *trans= m_active_trans; // Send rows to NDB DBUG_PRINT("info", ("Sending inserts to NDB, "\ "rows_inserted:%d, bulk_insert_rows: %d", @@ -3102,7 +3110,7 @@ THR_LOCK_DATA **ha_ndbcluster::store_lock(THD *thd, int ha_ndbcluster::external_lock(THD *thd, int lock_type) { int error=0; - NdbConnection* trans= NULL; + NdbTransaction* trans= NULL; DBUG_ENTER("external_lock"); /* @@ -3189,8 +3197,8 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) // m_use_local_query_cache= thd->variables.ndb_use_local_query_cache; m_active_trans= thd->transaction.all.ndb_tid ? - (NdbConnection*)thd->transaction.all.ndb_tid: - (NdbConnection*)thd->transaction.stmt.ndb_tid; + (NdbTransaction*)thd->transaction.all.ndb_tid: + (NdbTransaction*)thd->transaction.stmt.ndb_tid; DBUG_ASSERT(m_active_trans); // Start of transaction m_retrieve_all_fields= FALSE; @@ -3272,13 +3280,13 @@ int ha_ndbcluster::start_stmt(THD *thd) DBUG_ENTER("start_stmt"); PRINT_OPTION_FLAGS(thd); - NdbConnection *trans= (NdbConnection*)thd->transaction.stmt.ndb_tid; + NdbTransaction *trans= (NdbTransaction*)thd->transaction.stmt.ndb_tid; if (!trans){ Ndb *ndb= ((Thd_ndb*)thd->transaction.thd_ndb)->ndb; DBUG_PRINT("trans",("Starting transaction stmt")); - NdbConnection *tablock_trans= - (NdbConnection*)thd->transaction.all.ndb_tid; + NdbTransaction *tablock_trans= + (NdbTransaction*)thd->transaction.all.ndb_tid; DBUG_PRINT("info", ("tablock_trans: %x", (uint)tablock_trans)); DBUG_ASSERT(tablock_trans); // trans= ndb->hupp(tablock_trans); @@ -3307,7 +3315,7 @@ int ndbcluster_commit(THD *thd, void *ndb_transaction) { int res= 0; Ndb *ndb= ((Thd_ndb*)thd->transaction.thd_ndb)->ndb; - NdbConnection *trans= (NdbConnection*)ndb_transaction; + NdbTransaction *trans= (NdbTransaction*)ndb_transaction; DBUG_ENTER("ndbcluster_commit"); DBUG_PRINT("transaction",("%s", @@ -3337,7 +3345,7 @@ int ndbcluster_rollback(THD *thd, void *ndb_transaction) { int res= 0; Ndb *ndb= ((Thd_ndb*)thd->transaction.thd_ndb)->ndb; - NdbConnection *trans= (NdbConnection*)ndb_transaction; + NdbTransaction *trans= (NdbTransaction*)ndb_transaction; DBUG_ENTER("ndbcluster_rollback"); DBUG_PRINT("transaction",("%s", @@ -3345,7 +3353,7 @@ int ndbcluster_rollback(THD *thd, void *ndb_transaction) "stmt" : "all")); DBUG_ASSERT(ndb && trans); - if (trans->execute(Rollback) != 0) + if (trans->execute(NdbTransaction::Rollback) != 0) { const NdbError err= trans->getNdbError(); const NdbOperation *error_op= trans->getNdbErrorOperation(); @@ -4842,7 +4850,7 @@ ndb_get_table_statistics(Ndb* ndb, const char * table, { DBUG_ENTER("ndb_get_table_statistics"); DBUG_PRINT("enter", ("table: %s", table)); - NdbConnection* pTrans= ndb->startTransaction(); + NdbTransaction* pTrans= ndb->startTransaction(); do { if (pTrans == NULL) @@ -4863,7 +4871,9 @@ ndb_get_table_statistics(Ndb* ndb, const char * table, pOp->getValue(NdbDictionary::Column::ROW_COUNT, (char*)&rows); pOp->getValue(NdbDictionary::Column::COMMIT_COUNT, (char*)&commits); - check= pTrans->execute(NoCommit, AbortOnError, TRUE); + check= pTrans->execute(NdbTransaction::NoCommit, + NdbTransaction::AbortOnError, + TRUE); if (check == -1) break; |