diff options
Diffstat (limited to 'storage/ndb/test/newtonapi')
-rw-r--r-- | storage/ndb/test/newtonapi/basic_test/Makefile | 25 | ||||
-rw-r--r-- | storage/ndb/test/newtonapi/basic_test/basic/Makefile | 14 | ||||
-rw-r--r-- | storage/ndb/test/newtonapi/basic_test/basic/basic.cpp | 320 | ||||
-rw-r--r-- | storage/ndb/test/newtonapi/basic_test/bulk_read/Makefile | 14 | ||||
-rw-r--r-- | storage/ndb/test/newtonapi/basic_test/bulk_read/br_test.cpp | 261 | ||||
-rw-r--r-- | storage/ndb/test/newtonapi/basic_test/common.cpp | 132 | ||||
-rw-r--r-- | storage/ndb/test/newtonapi/basic_test/common.hpp | 65 | ||||
-rw-r--r-- | storage/ndb/test/newtonapi/basic_test/ptr_binding/Makefile | 14 | ||||
-rw-r--r-- | storage/ndb/test/newtonapi/basic_test/ptr_binding/ptr_binding_test.cpp | 263 | ||||
-rw-r--r-- | storage/ndb/test/newtonapi/basic_test/too_basic.cpp | 104 | ||||
-rw-r--r-- | storage/ndb/test/newtonapi/perf_test/Makefile | 14 | ||||
-rw-r--r-- | storage/ndb/test/newtonapi/perf_test/perf.cpp | 646 |
12 files changed, 1872 insertions, 0 deletions
diff --git a/storage/ndb/test/newtonapi/basic_test/Makefile b/storage/ndb/test/newtonapi/basic_test/Makefile new file mode 100644 index 00000000000..d7eaf984b12 --- /dev/null +++ b/storage/ndb/test/newtonapi/basic_test/Makefile @@ -0,0 +1,25 @@ +include .defs.mk + +TYPE := util + +PIC_ARCHIVE := Y +ARCHIVE_TARGET := newtonbasictestcommon + +A_LIB := Y +SO_LIB := Y +PIC_LIB := Y + +LIB_TARGET := NEWTON_BASICTEST_COMMON +LIB_TARGET_ARCHIVES := $(ARCHIVE_TARGET) NEWTON_API + + +SOURCES = common.cpp + +DIRS := basic \ + ptr_binding \ + bulk_read + +CCFLAGS_LOC := -I$(call fixpath,$(NDB_TOP)/include/util) -I$(call fixpath,$(NDB_TOP)/include/newtonapi) + +include $(NDB_TOP)/Epilogue.mk + diff --git a/storage/ndb/test/newtonapi/basic_test/basic/Makefile b/storage/ndb/test/newtonapi/basic_test/basic/Makefile new file mode 100644 index 00000000000..7e2945d2e5f --- /dev/null +++ b/storage/ndb/test/newtonapi/basic_test/basic/Makefile @@ -0,0 +1,14 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := newton_basic +BIN_TARGET_LIBS := +BIN_TARGET_ARCHIVES := NEWTON_BASICTEST_COMMON NEWTON_API +SOURCES := basic.cpp + +CCFLAGS_LOC := -I.. -I$(call fixpath,$(NDB_TOP)/include/util) -I$(call fixpath,$(NDB_TOP)/include/newtonapi) -I$(call fixpath,$(NDB_TOP)/include/portlib) + +include $(NDB_TOP)/Epilogue.mk + + diff --git a/storage/ndb/test/newtonapi/basic_test/basic/basic.cpp b/storage/ndb/test/newtonapi/basic_test/basic/basic.cpp new file mode 100644 index 00000000000..23c9d38cbdc --- /dev/null +++ b/storage/ndb/test/newtonapi/basic_test/basic/basic.cpp @@ -0,0 +1,320 @@ +/* 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; version 2 of the License. + + 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 */ + + + +/****** THIS LINE IS 80 CHARACTERS WIDE - DO *NOT* EXCEED 80 CHARACTERS! ****/ +extern "C" { +#include <dba.h> +} + +#include "common.hpp" + +#include <NdbOut.hpp> +#include <NdbSleep.h> +#include <NdbMain.h> + +static const +DBA_ColumnDesc_t EmpColDesc[] = { + { "emp_no", DBA_INT, PCN_SIZE_OF( Employee, EmpNo ), PCN_TRUE }, + { "first_name", DBA_CHAR, PCN_SIZE_OF( Employee, FirstName ), PCN_FALSE }, + { "last_name", DBA_CHAR, PCN_SIZE_OF( Employee, LastName ), PCN_FALSE } +}; + +static const +DBA_ColumnDesc_t AddColDesc[] = { + { "emp_no", DBA_INT, PCN_SIZE_OF( Address, EmpNo ), PCN_TRUE }, + { "street_name", DBA_CHAR, PCN_SIZE_OF( Address, StreetName ), PCN_FALSE}, + { "street_no", DBA_INT, PCN_SIZE_OF( Address, StreetNo ), PCN_FALSE}, + { "city", DBA_CHAR, PCN_SIZE_OF( Address, City ), PCN_FALSE} +} ; + +static const +DBA_ColumnBinding_t EmpBindings[] = { + DBA_BINDING( "emp_no", DBA_INT, Employee, EmpNo ), + DBA_BINDING( "last_name", DBA_CHAR, Employee, LastName ), + DBA_BINDING( "first_name", DBA_CHAR, Employee, FirstName) +}; + +static const +DBA_ColumnBinding_t AddBindings[] = { + DBA_BINDING( "emp_no", DBA_INT, Address, EmpNo ), + DBA_BINDING( "street_name", DBA_CHAR, Address, StreetName ), + DBA_BINDING( "street_no", DBA_INT, Address, StreetNo ), + DBA_BINDING( "city", DBA_CHAR, Address, City ) +}; + +static DBA_Binding_t * EmpB; +static DBA_Binding_t * AddB; + +static const int Rows = 6; + +static +Employee_t EMP_TABLE_DATA[] = { + { 1242, "Joe", "Dalton" }, + { 123, "Lucky", "Luke" }, + { 456, "Averell", "Dalton" }, + { 8976, "Gaston", "Lagaffe" }, + { 1122, "Jolly", "Jumper" }, + { 3211, "Leffe", "Pagrotsky" } +}; + +static +Employee_t EMP_TABLE_DATA_READ[] = { + { 1242, "", "" }, + { 123, "", "" }, + { 456, "", "" }, + { 8976, "", "" }, + { 1122, "", "" }, + { 3211, "", "" } +}; + +static +Address_t ADD_TABLE_DATA[] = { + { 1242, "Lonesome Street", 12, "Crime Town" }, + { 123, "Pistol Road", 13, "Fort Mount" }, + { 456, "Banking Blv.", 43, "Las Vegas" }, + { 8976, "ChancylleZee", 54, "Paris" }, + { 1122, "Lucky", 111, "Wild West" }, + { 3211, "Parlament St.", 11, "Stockholm" } +}; + +static +Address_t ADD_TABLE_DATA_READ[] = { + { 1242, "", 0, "" }, + { 123, "", 0, "" }, + { 456, "", 0, "" }, + { 8976, "", 0, "" }, + { 1122, "", 0, "" }, + { 3211, "", 0, "" } +}; + +static const char EMP_TABLE[] = "employees"; +static const char ADD_TABLE[] = "addresses"; + +static const int EmpNbCol = 3; +static const int AddNbCol = 4; + +static +void +DbCreate(void){ + + ndbout << "Opening database" << endl; + require( DBA_Open() == DBA_NO_ERROR ); + + ndbout << "Creating tables" << endl; + require( DBA_CreateTable( EMP_TABLE, EmpNbCol, EmpColDesc ) == DBA_NO_ERROR ); + require( DBA_CreateTable( ADD_TABLE, AddNbCol, AddColDesc ) == DBA_NO_ERROR ); + + ndbout << "Checking for table existance" << endl; + require( DBA_TableExists( EMP_TABLE ) ); + require( DBA_TableExists( ADD_TABLE ) ); +} + +static +void +CreateBindings(void){ + ndbout << "Creating bindings" << endl; + + EmpB = DBA_CreateBinding(EMP_TABLE, + EmpNbCol, + EmpBindings, + sizeof(Employee_t) ); + require(EmpB != 0); + + AddB = DBA_CreateBinding(ADD_TABLE, + AddNbCol, + AddBindings, + sizeof(Address_t) ); + require(AddB != 0); +} + +extern "C" { + static void insertCallback( DBA_ReqId_t, DBA_Error_t, DBA_ErrorCode_t ); + static void deleteCallback( DBA_ReqId_t, DBA_Error_t, DBA_ErrorCode_t ); + static void updateCallback( DBA_ReqId_t, DBA_Error_t, DBA_ErrorCode_t ); + static void readCallback ( DBA_ReqId_t, DBA_Error_t, DBA_ErrorCode_t ); + static void writeCallback ( DBA_ReqId_t, DBA_Error_t, DBA_ErrorCode_t ); +} + +static +void BasicArray(){ + ndbout << "Testing basic array operations" << endl; + + // Basic insert + DBA_ArrayInsertRows(EmpB, EMP_TABLE_DATA, Rows-2, insertCallback); + NdbSleep_SecSleep(1); + DBA_ArrayReadRows(EmpB, EMP_TABLE_DATA_READ, Rows-2, readCallback); + NdbSleep_SecSleep(1); + CompareRows(EMP_TABLE_DATA, Rows-2, EMP_TABLE_DATA_READ); + + // Basic update + AlterRows(EMP_TABLE_DATA, Rows-2); + DBA_ArrayUpdateRows(EmpB, EMP_TABLE_DATA, Rows-2, updateCallback); + NdbSleep_SecSleep(1); + DBA_ArrayReadRows(EmpB, EMP_TABLE_DATA_READ, Rows-2, readCallback); + NdbSleep_SecSleep(1); + CompareRows(EMP_TABLE_DATA, Rows-2, EMP_TABLE_DATA_READ); + + // Basic write + AlterRows(EMP_TABLE_DATA, Rows); + DBA_ArrayWriteRows(EmpB, EMP_TABLE_DATA, Rows, writeCallback); + NdbSleep_SecSleep(1); + DBA_ArrayReadRows(EmpB, EMP_TABLE_DATA_READ, Rows, readCallback); + NdbSleep_SecSleep(1); + CompareRows(EMP_TABLE_DATA, Rows, EMP_TABLE_DATA_READ); + + // Basic delete + DBA_ArrayDeleteRows(EmpB, EMP_TABLE_DATA, Rows, deleteCallback); + NdbSleep_SecSleep(1); +} + +static +void Multi(){ + ndbout << "Testing multi operations" << endl; + + const int R2 = Rows + Rows; + + DBA_Binding_t * Bindings[R2]; + void * DATA[R2]; + void * DATA_READ[R2]; + for(int i = 0; i<Rows; i++){ + Bindings[2*i] = EmpB; + Bindings[2*i+1] = AddB; + + DATA[2*i] = &EMP_TABLE_DATA[i]; + DATA[2*i+1] = &ADD_TABLE_DATA[i]; + + DATA_READ[2*i] = &EMP_TABLE_DATA_READ[i]; + DATA_READ[2*i+1] = &ADD_TABLE_DATA_READ[i]; + } + + // Basic insert + DBA_MultiInsertRow(Bindings, DATA, R2-4, insertCallback); + NdbSleep_SecSleep(1); + DBA_MultiReadRow (Bindings, DATA_READ, R2-4, readCallback); + NdbSleep_SecSleep(1); + + CompareRows(EMP_TABLE_DATA, Rows-2, EMP_TABLE_DATA_READ); + CompareRows(ADD_TABLE_DATA, Rows-2, ADD_TABLE_DATA_READ); + + // Basic update + AlterRows(EMP_TABLE_DATA, Rows-2); + AlterRows(ADD_TABLE_DATA, Rows-2); + DBA_MultiUpdateRow(Bindings, DATA, R2-4, updateCallback); + NdbSleep_SecSleep(1); + DBA_MultiReadRow (Bindings, DATA_READ, R2-4, readCallback); + NdbSleep_SecSleep(1); + CompareRows(EMP_TABLE_DATA, Rows-2, EMP_TABLE_DATA_READ); + CompareRows(ADD_TABLE_DATA, Rows-2, ADD_TABLE_DATA_READ); + + // Basic write + AlterRows(EMP_TABLE_DATA, Rows); + AlterRows(ADD_TABLE_DATA, Rows); + DBA_MultiWriteRow(Bindings, DATA, R2, writeCallback); + NdbSleep_SecSleep(1); + DBA_MultiReadRow (Bindings, DATA_READ, R2, readCallback); + NdbSleep_SecSleep(1); + CompareRows(EMP_TABLE_DATA, Rows, EMP_TABLE_DATA_READ); + CompareRows(ADD_TABLE_DATA, Rows, ADD_TABLE_DATA_READ); + + // Basic delete + DBA_MultiDeleteRow(Bindings, DATA, R2, deleteCallback); + NdbSleep_SecSleep(1); +} + +static +void BasicPtr(){ + ndbout << "Testing array of pointer operations" << endl; + Employee_t * EmpData[Rows]; + Employee_t * EmpDataRead[Rows]; + for(int i = 0; i<Rows; i++){ + EmpData[i] = &EMP_TABLE_DATA[i]; + EmpDataRead[i] = &EMP_TABLE_DATA_READ[i]; + } + + void * const * EMP_TABLE_DATA2 = (void * const *)EmpData; + void * const * EMP_TABLE_DATA_READ2 = (void * const *)EmpDataRead; + + // Basic insert + DBA_InsertRows(EmpB, EMP_TABLE_DATA2, Rows-2, insertCallback); + NdbSleep_SecSleep(1); + DBA_ReadRows (EmpB, EMP_TABLE_DATA_READ2, Rows-2, readCallback); + NdbSleep_SecSleep(1); + CompareRows(EMP_TABLE_DATA, Rows-2, EMP_TABLE_DATA_READ); + + // Basic update + AlterRows(EMP_TABLE_DATA, Rows-2); + DBA_UpdateRows(EmpB, EMP_TABLE_DATA2, Rows-2, updateCallback); + NdbSleep_SecSleep(1); + DBA_ReadRows (EmpB, EMP_TABLE_DATA_READ2, Rows-2, readCallback); + NdbSleep_SecSleep(1); + CompareRows(EMP_TABLE_DATA, Rows-2, EMP_TABLE_DATA_READ); + + // Basic write + AlterRows (EMP_TABLE_DATA, Rows); + DBA_WriteRows(EmpB, EMP_TABLE_DATA2, Rows, writeCallback); + NdbSleep_SecSleep(1); + DBA_ReadRows (EmpB, EMP_TABLE_DATA_READ2, Rows, readCallback); + NdbSleep_SecSleep(1); + CompareRows(EMP_TABLE_DATA, Rows, EMP_TABLE_DATA_READ); + + // Basic delete + DBA_DeleteRows(EmpB, EMP_TABLE_DATA2, Rows, deleteCallback); + NdbSleep_SecSleep(1); +} + +/*---------------------------------------------------------------------------*/ +NDB_COMMAND(newton_basic, "newton_basic", + "newton_basic", "newton_basic", 65535){ + + DbCreate(); + CreateBindings(); + + BasicArray(); + BasicPtr(); + Multi(); + + DBA_Close(); + + return 0; +} + + + +/** + * callbackStatusCheck checks whether or not the operation succeeded + */ +void +callbackStatusCheck( DBA_Error_t status, const char* operation) { + ndbout_c("%s: %d", operation, status); +} + +void insertCallback( DBA_ReqId_t, DBA_Error_t s, DBA_ErrorCode_t ){ + callbackStatusCheck(s, "insert"); +} +void deleteCallback( DBA_ReqId_t, DBA_Error_t s, DBA_ErrorCode_t ){ + callbackStatusCheck(s, "delete"); +} +void updateCallback( DBA_ReqId_t, DBA_Error_t s, DBA_ErrorCode_t ){ + callbackStatusCheck(s, "update"); +} +void readCallback ( DBA_ReqId_t, DBA_Error_t s, DBA_ErrorCode_t ){ + callbackStatusCheck(s, "read"); +} +void writeCallback ( DBA_ReqId_t, DBA_Error_t s, DBA_ErrorCode_t ){ + callbackStatusCheck(s, "write"); +} + diff --git a/storage/ndb/test/newtonapi/basic_test/bulk_read/Makefile b/storage/ndb/test/newtonapi/basic_test/bulk_read/Makefile new file mode 100644 index 00000000000..c45bbad7957 --- /dev/null +++ b/storage/ndb/test/newtonapi/basic_test/bulk_read/Makefile @@ -0,0 +1,14 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := newton_br +BIN_TARGET_LIBS := +BIN_TARGET_ARCHIVES := NEWTON_BASICTEST_COMMON NEWTON_API +SOURCES := br_test.cpp + +CCFLAGS_LOC := -I.. -I$(call fixpath,$(NDB_TOP)/include/util) -I$(call fixpath,$(NDB_TOP)/include/newtonapi) -I$(call fixpath,$(NDB_TOP)/include/portlib) + +include $(NDB_TOP)/Epilogue.mk + + diff --git a/storage/ndb/test/newtonapi/basic_test/bulk_read/br_test.cpp b/storage/ndb/test/newtonapi/basic_test/bulk_read/br_test.cpp new file mode 100644 index 00000000000..7b447b29e05 --- /dev/null +++ b/storage/ndb/test/newtonapi/basic_test/bulk_read/br_test.cpp @@ -0,0 +1,261 @@ +/* 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; version 2 of the License. + + 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 */ + + + +/****** THIS LINE IS 80 CHARACTERS WIDE - DO *NOT* EXCEED 80 CHARACTERS! ****/ +extern "C" { +#include <dba.h> +} + +#include "common.hpp" + +#include <NdbOut.hpp> +#include <NdbSleep.h> +#include <NdbMain.h> + +static const +DBA_ColumnDesc_t EmpColDesc[] = { + { "emp_no", DBA_INT, PCN_SIZE_OF( Employee, EmpNo ), PCN_TRUE }, + { "first_name", DBA_CHAR, PCN_SIZE_OF( Employee, FirstName ), PCN_FALSE }, + { "last_name", DBA_CHAR, PCN_SIZE_OF( Employee, LastName ), PCN_FALSE } +}; + +static const +DBA_ColumnDesc_t AddColDesc[] = { + { "emp_no", DBA_INT, PCN_SIZE_OF( Address, EmpNo ), PCN_TRUE }, + { "street_name", DBA_CHAR, PCN_SIZE_OF( Address, StreetName ), PCN_FALSE}, + { "street_no", DBA_INT, PCN_SIZE_OF( Address, StreetNo ), PCN_FALSE}, + { "city", DBA_CHAR, PCN_SIZE_OF( Address, City ), PCN_FALSE} +} ; + +static const +DBA_ColumnBinding_t EmpBindings[] = { + DBA_BINDING( "emp_no", DBA_INT, Employee, EmpNo ), + DBA_BINDING( "last_name", DBA_CHAR, Employee, LastName ), + DBA_BINDING( "first_name", DBA_CHAR, Employee, FirstName) +}; + +static const +DBA_ColumnBinding_t AddBindings[] = { + DBA_BINDING( "emp_no", DBA_INT, Address, EmpNo ), + DBA_BINDING( "street_name", DBA_CHAR, Address, StreetName ), + DBA_BINDING( "street_no", DBA_INT, Address, StreetNo ), + DBA_BINDING( "city", DBA_CHAR, Address, City ) +}; + +static DBA_Binding_t * EmpB; +static DBA_Binding_t * AddB; + +static const int Rows = 6; + +static +Employee_t EMP_TABLE_DATA[] = { + { 1242, "Joe", "Dalton" }, + { 123, "Lucky", "Luke" }, + { 456, "Averell", "Dalton" }, + { 8976, "Gaston", "Lagaffe" }, + { 1122, "Jolly", "Jumper" }, + { 3211, "Leffe", "Pagrotsky" } +}; + +static +Employee_t EMP_TABLE_DATA_READ[] = { + { 1242, "", "" }, + { 123, "", "" }, + { 456, "", "" }, + { 8976, "", "" }, + { 1122, "", "" }, + { 3211, "", "" } +}; + +static +Address_t ADD_TABLE_DATA[] = { + { 1242, "Lonesome Street", 12, "Crime Town" }, + { 123, "Pistol Road", 13, "Fort Mount" }, + { 456, "Banking Blv.", 43, "Las Vegas" }, + { 8976, "ChancylleZee", 54, "Paris" }, + { 1122, "Lucky", 111, "Wild West" }, + { 3211, "Parlament St.", 11, "Stockholm" } +}; + +static +Address_t ADD_TABLE_DATA_READ[] = { + { 1242, "", 0, "" }, + { 123, "", 0, "" }, + { 456, "", 0, "" }, + { 8976, "", 0, "" }, + { 1122, "", 0, "" }, + { 3211, "", 0, "" } +}; + +static const char EMP_TABLE[] = "employees"; +static const char ADD_TABLE[] = "addresses"; + +static const int EmpNbCol = 3; +static const int AddNbCol = 4; + +static +void +DbCreate(void){ + + ndbout << "Opening database" << endl; + require( DBA_Open() == DBA_NO_ERROR ); + + ndbout << "Creating tables" << endl; + require( DBA_CreateTable( EMP_TABLE, EmpNbCol, EmpColDesc ) == DBA_NO_ERROR ); + require( DBA_CreateTable( ADD_TABLE, AddNbCol, AddColDesc ) == DBA_NO_ERROR ); + + ndbout << "Checking for table existance" << endl; + require( DBA_TableExists( EMP_TABLE ) ); + require( DBA_TableExists( ADD_TABLE ) ); +} + +static +void +CreateBindings(void){ + ndbout << "Creating bindings" << endl; + + EmpB = DBA_CreateBinding(EMP_TABLE, + EmpNbCol, + EmpBindings, + sizeof(Employee_t) ); + require(EmpB != 0); + + AddB = DBA_CreateBinding(ADD_TABLE, + AddNbCol, + AddBindings, + sizeof(Address_t) ); + require(AddB != 0); +} + +int +CountRows(DBA_BulkReadResultSet_t * rs, int count){ + int res = 0; + for(int i = 0; i<count; i++) + if(rs[i].RowFoundIndicator) + res++; + return res; +} + +extern "C" { + static void insertCallback( DBA_ReqId_t, DBA_Error_t, DBA_ErrorCode_t ); + static void deleteCallback( DBA_ReqId_t, DBA_Error_t, DBA_ErrorCode_t ); + static void updateCallback( DBA_ReqId_t, DBA_Error_t, DBA_ErrorCode_t ); + static void readCallback ( DBA_ReqId_t, DBA_Error_t, DBA_ErrorCode_t ); + static void writeCallback ( DBA_ReqId_t, DBA_Error_t, DBA_ErrorCode_t ); +} + +static +void Multi(){ + ndbout << "Testing multi operations" << endl; + + DBA_ArrayInsertRows(EmpB, EMP_TABLE_DATA, Rows-2, insertCallback); + DBA_ArrayInsertRows(AddB, ADD_TABLE_DATA, Rows-2, insertCallback); + NdbSleep_SecSleep(1); + + const int R2 = Rows + Rows; + + DBA_Binding_t * Bindings[2]; + DBA_BulkReadResultSet_t DataRead[R2]; + + Bindings[0] = EmpB; + Bindings[1] = AddB; + + for(int i = 0; i<Rows; i++) + DataRead[i].DataPtr = &EMP_TABLE_DATA_READ[i]; + + for(int i = 0; i<Rows; i++) + DataRead[i+Rows].DataPtr = &ADD_TABLE_DATA_READ[i]; + + NdbSleep_SecSleep(1); + + DBA_BulkMultiReadRows(Bindings, DataRead, 2, Rows, readCallback); + NdbSleep_SecSleep(1); + CompareRows(EMP_TABLE_DATA, Rows-2, EMP_TABLE_DATA_READ); + CompareRows(ADD_TABLE_DATA, Rows-2, ADD_TABLE_DATA_READ); + + require(CountRows(DataRead, R2) == (R2-4)); + + // Basic delete + DBA_ArrayDeleteRows(EmpB, EMP_TABLE_DATA, Rows-2, deleteCallback); + DBA_ArrayDeleteRows(AddB, ADD_TABLE_DATA, Rows-2, deleteCallback); + NdbSleep_SecSleep(1); +} + +static +void BasicPtr(){ + ndbout << "Testing array of pointer operations" << endl; + + // Basic insert + DBA_ArrayInsertRows(EmpB, EMP_TABLE_DATA, Rows-2, insertCallback); + NdbSleep_SecSleep(1); + + DBA_BulkReadResultSet_t EmpDataRead[Rows]; + for(int i = 0; i<Rows; i++){ + EmpDataRead[i].DataPtr = &EMP_TABLE_DATA_READ[i]; + } + + DBA_BulkReadRows(EmpB, EmpDataRead, Rows, readCallback); + NdbSleep_SecSleep(1); + CompareRows(EMP_TABLE_DATA, Rows-2, EMP_TABLE_DATA_READ); + require(CountRows(EmpDataRead, Rows) == (Rows-2)); + + // Basic delete + DBA_ArrayDeleteRows(EmpB, EMP_TABLE_DATA, Rows-2, deleteCallback); + NdbSleep_SecSleep(1); +} + +/*---------------------------------------------------------------------------*/ +NDB_COMMAND(newton_br, "newton_br", + "newton_br", "newton_br", 65535){ + + DbCreate(); + CreateBindings(); + + BasicPtr(); + Multi(); + + DBA_Close(); + + return 0; +} + + + +/** + * callbackStatusCheck checks whether or not the operation succeeded + */ +void +callbackStatusCheck( DBA_Error_t status, const char* operation) { + ndbout_c("%s: %d", operation, status); +} + +void insertCallback( DBA_ReqId_t, DBA_Error_t s, DBA_ErrorCode_t ){ + callbackStatusCheck(s, "insert"); +} +void deleteCallback( DBA_ReqId_t, DBA_Error_t s, DBA_ErrorCode_t ){ + callbackStatusCheck(s, "delete"); +} +void updateCallback( DBA_ReqId_t, DBA_Error_t s, DBA_ErrorCode_t ){ + callbackStatusCheck(s, "update"); +} +void readCallback ( DBA_ReqId_t, DBA_Error_t s, DBA_ErrorCode_t ){ + callbackStatusCheck(s, "read"); +} +void writeCallback ( DBA_ReqId_t, DBA_Error_t s, DBA_ErrorCode_t ){ + callbackStatusCheck(s, "write"); +} + diff --git a/storage/ndb/test/newtonapi/basic_test/common.cpp b/storage/ndb/test/newtonapi/basic_test/common.cpp new file mode 100644 index 00000000000..d393394dcc9 --- /dev/null +++ b/storage/ndb/test/newtonapi/basic_test/common.cpp @@ -0,0 +1,132 @@ +/* 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; version 2 of the License. + + 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 */ + + +#include "common.hpp" + +NdbOut & +operator << (NdbOut & out, const Employee_t & emp){ + out << emp.EmpNo << " \"" << emp.FirstName << "\" \"" + << emp.LastName << "\""; + return out; +} + +bool +operator==(const Employee_t & e1, const Employee_t & e2){ + if(e1.EmpNo != e2.EmpNo) + return false; + if(strcmp(e1.FirstName, e2.FirstName) != 0) + return false; + return strcmp(e1.LastName, e2.LastName) == 0; +} + +void +Alter(Employee_t & emp){ + static int updown = 0; + if(updown == 0){ + for(int i = 0; i<strlen(emp.FirstName); i++) + toupper(emp.FirstName[i]); + + for(int i = 0; i<strlen(emp.LastName); i++) + toupper(emp.LastName[i]); + } else { + for(int i = 0; i<strlen(emp.FirstName); i++) + tolower(emp.FirstName[i]); + + for(int i = 0; i<strlen(emp.LastName); i++) + tolower(emp.LastName[i]); + } + updown = 1 - updown; +} + +void +CompareRows(Employee_t * data1, + int rows, + Employee_t * data2){ + for(int i = 0; i<rows; i++){ + if(!(data1[i] == data2[i])){ + ndbout << data1[i] << endl + << data2[i] << endl; + } + } +} + +void +AlterRows(Employee_t * data1, int rows){ + for(int i = 0; i<rows; i++){ + Alter(data1[i]); + } +} + +inline +NdbOut & +operator << (NdbOut & out, const Address_t & adr){ + out << adr.EmpNo << " \"" << adr.StreetName << "\" " + << adr.StreetNo << " \"" << adr.City << "\""; + return out; +} + +inline +bool +operator==(const Address_t & a1, const Address_t & a2){ + if(a1.EmpNo != a2.EmpNo) + return false; + if(a1.StreetNo != a2.StreetNo) + return false; + if(strcmp(a1.StreetName, a2.StreetName) != 0) + return false; + return strcmp(a1.City, a2.City) == 0; +} + +inline +void +Alter(Address_t & emp){ + static int updown = 0; + if(updown == 0){ + for(int i = 0; i<strlen(emp.StreetName); i++) + toupper(emp.StreetName[i]); + + for(int i = 0; i<strlen(emp.City); i++) + toupper(emp.City[i]); + } else { + for(int i = 0; i<strlen(emp.StreetName); i++) + tolower(emp.StreetName[i]); + + for(int i = 0; i<strlen(emp.City); i++) + tolower(emp.City[i]); + } + emp.StreetNo *= emp.EmpNo; + updown = 1 - updown; +} + +void +CompareRows(Address_t * data1, + int rows, + Address_t * data2){ + for(int i = 0; i<rows; i++){ + if(!(data1[i] == data2[i])){ + ndbout << data1[i] << endl + << data2[i] << endl; + } + } +} + +void +AlterRows(Address_t * data1, int rows){ + for(int i = 0; i<rows; i++){ + Alter(data1[i]); + } +} + diff --git a/storage/ndb/test/newtonapi/basic_test/common.hpp b/storage/ndb/test/newtonapi/basic_test/common.hpp new file mode 100644 index 00000000000..d76d1cf1733 --- /dev/null +++ b/storage/ndb/test/newtonapi/basic_test/common.hpp @@ -0,0 +1,65 @@ +/* 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; version 2 of the License. + + 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 */ + +#ifndef COMMON_H +#define COMMON_H + +#include <ndb_global.h> + +extern "C" { +#include <dba.h> +} + +#include <NdbOut.hpp> + +typedef struct Employee { + UInt32_t EmpNo; + char FirstName[24]; + char LastName[24]; + + struct Address * EmployeeAddress; +} Employee_t; + +typedef struct Address { + UInt32_t EmpNo; + char StreetName[24]; + UInt32_t StreetNo; + char City[12]; +} Address_t; + +/** + * Employee functions + */ +NdbOut & operator << (NdbOut & out, const Employee_t & emp); +bool operator==(const Employee_t & e1, const Employee_t & e2); +void Alter(Employee_t & emp); +void CompareRows(Employee_t * data1, int rows, Employee_t * data2); +void AlterRows(Employee_t * data1, int rows); + +/** + * Address functions + */ +NdbOut & operator << (NdbOut & out, const Address_t & adr); +bool operator==(const Address_t & a1, const Address_t & a2); +void Alter(Address_t & emp); +void CompareRows(Address_t * data1, int rows, Address_t * data2); +void AlterRows(Address_t * data1, int rows); + +inline void require(bool test){ + if(!test) + abort(); +} + +#endif diff --git a/storage/ndb/test/newtonapi/basic_test/ptr_binding/Makefile b/storage/ndb/test/newtonapi/basic_test/ptr_binding/Makefile new file mode 100644 index 00000000000..95e87d47e62 --- /dev/null +++ b/storage/ndb/test/newtonapi/basic_test/ptr_binding/Makefile @@ -0,0 +1,14 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := newton_pb +BIN_TARGET_LIBS := +BIN_TARGET_ARCHIVES := NEWTON_BASICTEST_COMMON NEWTON_API +SOURCES := ptr_binding_test.cpp + +CCFLAGS_LOC := -I.. -I$(call fixpath,$(NDB_TOP)/include/util) -I$(call fixpath,$(NDB_TOP)/include/newtonapi) -I$(call fixpath,$(NDB_TOP)/include/portlib) + +include $(NDB_TOP)/Epilogue.mk + + diff --git a/storage/ndb/test/newtonapi/basic_test/ptr_binding/ptr_binding_test.cpp b/storage/ndb/test/newtonapi/basic_test/ptr_binding/ptr_binding_test.cpp new file mode 100644 index 00000000000..754dad25dba --- /dev/null +++ b/storage/ndb/test/newtonapi/basic_test/ptr_binding/ptr_binding_test.cpp @@ -0,0 +1,263 @@ +/* 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; version 2 of the License. + + 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 */ + + + +/****** THIS LINE IS 80 CHARACTERS WIDE - DO *NOT* EXCEED 80 CHARACTERS! ****/ +extern "C" { +#include <dba.h> +} + +#include "common.hpp" + +#include <NdbOut.hpp> +#include <NdbSleep.h> +#include <NdbMain.h> + +static const +DBA_ColumnDesc_t ColDesc[] = { + { "emp_no", DBA_INT, PCN_SIZE_OF( Employee, EmpNo ), PCN_TRUE }, + { "first_name", DBA_CHAR, PCN_SIZE_OF( Employee, FirstName ), PCN_FALSE }, + { "last_name", DBA_CHAR, PCN_SIZE_OF( Employee, LastName ), PCN_FALSE }, + { "street_name",DBA_CHAR, PCN_SIZE_OF( Address, StreetName ), PCN_FALSE }, + { "street_no", DBA_INT, PCN_SIZE_OF( Address, StreetNo ), PCN_FALSE }, + { "city", DBA_CHAR, PCN_SIZE_OF( Address, City ), PCN_FALSE } +}; +static const int NbCol = 6; + +static const +DBA_ColumnBinding_t AddBindings[] = { + //DBA_BINDING( "emp_no", DBA_INT, Address, EmpNo ), + DBA_BINDING( "street_name", DBA_CHAR, Address, StreetName ), + DBA_BINDING( "street_no", DBA_INT, Address, StreetNo ), + DBA_BINDING( "city", DBA_CHAR, Address, City ) +}; + +static const +int AddBindingRows = sizeof(AddBindings)/sizeof(DBA_ColumnBinding_t); + +static const +DBA_ColumnBinding_t EmpBindings[] = { + DBA_BINDING( "emp_no", DBA_INT, Employee, EmpNo ), + DBA_BINDING( "last_name", DBA_CHAR, Employee, LastName ), + DBA_BINDING( "first_name", DBA_CHAR, Employee, FirstName), + DBA_BINDING_PTR(Employee, EmployeeAddress, AddBindings, AddBindingRows) +}; +static const +int EmpBindingRows = sizeof(EmpBindings)/sizeof(DBA_ColumnBinding_t); + +static DBA_Binding_t * Bind; + +static const int Rows = 6; + +static +Address_t ADD_TABLE_DATA[] = { + { 1242, "Lonesome Street", 12, "Crime Town" }, + { 123, "Pistol Road", 13, "Fort Mount" }, + { 456, "Banking Blv.", 43, "Las Vegas" }, + { 8976, "ChancylleZee", 54, "Paris" }, + { 1122, "Lucky", 111, "Wild West" }, + { 3211, "Parlament St.", 11, "Stockholm" } +}; + +static +Address_t ADD_TABLE_DATA_READ[] = { + { 1242, "", 0, "" }, + { 123, "", 0, "" }, + { 456, "", 0, "" }, + { 8976, "", 0, "" }, + { 1122, "", 0, "" }, + { 3211, "", 0, "" } +}; + +static +Employee_t EMP_TABLE_DATA[] = { + { 1242, "Joe", "Dalton" , &ADD_TABLE_DATA[0] }, + { 123, "Lucky", "Luke" , &ADD_TABLE_DATA[1] }, + { 456, "Averell", "Dalton" , &ADD_TABLE_DATA[2] }, + { 8976, "Gaston", "Lagaffe", &ADD_TABLE_DATA[3] }, + { 1122, "Jolly", "Jumper" , &ADD_TABLE_DATA[4] }, + { 3211, "Leffe", "Pagrotsky", &ADD_TABLE_DATA[5] }, +}; + +static +Employee_t EMP_TABLE_DATA_READ[] = { + { 1242, "", "", &ADD_TABLE_DATA_READ[0] }, + { 123, "", "", &ADD_TABLE_DATA_READ[1] }, + { 456, "", "", &ADD_TABLE_DATA_READ[2] }, + { 8976, "", "", &ADD_TABLE_DATA_READ[3] }, + { 1122, "", "", &ADD_TABLE_DATA_READ[4] }, + { 3211, "", "", &ADD_TABLE_DATA_READ[5] } +}; + +static const char TABLE[] = "employee_address"; + +static +void +DbCreate(void){ + + ndbout << "Opening database" << endl; + require( DBA_Open() == DBA_NO_ERROR ); + + ndbout << "Creating tables" << endl; + require( DBA_CreateTable( TABLE, NbCol, ColDesc ) == DBA_NO_ERROR ); + + ndbout << "Checking for table existance" << endl; + require( DBA_TableExists( TABLE ) ); +} + +static +void +CreateBindings(void){ + ndbout << "Creating bindings" << endl; + + Bind = DBA_CreateBinding(TABLE, + EmpBindingRows, + EmpBindings, + sizeof(Employee_t) ); + + require(Bind != 0); +} + +extern "C" { + static void insertCallback( DBA_ReqId_t, DBA_Error_t, DBA_ErrorCode_t ); + static void deleteCallback( DBA_ReqId_t, DBA_Error_t, DBA_ErrorCode_t ); + static void updateCallback( DBA_ReqId_t, DBA_Error_t, DBA_ErrorCode_t ); + static void readCallback ( DBA_ReqId_t, DBA_Error_t, DBA_ErrorCode_t ); + static void writeCallback ( DBA_ReqId_t, DBA_Error_t, DBA_ErrorCode_t ); +} + +static +void BasicArray(){ + ndbout << "Testing basic array operations" << endl; + + // Basic insert + DBA_ArrayInsertRows(Bind, EMP_TABLE_DATA, Rows-2, insertCallback); + NdbSleep_SecSleep(1); + DBA_ArrayReadRows (Bind, EMP_TABLE_DATA_READ, Rows-2, readCallback); + NdbSleep_SecSleep(1); + CompareRows(EMP_TABLE_DATA, Rows-2, EMP_TABLE_DATA_READ); + CompareRows(ADD_TABLE_DATA, Rows-2, ADD_TABLE_DATA_READ); + + // Basic update + AlterRows (EMP_TABLE_DATA, Rows-2); + AlterRows (ADD_TABLE_DATA, Rows-2); + DBA_ArrayUpdateRows(Bind, EMP_TABLE_DATA, Rows-2, updateCallback); + NdbSleep_SecSleep(1); + DBA_ArrayReadRows (Bind, EMP_TABLE_DATA_READ, Rows-2, readCallback); + NdbSleep_SecSleep(1); + CompareRows(EMP_TABLE_DATA, Rows-2, EMP_TABLE_DATA_READ); + CompareRows(ADD_TABLE_DATA, Rows-2, ADD_TABLE_DATA_READ); + + // Basic write + AlterRows (EMP_TABLE_DATA, Rows); + AlterRows (ADD_TABLE_DATA, Rows); + DBA_ArrayWriteRows(Bind, EMP_TABLE_DATA, Rows, writeCallback); + NdbSleep_SecSleep(1); + DBA_ArrayReadRows (Bind, EMP_TABLE_DATA_READ, Rows, readCallback); + NdbSleep_SecSleep(1); + CompareRows(EMP_TABLE_DATA, Rows, EMP_TABLE_DATA_READ); + CompareRows(ADD_TABLE_DATA, Rows, ADD_TABLE_DATA_READ); + + // Basic delete + DBA_ArrayDeleteRows(Bind, EMP_TABLE_DATA, Rows, deleteCallback); + NdbSleep_SecSleep(1); +} + +static +void BasicPtr(){ + ndbout << "Testing array of pointer operations" << endl; + Employee_t * EmpData[Rows]; + Employee_t * EmpDataRead[Rows]; + for(int i = 0; i<Rows; i++){ + EmpData[i] = &EMP_TABLE_DATA[i]; + EmpDataRead[i] = &EMP_TABLE_DATA_READ[i]; + } + + void * const * EMP_TABLE_DATA2 = (void * const *)EmpData; + void * const * EMP_TABLE_DATA_READ2 = (void * const *)EmpDataRead; + + // Basic insert + DBA_InsertRows(Bind, EMP_TABLE_DATA2, Rows-2, insertCallback); + NdbSleep_SecSleep(1); + DBA_ReadRows (Bind, EMP_TABLE_DATA_READ2, Rows-2, readCallback); + NdbSleep_SecSleep(1); + CompareRows(EMP_TABLE_DATA, Rows-2, EMP_TABLE_DATA_READ); + CompareRows(ADD_TABLE_DATA, Rows-2, ADD_TABLE_DATA_READ); + + // Basic update + AlterRows (ADD_TABLE_DATA, Rows-2); + AlterRows (EMP_TABLE_DATA, Rows-2); + DBA_UpdateRows(Bind, EMP_TABLE_DATA2, Rows-2, updateCallback); + NdbSleep_SecSleep(1); + DBA_ReadRows (Bind, EMP_TABLE_DATA_READ2, Rows-2, readCallback); + NdbSleep_SecSleep(1); + CompareRows(EMP_TABLE_DATA, Rows-2, EMP_TABLE_DATA_READ); + CompareRows(ADD_TABLE_DATA, Rows-2, ADD_TABLE_DATA_READ); + + // Basic write + AlterRows (ADD_TABLE_DATA, Rows); + AlterRows (EMP_TABLE_DATA, Rows); + DBA_WriteRows(Bind, EMP_TABLE_DATA2, Rows, writeCallback); + NdbSleep_SecSleep(1); + DBA_ReadRows (Bind, EMP_TABLE_DATA_READ2, Rows, readCallback); + NdbSleep_SecSleep(1); + CompareRows(EMP_TABLE_DATA, Rows, EMP_TABLE_DATA_READ); + CompareRows(ADD_TABLE_DATA, Rows, ADD_TABLE_DATA_READ); + + // Basic delete + DBA_DeleteRows(Bind, EMP_TABLE_DATA2, Rows, deleteCallback); + NdbSleep_SecSleep(1); +} + +/*---------------------------------------------------------------------------*/ +NDB_COMMAND(newton_pb, "newton_pb", + "newton_pb", "newton_pb", 65535){ + + DbCreate(); + CreateBindings(); + + BasicArray(); + BasicPtr(); + + DBA_Close(); + + return 0; +} + +/** + * callbackStatusCheck checks whether or not the operation succeeded + */ +void +callbackStatusCheck( DBA_Error_t status, const char* operation) { + ndbout_c("%s: %d", operation, status); +} + +void insertCallback( DBA_ReqId_t, DBA_Error_t s, DBA_ErrorCode_t ){ + callbackStatusCheck(s, "insert"); +} +void deleteCallback( DBA_ReqId_t, DBA_Error_t s, DBA_ErrorCode_t ){ + callbackStatusCheck(s, "delete"); +} +void updateCallback( DBA_ReqId_t, DBA_Error_t s, DBA_ErrorCode_t ){ + callbackStatusCheck(s, "update"); +} +void readCallback ( DBA_ReqId_t, DBA_Error_t s, DBA_ErrorCode_t ){ + callbackStatusCheck(s, "read"); +} +void writeCallback ( DBA_ReqId_t, DBA_Error_t s, DBA_ErrorCode_t ){ + callbackStatusCheck(s, "write"); +} + diff --git a/storage/ndb/test/newtonapi/basic_test/too_basic.cpp b/storage/ndb/test/newtonapi/basic_test/too_basic.cpp new file mode 100644 index 00000000000..f751967c181 --- /dev/null +++ b/storage/ndb/test/newtonapi/basic_test/too_basic.cpp @@ -0,0 +1,104 @@ +/* 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; version 2 of the License. + + 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 */ + + + +/****** THIS LINE IS 80 CHARACTERS WIDE - DO *NOT* EXCEED 80 CHARACTERS! ****/ + +#include <ndb_global.h> +#include <NdbOut.hpp> + +//#include <cfg/cfg_db.h> +//#include <init/init_start_restart.h> +//#include "pcn_types.h" +//#include <testing/testing.h> + +extern "C" { +#include <cfg_db.h> +} + +typedef struct Employee { + + UInt32_t EmpNo; + char FirstName[22]; + char LastName[22]; + +} Employee_t; +#define CHECK_DB_CALL( Call ) \ + CheckDbCall( Call, #Call, __FILE__, __LINE__ ) + + + +/* --- Exported functions --- */ + +/*---------------------------------------------------------------------------*/ +int main() { + + + char EMP_TABLE_NAME[] = "employees"; + + Employee_t t; + + CFG_DbColumnDesc_t EmpColDesc[] = { + { "first_name", CFG_DB_CHAR, PCN_SIZE_OF( Employee, FirstName ), + PCN_FALSE }, + { "emp_no", CFG_DB_INT, PCN_SIZE_OF( Employee, EmpNo ), PCN_TRUE }, + { "last_name", CFG_DB_CHAR, PCN_SIZE_OF( Employee, LastName ), + PCN_FALSE }, + }; + + int EmpNbCol = 3; + + + + CFG_DbColumnBinding_t ColBindings[] = { + CFG_DB_BINDING( "last_name", CFG_DB_CHAR, Employee, LastName ), + CFG_DB_BINDING( "emp_no", CFG_DB_INT, Employee, EmpNo ), + CFG_DB_BINDING( "first_name", CFG_DB_CHAR, Employee, FirstName) + }; + + + Employee_t EMP_TABLE_DATA[] = { + { 1242, "Joe", "Dalton" }, + { 123, "Lucky", "Luke" }, + { 456, "Averell", "Dalton" }, + { 8976, "Gaston", "Lagaffe" } + }; + + + char* DbName; + + DbName = NULL; + + + // On Linux: will destroy the table to start from a clean slate. + + CFG_DbDestroy(); + CFG_DbOpen( &DbName ) ; + CFG_DbCreateTable( EMP_TABLE_NAME, + EmpNbCol, EmpColDesc ); + + CFG_DbTableExists( EMP_TABLE_NAME ); + + //#ifndef CELLO_PLATFORM + //CHECK_DB_CALL( CFG_DbDumpSchema( stdout ) ); + //#endif + + CFG_DbClose(); + // INIT_StopSystem(); + +} + + diff --git a/storage/ndb/test/newtonapi/perf_test/Makefile b/storage/ndb/test/newtonapi/perf_test/Makefile new file mode 100644 index 00000000000..2be004d4277 --- /dev/null +++ b/storage/ndb/test/newtonapi/perf_test/Makefile @@ -0,0 +1,14 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := newton_perf +BIN_TARGET_LIBS := +BIN_TARGET_ARCHIVES := NEWTON_API +SOURCES := perf.cpp + +CCFLAGS_LOC := -I$(call fixpath,$(NDB_TOP)/include/util) -I$(call fixpath,$(NDB_TOP)/include/newtonapi) -I$(call fixpath,$(NDB_TOP)/include/portlib) + +include $(NDB_TOP)/Epilogue.mk + + diff --git a/storage/ndb/test/newtonapi/perf_test/perf.cpp b/storage/ndb/test/newtonapi/perf_test/perf.cpp new file mode 100644 index 00000000000..23484dbdac2 --- /dev/null +++ b/storage/ndb/test/newtonapi/perf_test/perf.cpp @@ -0,0 +1,646 @@ +/* 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; version 2 of the License. + + 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 */ + + +#include <ndb_global.h> + +extern "C" { +#include <dba.h> +} + +#include <NdbOut.hpp> +#include <NdbSleep.h> +#include <NdbTimer.hpp> +#include <NDBT_Stats.hpp> +#include <NDBT_ReturnCodes.h> +#include <NdbMain.h> +#include <time.h> + +#undef min +#undef max + +static const int NP_Insert = 0; +static const int NP_Update = 1; +static const int NP_WriteUpdate = 2; +static const int NP_WriteInsert = 3; +static const int NP_Delete = 4; +static const int NP_BulkRead = 5; +static const int NP_MAX = 5; + +static const char * Operations[] = { + "Insert ", + "Update ", + "WriteUpd", + "WriteIns", + "Delete ", + "BulkRead" +}; + +/** + * Configuration variables + */ +static int NoOfTransactions = 10000; +static int ParallellTransactions = 1000; +static int OperationsPerTransaction = 10; +static int NoOfColumns = 20; +static int BytesPerInsert = 300; +static int BytesPerUpdate = 200; +static int LoopCount = 10; + +/** + * Global variables + */ +static char TableName[255]; +static DBA_ColumnDesc_t * ColumnDescriptions; +static DBA_ColumnBinding_t * InsertBindings; +static DBA_ColumnBinding_t * UpdateBindings; static int UpdateBindingColumns; +static DBA_ColumnBinding_t * DeleteBindings; + +static char * TestData; +static DBA_Binding_t * InsertB; +static DBA_Binding_t * UpdateB; +static DBA_Binding_t * DeleteB; + +/** + * Function prototypes + */ +static void sequence(int loops); + +inline void * getPtr(int rowNo) { return TestData+rowNo*BytesPerInsert;} +inline void setPK(int rowNo, int pk){ * (int *)getPtr(rowNo) = pk; } + +static void SetupTestData(); +static void CleanupTestData(); + +static bool CreateTable(); +static bool CleanTable(); +static bool CreateBindings(); + +static void usage(); + +static +void +usage(){ + int ForceSend, Interval; + DBA_GetParameter(0, &Interval); + DBA_GetParameter(3, &ForceSend); + + ndbout << "newtonPerf" << endl + << " -n Transactions per loop and operation (" + << NoOfTransactions << ")" << endl + << " -p parallell transactions (" << ParallellTransactions << ")" + << endl + << " -o operations per transaction (" << OperationsPerTransaction + << ")" << endl + << " -a no of columns (" << NoOfColumns << ")" << endl + << " -b Table size in bytes (" << BytesPerInsert << ")" << endl + << " -u Bytes per update (" << BytesPerUpdate << ")" << endl + << " -l Loop count (" << LoopCount << ")" << endl + << " -i Interval (" << Interval << "ms)" << endl + << " -f Force send algorithm (" << ForceSend << ")" << endl + << " -h Help" << endl; + +} + +static +bool +parseArgs(int argc, const char **argv){ + bool a = false, b = false, u = false; + + for(int i = 1; i<argc; i++){ + if(argv[i][0] != '-'){ + ndbout << "Invalid argument: " << argv[i] << endl; + return false; + } + + if(argv[i][1] == 'h') + return false; + + if(i == argc-1){ + ndbout << "Expecting argument to " << argv[i] << endl; + return false; + } + + switch(argv[i][1]){ + case 'n': + NoOfTransactions = atoi(argv[i+1]); + break; + case 'p': + ParallellTransactions = atoi(argv[i+1]); + break; + case 'o': + OperationsPerTransaction = atoi(argv[i+1]); + break; + case 'a': + NoOfColumns = atoi(argv[i+1]); + a = true; + break; + case 'b': + BytesPerInsert = atoi(argv[i+1]); + b = true; + break; + case 'u': + BytesPerUpdate = atoi(argv[i+1]); + u = true; + break; + case 'l': + LoopCount = atoi(argv[i+1]); + break; + case 'f': + { + const int val = atoi(argv[i+1]); + if(DBA_SetParameter(3, val) != DBA_NO_ERROR){ + ndbout << "Invalid force send algorithm: " + << DBA_GetLatestErrorMsg() + << "(" << DBA_GetLatestError() << ")" << endl; + return false; + } + } + break; + case 'i': + { + const int val = atoi(argv[i+1]); + if(DBA_SetParameter(0, val) != DBA_NO_ERROR){ + ndbout << "Invalid NBP interval: " + << DBA_GetLatestErrorMsg() + << "(" << DBA_GetLatestError() << ")" << endl; + return false; + } + } + break; + default: + ndbout << "Invalid option: " << argv[i] << endl; + return false; + } + i++; + } + if(a && !b) BytesPerInsert = 15 * NoOfColumns; + if(!a && b) NoOfColumns = ((BytesPerInsert + 14) / 15)+1; + + if(!u) + BytesPerUpdate = (2 * BytesPerInsert) / 3; + + bool t = true; + if(NoOfColumns < 2) t = false; + if(BytesPerInsert < 8) t = false; + if(BytesPerUpdate < 8) t = false; + + if(!t){ + ndbout << "Invalid arguments combination of -a -b -u not working out" + << endl; + return false; + } + return true; +} + +NDB_COMMAND(newton_perf, "newton_perf", + "newton_perf", "newton_perf", 65535){ + + if(!parseArgs(argc, argv)){ + usage(); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + + ndbout << "-----------" << endl; + usage(); + ndbout << endl; + + SetupTestData(); + + DBA_Open(); + + if(!CreateTable()){ + DBA_Close(); + CleanupTestData(); + return 0; + } + + if(!CreateBindings()){ + DBA_Close(); + CleanupTestData(); + return 0; + } + + CleanTable(); + + sequence(LoopCount); + + DBA_Close(); + CleanupTestData(); + + DBA_DestroyBinding(InsertB); + DBA_DestroyBinding(UpdateB); + DBA_DestroyBinding(DeleteB); +} + +static +void +ErrorMsg(const char * s){ + ndbout << s + << ": " << DBA_GetLatestError() << "-" << DBA_GetLatestErrorMsg() + << ", " << DBA_GetLatestNdbError() + << endl; +} + +static +int +m4(int i){ + const int j = i - (i & 3); + return j; +} + +static +void +SetupTestData(){ + ndbout << "Creating testdata" << endl; + + ColumnDescriptions = new DBA_ColumnDesc_t[NoOfColumns]; + InsertBindings = new DBA_ColumnBinding_t[NoOfColumns]; + + const int sz = m4((BytesPerInsert - ((NoOfColumns+1)/2)*4)/(NoOfColumns/2)); + int sum = 0; + UpdateBindingColumns = 0; + for(int i = 0; i<NoOfColumns; i++){ + char tmp[16]; + if((i % 2) == 0){ + sprintf(tmp, "I%d", i); + ColumnDescriptions[i].DataType = DBA_INT; + ColumnDescriptions[i].Size = 4; + sum += 4; + } else { + sprintf(tmp, "S%d", i); + ColumnDescriptions[i].DataType = DBA_CHAR; + ColumnDescriptions[i].Size = sz; + sum += sz; + } + ColumnDescriptions[i].IsKey = 0; + ColumnDescriptions[i].Name = strdup(tmp); + + InsertBindings[i].Name = strdup(tmp); + InsertBindings[i].DataType = ColumnDescriptions[i].DataType; + InsertBindings[i].Size = ColumnDescriptions[i].Size; + InsertBindings[i].Offset = sum - ColumnDescriptions[i].Size; + InsertBindings[i].Ptr = 0; + + if(sum <= BytesPerUpdate) + UpdateBindingColumns++; + } + if(UpdateBindingColumns == 1) + UpdateBindingColumns++; + + ColumnDescriptions[0].IsKey = 1; + + assert(sum <= BytesPerInsert); + sprintf(TableName, "NEWTON_%d_%d", sum, NoOfColumns); + + UpdateBindings = new DBA_ColumnBinding_t[UpdateBindingColumns]; + memcpy(UpdateBindings, InsertBindings, + UpdateBindingColumns*sizeof(DBA_ColumnBinding_t)); + + DeleteBindings = new DBA_ColumnBinding_t[1]; + memcpy(DeleteBindings, InsertBindings, + 1*sizeof(DBA_ColumnBinding_t)); + + TestData = (char *)malloc(NoOfTransactions * + OperationsPerTransaction * BytesPerInsert); + + assert(TestData != 0); + for(int i = 0; i<NoOfTransactions; i++) + for(int j = 0; j<OperationsPerTransaction; j++){ + const int pk = i * OperationsPerTransaction + j; + setPK(pk, pk); + } +} + +static +void +CleanupTestData(){ + free(TestData); + for(int i = 0; i<NoOfColumns; i++){ + free((char*)ColumnDescriptions[i].Name); + free((char*)InsertBindings[i].Name); + } + delete [] ColumnDescriptions; + delete [] InsertBindings; + delete [] UpdateBindings; + delete [] DeleteBindings; +} + + +static bool CleanReturnValue = true; +static int CleanCallbacks = 0; +static int CleanRows = 0; + +extern "C" +void +CleanCallback(DBA_ReqId_t reqId, DBA_Error_t error, DBA_ErrorCode_t ec){ + CleanCallbacks++; + if(error == DBA_NO_ERROR) + CleanRows++; +} + +static +bool +CleanTable(){ + ndbout << "Cleaning table..." << flush; + CleanReturnValue = true; + CleanCallbacks = 0; + CleanRows = 0; + for(int i = 0; i<NoOfTransactions * OperationsPerTransaction; i++){ + DBA_ArrayDeleteRows(DeleteB, + getPtr(i), 1, + CleanCallback); + while((i-CleanCallbacks)>ParallellTransactions) + NdbSleep_MilliSleep(100); + } + while(CleanCallbacks != (NoOfTransactions * OperationsPerTransaction)) + NdbSleep_SecSleep(1); + + ndbout << CleanRows << " rows deleted" << endl; + + return CleanReturnValue; +} + +static +bool +CreateBindings(){ + ndbout << "Creating bindings" << endl; + InsertB = UpdateB = DeleteB = 0; + + InsertB = DBA_CreateBinding(TableName, NoOfColumns, + InsertBindings, BytesPerInsert); + if(InsertB == 0){ + ErrorMsg("Failed to create insert bindings"); + return false; + } + + UpdateB = DBA_CreateBinding(TableName, UpdateBindingColumns, + UpdateBindings, BytesPerInsert); + if(UpdateB == 0){ + ErrorMsg("Failed to create update bindings"); + DBA_DestroyBinding(InsertB); + return false; + } + + DeleteB = DBA_CreateBinding(TableName, 1, + DeleteBindings, BytesPerInsert); + if(DeleteB == 0){ + ErrorMsg("Failed to create delete bindings"); + DBA_DestroyBinding(InsertB); + DBA_DestroyBinding(UpdateB); + return false; + } + return true; +} + +static +bool +CreateTable(){ + ndbout << "Creating " << TableName << endl; + return DBA_CreateTable( TableName, + NoOfColumns, + ColumnDescriptions ) == DBA_NO_ERROR; +} + +/** + * + */ +static NdbTimer SequenceTimer; + +static int CurrentOp = NP_Insert; +static int SequenceSent = 0; +static int SequenceRecv = 0; +static NDBT_Stats SequenceStats[NP_MAX][4]; +static NDBT_Stats SequenceLatency[NP_MAX]; + +static int HashMax; +static DBA_ReqId_t * ReqHash; // ReqId - Latency/Row +static int * ReqHashPos; // (row in StartTime) + +static int SequenceLatencyPos; +static NDB_TICKS * StartTime; + +static +inline +int +computeHashMax(int elements){ + HashMax = 1; + while(HashMax < elements) + HashMax *= 2; + + if(HashMax < 1024) + HashMax = 1024; + + return HashMax; +} + +static +inline +int +hash(DBA_ReqId_t request){ + int r = (request >> 2) & (HashMax-1); + return r; +} + +static +inline +void +addRequest(DBA_ReqId_t request, int pos){ + + int i = hash(request); + + while(ReqHash[i] != 0) + i = ((i + 1) & (HashMax-1)); + + ReqHash[i] = request; + ReqHashPos[i] = pos; +} + +static +inline +int +getRequest(DBA_ReqId_t request){ + + int i = hash(request); + + while(ReqHash[i] != request) + i = ((i + 1) & (HashMax-1)); + + ReqHash[i] = 0; + + return ReqHashPos[i]; +} + +extern "C" +void +SequenceCallback(DBA_ReqId_t reqId, DBA_Error_t error, DBA_ErrorCode_t ec){ + int p = getRequest(reqId) - 1; + + if(error != DBA_NO_ERROR){ + ndbout << "p = " << p << endl; + ndbout << "DBA_GetErrorMsg(" << error << ") = " + << DBA_GetErrorMsg(error) << endl; + ndbout << "DBA_GetNdbErrorMsg(" << ec << ") = " + << DBA_GetNdbErrorMsg(ec) << endl; + + assert(error == DBA_NO_ERROR); + } + + SequenceRecv++; + if(SequenceRecv == NoOfTransactions){ + SequenceTimer.doStop(); + } + + if((p & 127) == 127){ + NDB_TICKS t = NdbTick_CurrentMillisecond() - StartTime[p]; + SequenceLatency[CurrentOp].addObservation(t); + } +} + +typedef DBA_ReqId_t (* DBA_ArrayFunction)( const DBA_Binding_t* pBindings, + const void * pData, + int NbRows, + DBA_AsyncCallbackFn_t CbFunc ); + +inline +int +min(int a, int b){ + return a > b ? b : a; +} + +static +void +SequenceOp(DBA_ArrayFunction func, const DBA_Binding_t* pBindings, int op){ + SequenceSent = 0; + SequenceRecv = 0; + SequenceLatencyPos = 1; + CurrentOp = op; + + SequenceTimer.doStart(); + for(int i = 0; i<NoOfTransactions; ){ + const int l1 = ParallellTransactions - (SequenceSent - SequenceRecv); + const int l2 = min(NoOfTransactions - i, l1); + for(int j = 0; j<l2; j++){ + const DBA_ReqId_t r = func(pBindings, + getPtr(i*OperationsPerTransaction), + OperationsPerTransaction, + SequenceCallback); + assert(r != 0); + SequenceSent++; + addRequest(r, i + 1); + i++; + + if((SequenceSent & 127) == 127){ + NDB_TICKS t = NdbTick_CurrentMillisecond(); + StartTime[i] = t; + } + } + if(l2 == 0) + NdbSleep_MilliSleep(10); + } + + while(SequenceRecv != SequenceSent) + NdbSleep_SecSleep(1); + + ndbout << "Performed " << NoOfTransactions << " " << Operations[op] + << " in "; + + double p = NoOfTransactions * 1000; + double t = SequenceTimer.elapsedTime(); + double o = p * OperationsPerTransaction; + + p /= t; + o /= t; + + int _p = p; + int _o = o; + + double b = 0; + + switch(op){ + case NP_Insert: + case NP_WriteInsert: + case NP_WriteUpdate: + case NP_BulkRead: + b = BytesPerInsert; + break; + case NP_Update: + b = BytesPerUpdate; + break; + case NP_Delete: + b = 4; + break; + default: + b = 0; + } + b *= NoOfTransactions * OperationsPerTransaction; + b /= t; + int _b = b; + + SequenceStats[op][0].addObservation(t); + SequenceStats[op][1].addObservation(p); + SequenceStats[op][2].addObservation(o); + SequenceStats[op][3].addObservation(b); + + int t2 = SequenceStats[op][0].getMean(); + int p2 = SequenceStats[op][1].getMean(); + int o2 = SequenceStats[op][2].getMean(); + int b2 = SequenceStats[op][3].getMean(); + + ndbout << SequenceTimer.elapsedTime() << "(" << t2 << ")ms"; + ndbout << " -> " << _p << "(" << p2 << ") T/s - " << _o + << "(" << o2 << ") O/s - " << _b << "(" << b2 << ") Kb/s" << endl; + + ndbout << " Latency (ms) Avg: " << (int)SequenceLatency[op].getMean() + << " min: " << (int)SequenceLatency[op].getMin() + << " max: " << (int)SequenceLatency[op].getMax() + << " stddev: " << (int)SequenceLatency[op].getStddev() + << " n: " << SequenceLatency[op].getCount() << endl; +} + +/** + * Sequence + */ +static +void +sequence(int loops){ + computeHashMax(ParallellTransactions); + ReqHash = new DBA_ReqId_t[HashMax]; + ReqHashPos = new int[HashMax]; + StartTime = new NDB_TICKS[NoOfTransactions]; + + for(int i = 0; i<NP_MAX; i++){ + SequenceLatency[i].reset(); + for(int j = 0; j<4; j++) + SequenceStats[i][j].reset(); + } + for(int i = 0; i<loops; i++){ + ndbout << "Loop #" << (i+1) << endl; + SequenceOp(DBA_ArrayInsertRows, InsertB, NP_Insert); + + // BulkRead + + SequenceOp(DBA_ArrayUpdateRows, UpdateB, NP_Update); + SequenceOp(DBA_ArrayWriteRows, InsertB, NP_WriteUpdate); + SequenceOp(DBA_ArrayDeleteRows, DeleteB, NP_Delete); + SequenceOp(DBA_ArrayWriteRows, InsertB, NP_WriteInsert); + SequenceOp(DBA_ArrayDeleteRows, DeleteB, NP_Delete); + ndbout << "-------------------" << endl << endl; + } + + delete [] ReqHash; + delete [] ReqHashPos; + delete [] StartTime; +} |