From abee640f44e4475a6b5448f30dcec9bca5455bda Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 26 May 2004 15:36:55 +0000 Subject: neww ndb automake ndb/test/tools/hugoCalculator.cpp: Rename: ndb/test/tools/hugoCalculator/hugoCalculator.cpp -> ndb/test/tools/hugoCalculator.cpp ndb/test/tools/hugoLoad.cpp: Rename: ndb/test/tools/hugoLoad/hugoLoad.cpp -> ndb/test/tools/hugoLoad.cpp ndb/test/tools/hugoFill.cpp: Rename: ndb/test/tools/hugoFill/hugoFill.cpp -> ndb/test/tools/hugoFill.cpp ndb/test/tools/hugoLockRecords.cpp: Rename: ndb/test/tools/hugoLockRecords/hugoLockRecords.cpp -> ndb/test/tools/hugoLockRecords.cpp ndb/test/tools/hugoPkRead.cpp: Rename: ndb/test/tools/hugoPkRead/hugoPkRead.cpp -> ndb/test/tools/hugoPkRead.cpp ndb/test/tools/hugoPkReadRecord.cpp: Rename: ndb/test/tools/hugoPkReadRecord/hugoPkReadRecord.cpp -> ndb/test/tools/hugoPkReadRecord.cpp ndb/test/tools/hugoScanRead.cpp: Rename: ndb/test/tools/hugoScanRead/hugoScanRead.cpp -> ndb/test/tools/hugoScanRead.cpp ndb/test/tools/restart.cpp: Rename: ndb/test/tools/restart/restart.cpp -> ndb/test/tools/restart.cpp ndb/test/ndbapi/TraceNdbApi.cpp: Rename: ndb/test/ndbapi/acid2/TraceNdbApi.cpp -> ndb/test/ndbapi/TraceNdbApi.cpp ndb/test/ndbapi/VerifyNdbApi.cpp: Rename: ndb/test/ndbapi/acid2/VerifyNdbApi.cpp -> ndb/test/ndbapi/VerifyNdbApi.cpp ndb/test/ndbapi/acid.cpp: Rename: ndb/test/ndbapi/acid/acid.cpp -> ndb/test/ndbapi/acid.cpp ndb/test/ndbapi/acid2.cpp: Rename: ndb/test/ndbapi/acid2/acid2.cpp -> ndb/test/ndbapi/acid2.cpp ndb/test/ndbapi/bulk_copy.cpp: Rename: ndb/test/ndbapi/bulk_copy/bulk_copy.cpp -> ndb/test/ndbapi/bulk_copy.cpp ndb/test/ndbapi/celloDb.cpp: Rename: ndb/test/ndbapi/cello-sessionDb/celloDb.cpp -> ndb/test/ndbapi/celloDb.cpp ndb/test/ndbapi/create_all_tabs.cpp: Rename: ndb/test/ndbapi/create_all_tabs/create_all_tabs.cpp -> ndb/test/ndbapi/create_all_tabs.cpp ndb/test/ndbapi/create_tab.cpp: Rename: ndb/test/ndbapi/create_tab/create_tab.cpp -> ndb/test/ndbapi/create_tab.cpp ndb/test/ndbapi/drop_all_tabs.cpp: Rename: ndb/test/ndbapi/drop_all_tabs/drop_all_tabs.cpp -> ndb/test/ndbapi/drop_all_tabs.cpp ndb/test/ndbapi/flexAsynch.cpp: Rename: ndb/test/ndbapi/flexAsynch/flexAsynch.cpp -> ndb/test/ndbapi/flexAsynch.cpp ndb/test/ndbapi/flexBench.cpp: Rename: ndb/test/ndbapi/flexBench/flexBench.cpp -> ndb/test/ndbapi/flexBench.cpp ndb/test/ndbapi/flexHammer.cpp: Rename: ndb/test/ndbapi/flexHammer/flexHammer.cpp -> ndb/test/ndbapi/flexHammer.cpp ndb/test/ndbapi/flexScan.cpp: Rename: ndb/test/ndbapi/flexScan/flexScan.cpp -> ndb/test/ndbapi/flexScan.cpp ndb/test/ndbapi/flexTT.cpp: Rename: ndb/test/ndbapi/flexTT/flexTT.cpp -> ndb/test/ndbapi/flexTT.cpp ndb/test/ndbapi/flexTimedAsynch.cpp: Rename: ndb/test/ndbapi/flexTimedAsynch/flexTimedAsynch.cpp -> ndb/test/ndbapi/flexTimedAsynch.cpp ndb/test/ndbapi/flex_bench_mysql.cpp: Rename: ndb/test/ndbapi/flex_bench_mysql/flex_bench_mysql.cpp -> ndb/test/ndbapi/flex_bench_mysql.cpp ndb/test/ndbapi/index.cpp: Rename: ndb/test/ndbapi/indexTest/index.cpp -> ndb/test/ndbapi/index.cpp ndb/test/ndbapi/asyncGenerator.cpp: Rename: ndb/test/ndbapi/lmc-bench/async-src/generator/asyncGenerator.cpp -> ndb/test/ndbapi/asyncGenerator.cpp ndb/test/ndbapi/index2.cpp: Rename: ndb/test/ndbapi/indexTest2/index2.cpp -> ndb/test/ndbapi/index2.cpp ndb/test/ndbapi/interpreterInTup.cpp: Rename: ndb/test/ndbapi/interpreterInTup/interpreterInTup.cpp -> ndb/test/ndbapi/interpreterInTup.cpp ndb/test/ndbapi/mainAsyncGenerator.cpp: Rename: ndb/test/ndbapi/lmc-bench/async-src/generator/mainAsyncGenerator.cpp -> ndb/test/ndbapi/mainAsyncGenerator.cpp ndb/test/ndbapi/ndb_async1.cpp: Rename: ndb/test/ndbapi/lmc-bench/async-src/user/ndb_async1.cpp -> ndb/test/ndbapi/ndb_async1.cpp ndb/test/ndbapi/ndb_async2.cpp: Rename: ndb/test/ndbapi/lmc-bench/async-src/user/ndb_async2.cpp -> ndb/test/ndbapi/ndb_async2.cpp ndb/test/ndbapi/ndb_user_populate.cpp: Rename: ndb/test/ndbapi/lmc-bench/src/user/ndb_user_populate.cpp -> ndb/test/ndbapi/ndb_user_populate.cpp ndb/test/ndbapi/ndb_user_transaction.cpp: Rename: ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction.cpp -> ndb/test/ndbapi/ndb_user_transaction.cpp ndb/test/ndbapi/ndb_user_transaction2.cpp: Rename: ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction2.cpp -> ndb/test/ndbapi/ndb_user_transaction2.cpp ndb/test/ndbapi/ndb_user_transaction3.cpp: Rename: ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction3.cpp -> ndb/test/ndbapi/ndb_user_transaction3.cpp ndb/test/ndbapi/userInterface.cpp: Rename: ndb/test/ndbapi/lmc-bench/async-src/user/userInterface.cpp -> ndb/test/ndbapi/userInterface.cpp ndb/test/ndbapi/benchronja.cpp: Rename: ndb/test/ndbapi/ronja/benchronja/benchronja.cpp -> ndb/test/ndbapi/benchronja.cpp ndb/test/ndbapi/ndb_user_transaction4.cpp: Rename: ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction4.cpp -> ndb/test/ndbapi/ndb_user_transaction4.cpp ndb/test/ndbapi/ndb_user_transaction5.cpp: Rename: ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction5.cpp -> ndb/test/ndbapi/ndb_user_transaction5.cpp ndb/test/ndbapi/ndb_user_transaction6.cpp: Rename: ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction6.cpp -> ndb/test/ndbapi/ndb_user_transaction6.cpp ndb/test/ndbapi/restarter.cpp: Rename: ndb/test/ndbapi/restarter/restarter.cpp -> ndb/test/ndbapi/restarter.cpp ndb/test/ndbapi/restarter2.cpp: Rename: ndb/test/ndbapi/restarter2/restarter2.cpp -> ndb/test/ndbapi/restarter2.cpp ndb/test/ndbapi/restarts.cpp: Rename: ndb/test/ndbapi/restarts/restarts.cpp -> ndb/test/ndbapi/restarts.cpp ndb/test/ndbapi/InsertRecs.cpp: Rename: ndb/test/ndbapi/telco/InsertRecs.cpp -> ndb/test/ndbapi/InsertRecs.cpp ndb/test/ndbapi/adoInsertRecs.cpp: Rename: ndb/test/ndbapi/telco/adoInsertRecs.cpp -> ndb/test/ndbapi/adoInsertRecs.cpp ndb/test/ndbapi/initronja.cpp: Rename: ndb/test/ndbapi/ronja/initronja/initronja.cpp -> ndb/test/ndbapi/initronja.cpp ndb/test/ndbapi/msa.cpp: Rename: ndb/test/ndbapi/telco/msa.cpp -> ndb/test/ndbapi/msa.cpp ndb/test/ndbapi/testBasic.cpp: Rename: ndb/test/ndbapi/testBasic/testBasic.cpp -> ndb/test/ndbapi/testBasic.cpp ndb/test/ndbapi/testDataBuffers.cpp: Rename: ndb/test/ndbapi/testDataBuffers/testDataBuffers.cpp -> ndb/test/ndbapi/testDataBuffers.cpp ndb/test/ndbapi/testDict.cpp: Rename: ndb/test/ndbapi/testDict/testDict.cpp -> ndb/test/ndbapi/testDict.cpp ndb/test/ndbapi/testGrep.cpp: Rename: ndb/test/ndbapi/testGrep/testGrep.cpp -> ndb/test/ndbapi/testGrep.cpp ndb/test/ndbapi/testGrepVerify.cpp: Rename: ndb/test/ndbapi/testGrep/verify/testGrepVerify.cpp -> ndb/test/ndbapi/testGrepVerify.cpp ndb/test/ndbapi/testIndex.cpp: Rename: ndb/test/ndbapi/testIndex/testIndex.cpp -> ndb/test/ndbapi/testIndex.cpp ndb/test/ndbapi/testInterpreter.cpp: Rename: ndb/test/ndbapi/testInterpreter/testInterpreter.cpp -> ndb/test/ndbapi/testInterpreter.cpp ndb/test/ndbapi/testMgm.cpp: Rename: ndb/test/ndbapi/testMgm/testMgm.cpp -> ndb/test/ndbapi/testMgm.cpp ndb/test/ndbapi/testNdbApi.cpp: Rename: ndb/test/ndbapi/testNdbApi/testNdbApi.cpp -> ndb/test/ndbapi/testNdbApi.cpp ndb/test/ndbapi/testNodeRestart.cpp: Rename: ndb/test/ndbapi/testNodeRestart/testNodeRestart.cpp -> ndb/test/ndbapi/testNodeRestart.cpp ndb/test/ndbapi/testOIBasic.cpp: Rename: ndb/test/ndbapi/testOIBasic/testOIBasic.cpp -> ndb/test/ndbapi/testOIBasic.cpp ndb/test/ndbapi/testOperations.cpp: Rename: ndb/test/ndbapi/testOperations/testOperations.cpp -> ndb/test/ndbapi/testOperations.cpp ndb/test/ndbapi/testOrderedIndex.cpp: Rename: ndb/test/ndbapi/testOrderedIndex/testOrderedIndex.cpp -> ndb/test/ndbapi/testOrderedIndex.cpp ndb/test/ndbapi/testRestartGci.cpp: Rename: ndb/test/ndbapi/testRestartGci/testRestartGci.cpp -> ndb/test/ndbapi/testRestartGci.cpp ndb/test/ndbapi/testScan.cpp: Rename: ndb/test/ndbapi/testScan/testScan.cpp -> ndb/test/ndbapi/testScan.cpp ndb/test/ndbapi/testScanInterpreter.cpp: Rename: ndb/test/ndbapi/testScanInterpreter/testScanInterpreter.cpp -> ndb/test/ndbapi/testScanInterpreter.cpp ndb/test/ndbapi/testSystemRestart.cpp: Rename: ndb/test/ndbapi/testSystemRestart/testSystemRestart.cpp -> ndb/test/ndbapi/testSystemRestart.cpp ndb/test/ndbapi/testTimeout.cpp: Rename: ndb/test/ndbapi/testTimeout/testTimeout.cpp -> ndb/test/ndbapi/testTimeout.cpp ndb/test/ndbapi/cdrserver.cpp: Rename: ndb/test/ndbapi/vw_test/cdrserver.cpp -> ndb/test/ndbapi/cdrserver.cpp ndb/test/ndbapi/size.cpp: Rename: ndb/test/ndbapi/vw_test/size.cpp -> ndb/test/ndbapi/size.cpp ndb/test/ndbapi/testTransactions.cpp: Rename: ndb/test/ndbapi/testTransactions/testTransactions.cpp -> ndb/test/ndbapi/testTransactions.cpp ndb/test/ndbapi/test_event.cpp: Rename: ndb/test/ndbapi/test_event/test_event.cpp -> ndb/test/ndbapi/test_event.cpp ndb/tools/delete_all.cpp: Rename: ndb/tools/delete_all/delete_all.cpp -> ndb/tools/delete_all.cpp ndb/tools/desc.cpp: Rename: ndb/tools/desc/desc.cpp -> ndb/tools/desc.cpp ndb/tools/drop_index.cpp: Rename: ndb/tools/drop_index/drop_index.cpp -> ndb/tools/drop_index.cpp ndb/tools/drop_tab.cpp: Rename: ndb/tools/drop_tab/drop_tab.cpp -> ndb/tools/drop_tab.cpp ndb/tools/listTables.cpp: Rename: ndb/tools/list_tables/listTables.cpp -> ndb/tools/listTables.cpp ndb/tools/ndbsql.cpp: Rename: ndb/tools/ndbsql/ndbsql.cpp -> ndb/tools/ndbsql.cpp ndb/tools/select_all.cpp: Rename: ndb/tools/select_all/select_all.cpp -> ndb/tools/select_all.cpp ndb/tools/select_count.cpp: Rename: ndb/tools/select_count/select_count.cpp -> ndb/tools/select_count.cpp ndb/test/tools/hugoScanUpdate.cpp: Rename: ndb/test/tools/hugoScanUpd.cpp -> ndb/test/tools/hugoScanUpdate.cpp ndb/test/tools/hugoPkUpdate.cpp: Rename: ndb/test/tools/hugoPkUpd.cpp -> ndb/test/tools/hugoPkUpdate.cpp ndb/test/tools/hugoPkDelete.cpp: Rename: ndb/test/tools/hugoPkDel.cpp -> ndb/test/tools/hugoPkDelete.cpp ndb/tools/Makefile_old: Rename: ndb/tools/Makefile -> ndb/tools/Makefile_old ndb/test/tools/transproxy.cpp: Rename: ndb/tools/transproxy.cpp -> ndb/test/tools/transproxy.cpp ndb/test/tools/verify_index.cpp: Rename: ndb/tools/verify_index.cpp -> ndb/test/tools/verify_index.cpp ndb/test/tools/copy_tab.cpp: Rename: ndb/tools/copy_tab.cpp -> ndb/test/tools/copy_tab.cpp ndb/test/tools/cpcc.cpp: Rename: ndb/tools/cpcc.cpp -> ndb/test/tools/cpcc.cpp ndb/test/tools/create_index.cpp: Rename: ndb/tools/create_index.cpp -> ndb/test/tools/create_index.cpp ndb/test/tools/old_dirs/waiter/Makefile_old: mvdir ndb/test/tools/old_dirs/waiter/waiter.cpp: mvdir ndb/test/tools/old_dirs/restart/Makefile: mvdir ndb/test/tools/old_dirs/hugoScanUpdate/Makefile: mvdir ndb/test/tools/old_dirs/hugoScanRead/Makefile: mvdir ndb/test/tools/old_dirs/hugoPkUpdate/Makefile: mvdir ndb/test/tools/old_dirs/hugoPkReadRecord/Makefile: mvdir ndb/test/tools/old_dirs/hugoPkRead/Makefile: mvdir ndb/test/tools/old_dirs/hugoPkDelete/Makefile: mvdir ndb/test/tools/old_dirs/hugoLockRecords/Makefile: mvdir ndb/test/tools/old_dirs/hugoLoad/Makefile: mvdir ndb/test/tools/old_dirs/hugoFill/Makefile: mvdir ndb/test/tools/old_dirs/hugoCalculator/Makefile: mvdir ndb/tools/old_dirs/copy_tab/Makefile: mvdir ndb/tools/old_dirs/cpcc/Makefile: mvdir ndb/tools/old_dirs/create_index/Makefile: mvdir ndb/tools/old_dirs/delete_all/Makefile: mvdir ndb/tools/old_dirs/desc/Makefile: mvdir ndb/tools/old_dirs/drop_index/Makefile: mvdir ndb/tools/old_dirs/drop_tab/Makefile: mvdir ndb/tools/old_dirs/list_tables/Makefile: mvdir ndb/tools/old_dirs/select_all/Makefile: mvdir ndb/tools/old_dirs/select_count/Makefile: mvdir ndb/test/tools/old_dirs/transproxy/Makefile: mvdir ndb/test/tools/old_dirs/verify_index/Makefile: mvdir ndb/test/ndbapi/old_dirs/flexTT/Makefile: mvdir ndb/test/ndbapi/old_dirs/flexTimedAsynch/Makefile: mvdir ndb/test/ndbapi/old_dirs/flexHammer/Makefile: mvdir ndb/test/ndbapi/old_dirs/flexHammer/README: mvdir ndb/test/ndbapi/old_dirs/flexBench/Makefile.am: mvdir ndb/test/ndbapi/old_dirs/flexBench/Makefile_old: mvdir ndb/test/ndbapi/old_dirs/flexBench/ndbplot.pl: mvdir ndb/test/ndbapi/old_dirs/flexAsynch/Makefile: mvdir ndb/test/ndbapi/old_dirs/drop_all_tabs/Makefile: mvdir ndb/test/ndbapi/old_dirs/create_tab/Makefile: mvdir ndb/test/ndbapi/old_dirs/testOIBasic/Makefile: mvdir ndb/test/ndbapi/old_dirs/testOIBasic/times.txt: mvdir ndb/test/ndbapi/old_dirs/testNodeRestart/Makefile: mvdir ndb/test/ndbapi/old_dirs/testOperations/Makefile: mvdir ndb/test/ndbapi/old_dirs/testBlobs/Makefile: mvdir ndb/test/ndbapi/old_dirs/testBackup/Makefile: mvdir ndb/test/ndbapi/old_dirs/testDict/Makefile: mvdir ndb/test/ndbapi/old_dirs/test_event/Makefile: mvdir ndb/test/ndbapi/old_dirs/testTransactions/Makefile: mvdir ndb/test/ndbapi/old_dirs/testTimeout/Makefile: mvdir ndb/test/ndbapi/old_dirs/testSystemRestart/Makefile: mvdir ndb/test/ndbapi/old_dirs/testScanInterpreter/Makefile: mvdir ndb/test/ndbapi/old_dirs/testDataBuffers/Makefile: mvdir ndb/test/ndbapi/old_dirs/testIndex/Makefile: mvdir ndb/test/ndbapi/old_dirs/testMgm/Makefile: mvdir ndb/test/ndbapi/old_dirs/restarter/Makefile: mvdir ndb/test/ndbapi/old_dirs/flexScan/Makefile: mvdir ndb/test/ndbapi/old_dirs/flexScan/README: mvdir ndb/test/ndbapi/old_dirs/testRestartGci/Makefile: mvdir ndb/test/ndbapi/old_dirs/flex_bench_mysql/Makefile: mvdir ndb/test/ndbapi/old_dirs/indexTest/Makefile: mvdir ndb/test/ndbapi/old_dirs/indexTest2/Makefile: mvdir ndb/test/ndbapi/old_dirs/testBasic/Makefile: mvdir ndb/test/ndbapi/old_dirs/basicAsynch/Makefile: mvdir ndb/test/ndbapi/old_dirs/create_all_tabs/Makefile: mvdir ndb/test/ndbapi/old_dirs/testNdbApi/Makefile: mvdir ndb/test/ndbapi/old_dirs/testOrderedIndex/Makefile: mvdir ndb/test/ndbapi/old_dirs/restarter2/Makefile: mvdir ndb/test/ndbapi/old_dirs/telco/Makefile: mvdir ndb/test/ndbapi/old_dirs/telco/readme: mvdir ndb/test/ndbapi/old_dirs/acid/Makefile: mvdir ndb/test/ndbapi/old_dirs/acid2/Makefile: mvdir ndb/test/ndbapi/old_dirs/acid2/TraceNdbApi.hpp: mvdir ndb/test/ndbapi/old_dirs/acid2/VerifyNdbApi.hpp: mvdir ndb/test/ndbapi/old_dirs/interpreterInTup/Makefile: mvdir ndb/test/ndbapi/old_dirs/ronja/Makefile: mvdir ndb/test/ndbapi/old_dirs/ronja/benchronja/Makefile: mvdir ndb/test/ndbapi/old_dirs/ronja/initronja/Makefile: mvdir ndb/test/ndbapi/old_dirs/testScan/Makefile: mvdir ndb/test/ndbapi/old_dirs/vw_test/Makefile: mvdir ndb/test/ndbapi/old_dirs/vw_test/bcd.h: mvdir ndb/test/ndbapi/old_dirs/vw_test/utv.h: mvdir ndb/test/ndbapi/old_dirs/vw_test/vcdrfunc.h: mvdir ndb/test/ndbapi/old_dirs/vw_test/script/client_start: mvdir ndb/test/ndbapi/old_dirs/testGrep/Makefile: mvdir ndb/test/ndbapi/old_dirs/testGrep/verify/Makefile: mvdir ndb/test/ndbapi/old_dirs/testInterpreter/Makefile: mvdir ndb/test/ndbapi/old_dirs/restarts/Makefile: mvdir ndb/test/ndbapi/old_dirs/bulk_copy/Makefile: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/Makefile: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/async-src/Makefile: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/async-src/generator/Makefile: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/async-src/include/dbGenerator.h: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/async-src/include/testData.h: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/async-src/include/userInterface.h: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/async-src/user/Makefile: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/async-src/user/macros.h: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/async-src/user/ndb_error.hpp: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/bin/.empty: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/include/ndb_schema.hpp: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/include/testDefinitions.h: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/lib/.empty: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/script/Makefile: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/script/async-lmc-bench-l-p10.sh: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/script/async-lmc-bench-l.sh: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/script/async-lmc-bench-p10.sh: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/script/async-lmc-bench.sh: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/src/Makefile: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/src/README: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/Makefile: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/dbGenerator.c: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/src/makevars.linux: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/src/makevars.sparc: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/dbGenerator.h: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/mainGenerator.c: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/src/include/testData.h: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/src/include/userInterface.h: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/src/populator/Makefile: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/src/populator/dbPopulate.c: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/src/populator/dbPopulate.h: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/src/populator/mainPopulate.c: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/src/user/Makefile: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/src/user/localDbPrepare.c: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/src/user/macros.h: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/src/user/ndb_error.hpp: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/src/user/old/Makefile: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/src/user/old/userHandle.h: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/src/user/old/userInterface.c: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/src/user/old/userTransaction.c: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/src/user/userHandle.h: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/src/user/userInterface.cpp: mvdir ndb/test/ndbapi/old_dirs/lmc-bench/src/user/userTransaction.c: mvdir ndb/test/ndbapi/testBasicAsynch.cpp: Change mode to -rw-rw-r-- ndb/tools/old_dirs/ndbnet/Makefile.PL: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Net.pm: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Net/Base.pm: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Net/Client.pm: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Net/Command.pm: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Net/Config.pm: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Run.pm: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Util.pm: mvdir ndb/tools/old_dirs/ndbnet/ndbnet.pl: mvdir ndb/tools/old_dirs/ndbnet/ndbnetd.pl: mvdir ndb/tools/old_dirs/ndbnet/ndbrun: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Net/Database.pm: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Net/Env.pm: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Net/Node.pm: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Net/NodeApi.pm: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Net/NodeDb.pm: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Net/NodeMgmt.pm: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Net/Server.pm: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Net/ServerINET.pm: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Net/ServerUNIX.pm: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Run/Base.pm: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Run/Database.pm: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Run/Env.pm: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Run/Node.pm: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Util/Base.pm: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Util/Dir.pm: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Util/Event.pm: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Util/File.pm: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Util/IO.pm: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Util/Lock.pm: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Util/Log.pm: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Util/Socket.pm: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Util/SocketINET.pm: mvdir ndb/tools/old_dirs/ndbnet/lib/NDB/Util/SocketUNIX.pm: mvdir ndb/tools/old_dirs/ndbsql/Makefile: mvdir ndb/tools/old_dirs/src/counterviewer/CounterViewer.java: mvdir ndb/test/ndbapi/bank/Bank.hpp: mvdir ndb/test/ndbapi/bank/Makefile_old: Rename: ndb/test/ndbapi/bank/Makefile -> ndb/test/ndbapi/bank/Makefile_old ndb/test/ndbapi/bank/old_dirs/bankCreator/Makefile: mvdir ndb/test/ndbapi/bank/old_dirs/bankSumAccounts/Makefile: mvdir ndb/test/ndbapi/bank/old_dirs/bankMakeGL/Makefile: mvdir ndb/test/ndbapi/bank/old_dirs/bankTimer/Makefile: mvdir ndb/test/ndbapi/bank/old_dirs/bankValidateAllGLs/Makefile: mvdir ndb/test/ndbapi/bank/old_dirs/bankTransactionMaker/Makefile: mvdir ndb/test/ndbapi/bank/old_dirs/src/Makefile: mvdir ndb/test/ndbapi/bank/old_dirs/testBank/Makefile: mvdir ndb/test/ndbapi/ScanFilter.hpp: Rename: ndb/test/ndbapi/old_dirs/testScanInterpreter/ScanFilter.hpp -> ndb/test/ndbapi/ScanFilter.hpp ndb/test/ndbapi/ScanInterpretTest.hpp: Rename: ndb/test/ndbapi/old_dirs/testScanInterpreter/ScanInterpretTest.hpp -> ndb/test/ndbapi/ScanInterpretTest.hpp ndb/test/ndbapi/ScanFunctions.hpp: Rename: ndb/test/ndbapi/old_dirs/testScan/ScanFunctions.hpp -> ndb/test/ndbapi/ScanFunctions.hpp --- ndb/test/Makefile.am | 3 +- ndb/test/ndbapi/InsertRecs.cpp | 571 ++++ ndb/test/ndbapi/Makefile.am | 79 +- ndb/test/ndbapi/ScanFilter.hpp | 131 + ndb/test/ndbapi/ScanFunctions.hpp | 392 +++ ndb/test/ndbapi/ScanInterpretTest.hpp | 528 ++++ ndb/test/ndbapi/TraceNdbApi.cpp | 543 ++++ ndb/test/ndbapi/VerifyNdbApi.cpp | 151 ++ ndb/test/ndbapi/acid.cpp | 561 ++++ ndb/test/ndbapi/acid/Makefile | 10 - ndb/test/ndbapi/acid/acid.cpp | 561 ---- ndb/test/ndbapi/acid2.cpp | 692 +++++ ndb/test/ndbapi/acid2/Makefile | 10 - ndb/test/ndbapi/acid2/TraceNdbApi.cpp | 543 ---- ndb/test/ndbapi/acid2/TraceNdbApi.hpp | 132 - ndb/test/ndbapi/acid2/VerifyNdbApi.cpp | 151 -- ndb/test/ndbapi/acid2/VerifyNdbApi.hpp | 466 ---- ndb/test/ndbapi/acid2/acid2.cpp | 692 ----- ndb/test/ndbapi/adoInsertRecs.cpp | 363 +++ ndb/test/ndbapi/asyncGenerator.cpp | 571 ++++ ndb/test/ndbapi/bank/Bank.cpp | 2458 +++++++++++++++++ ndb/test/ndbapi/bank/BankLoad.cpp | 582 ++++ ndb/test/ndbapi/bank/Makefile | 12 - ndb/test/ndbapi/bank/Makefile.am | 22 + ndb/test/ndbapi/bank/Makefile_old | 12 + ndb/test/ndbapi/bank/bankCreator.cpp | 54 + ndb/test/ndbapi/bank/bankCreator/Makefile | 8 - ndb/test/ndbapi/bank/bankCreator/bankCreator.cpp | 54 - ndb/test/ndbapi/bank/bankMakeGL.cpp | 55 + ndb/test/ndbapi/bank/bankMakeGL/Makefile | 8 - ndb/test/ndbapi/bank/bankMakeGL/bankMakeGL.cpp | 55 - ndb/test/ndbapi/bank/bankSumAccounts.cpp | 55 + ndb/test/ndbapi/bank/bankSumAccounts/Makefile | 8 - .../bank/bankSumAccounts/bankSumAccounts.cpp | 55 - ndb/test/ndbapi/bank/bankTimer.cpp | 58 + ndb/test/ndbapi/bank/bankTimer/Makefile | 8 - ndb/test/ndbapi/bank/bankTimer/bankTimer.cpp | 58 - ndb/test/ndbapi/bank/bankTransactionMaker.cpp | 58 + ndb/test/ndbapi/bank/bankTransactionMaker/Makefile | 8 - .../bankTransactionMaker/bankTransactionMaker.cpp | 58 - ndb/test/ndbapi/bank/bankValidateAllGLs.cpp | 56 + ndb/test/ndbapi/bank/bankValidateAllGLs/Makefile | 8 - .../bank/bankValidateAllGLs/bankValidateAllGLs.cpp | 56 - ndb/test/ndbapi/bank/old_dirs/bankCreator/Makefile | 8 + ndb/test/ndbapi/bank/old_dirs/bankMakeGL/Makefile | 8 + .../ndbapi/bank/old_dirs/bankSumAccounts/Makefile | 8 + ndb/test/ndbapi/bank/old_dirs/bankTimer/Makefile | 8 + .../bank/old_dirs/bankTransactionMaker/Makefile | 8 + .../bank/old_dirs/bankValidateAllGLs/Makefile | 8 + ndb/test/ndbapi/bank/old_dirs/src/Makefile | 7 + ndb/test/ndbapi/bank/old_dirs/testBank/Makefile | 9 + ndb/test/ndbapi/bank/src/Bank.cpp | 2458 ----------------- ndb/test/ndbapi/bank/src/BankLoad.cpp | 582 ---- ndb/test/ndbapi/bank/src/Makefile | 7 - ndb/test/ndbapi/bank/testBank.cpp | 150 ++ ndb/test/ndbapi/bank/testBank/Makefile | 9 - ndb/test/ndbapi/bank/testBank/testBank.cpp | 150 -- ndb/test/ndbapi/basicAsynch/Makefile | 9 - ndb/test/ndbapi/basicAsynch/testBasicAsynch.cpp | 186 -- ndb/test/ndbapi/benchronja.cpp | 1202 +++++++++ ndb/test/ndbapi/bulk_copy.cpp | 275 ++ ndb/test/ndbapi/bulk_copy/Makefile | 9 - ndb/test/ndbapi/bulk_copy/bulk_copy.cpp | 275 -- ndb/test/ndbapi/cdrserver.cpp | 1627 ++++++++++++ ndb/test/ndbapi/cello-sessionDb/celloDb.cpp | 1503 ----------- ndb/test/ndbapi/celloDb.cpp | 1503 +++++++++++ ndb/test/ndbapi/create_all_tabs.cpp | 63 + ndb/test/ndbapi/create_all_tabs/Makefile | 11 - .../ndbapi/create_all_tabs/create_all_tabs.cpp | 63 - ndb/test/ndbapi/create_tab.cpp | 107 + ndb/test/ndbapi/create_tab/Makefile | 11 - ndb/test/ndbapi/create_tab/create_tab.cpp | 107 - ndb/test/ndbapi/drop_all_tabs.cpp | 56 + ndb/test/ndbapi/drop_all_tabs/Makefile | 11 - ndb/test/ndbapi/drop_all_tabs/drop_all_tabs.cpp | 56 - ndb/test/ndbapi/flexAsynch.cpp | 982 +++++++ ndb/test/ndbapi/flexAsynch/Makefile | 11 - ndb/test/ndbapi/flexAsynch/flexAsynch.cpp | 982 ------- ndb/test/ndbapi/flexBench.cpp | 1153 ++++++++ ndb/test/ndbapi/flexBench/Makefile.am | 14 - ndb/test/ndbapi/flexBench/Makefile_old | 11 - ndb/test/ndbapi/flexBench/flexBench.cpp | 1153 -------- ndb/test/ndbapi/flexBench/ndbplot.pl | 305 --- ndb/test/ndbapi/flexHammer.cpp | 889 +++++++ ndb/test/ndbapi/flexHammer/Makefile | 9 - ndb/test/ndbapi/flexHammer/README | 67 - ndb/test/ndbapi/flexHammer/flexHammer.cpp | 889 ------- ndb/test/ndbapi/flexScan.cpp | 1674 ++++++++++++ ndb/test/ndbapi/flexScan/Makefile | 9 - ndb/test/ndbapi/flexScan/README | 66 - ndb/test/ndbapi/flexScan/flexScan.cpp | 1674 ------------ ndb/test/ndbapi/flexTT.cpp | 927 +++++++ ndb/test/ndbapi/flexTT/Makefile | 11 - ndb/test/ndbapi/flexTT/flexTT.cpp | 927 ------- ndb/test/ndbapi/flexTimedAsynch.cpp | 852 ++++++ ndb/test/ndbapi/flexTimedAsynch/Makefile | 11 - .../ndbapi/flexTimedAsynch/flexTimedAsynch.cpp | 852 ------ ndb/test/ndbapi/flex_bench_mysql.cpp | 1749 +++++++++++++ ndb/test/ndbapi/flex_bench_mysql/Makefile | 15 - .../ndbapi/flex_bench_mysql/flex_bench_mysql.cpp | 1749 ------------- ndb/test/ndbapi/index.cpp | 997 +++++++ ndb/test/ndbapi/index2.cpp | 835 ++++++ ndb/test/ndbapi/indexTest/Makefile | 9 - ndb/test/ndbapi/indexTest/index.cpp | 997 ------- ndb/test/ndbapi/indexTest2/Makefile | 9 - ndb/test/ndbapi/indexTest2/index2.cpp | 835 ------ ndb/test/ndbapi/initronja.cpp | 349 +++ ndb/test/ndbapi/interpreterInTup.cpp | 1524 +++++++++++ ndb/test/ndbapi/interpreterInTup/Makefile | 10 - .../ndbapi/interpreterInTup/interpreterInTup.cpp | 1524 ----------- ndb/test/ndbapi/lmc-bench/Makefile | 6 - ndb/test/ndbapi/lmc-bench/async-src/Makefile | 8 - .../ndbapi/lmc-bench/async-src/generator/Makefile | 13 - .../async-src/generator/asyncGenerator.cpp | 571 ---- .../async-src/generator/mainAsyncGenerator.cpp | 392 --- .../lmc-bench/async-src/include/dbGenerator.h | 63 - .../ndbapi/lmc-bench/async-src/include/testData.h | 156 -- .../lmc-bench/async-src/include/userInterface.h | 79 - ndb/test/ndbapi/lmc-bench/async-src/user/Makefile | 11 - ndb/test/ndbapi/lmc-bench/async-src/user/macros.h | 51 - .../ndbapi/lmc-bench/async-src/user/ndb_async1.cpp | 647 ----- .../ndbapi/lmc-bench/async-src/user/ndb_async2.cpp | 754 ------ .../ndbapi/lmc-bench/async-src/user/ndb_error.hpp | 63 - .../lmc-bench/async-src/user/userInterface.cpp | 117 - ndb/test/ndbapi/lmc-bench/bin/.empty | 0 ndb/test/ndbapi/lmc-bench/include/ndb_schema.hpp | 78 - .../ndbapi/lmc-bench/include/testDefinitions.h | 90 - ndb/test/ndbapi/lmc-bench/lib/.empty | 0 ndb/test/ndbapi/lmc-bench/script/Makefile | 5 - .../lmc-bench/script/async-lmc-bench-l-p10.sh | 14 - .../ndbapi/lmc-bench/script/async-lmc-bench-l.sh | 14 - .../ndbapi/lmc-bench/script/async-lmc-bench-p10.sh | 14 - .../ndbapi/lmc-bench/script/async-lmc-bench.sh | 14 - ndb/test/ndbapi/lmc-bench/src/Makefile | 8 - ndb/test/ndbapi/lmc-bench/src/README | 8 - ndb/test/ndbapi/lmc-bench/src/generator/Makefile | 17 - .../ndbapi/lmc-bench/src/generator/dbGenerator.c | 543 ---- .../ndbapi/lmc-bench/src/generator/dbGenerator.h | 61 - .../ndbapi/lmc-bench/src/generator/mainGenerator.c | 323 --- ndb/test/ndbapi/lmc-bench/src/include/testData.h | 103 - .../ndbapi/lmc-bench/src/include/userInterface.h | 128 - ndb/test/ndbapi/lmc-bench/src/makevars.linux | 6 - ndb/test/ndbapi/lmc-bench/src/makevars.sparc | 15 - ndb/test/ndbapi/lmc-bench/src/populator/Makefile | 15 - .../ndbapi/lmc-bench/src/populator/dbPopulate.c | 244 -- .../ndbapi/lmc-bench/src/populator/dbPopulate.h | 59 - .../ndbapi/lmc-bench/src/populator/mainPopulate.c | 76 - ndb/test/ndbapi/lmc-bench/src/user/Makefile | 11 - .../ndbapi/lmc-bench/src/user/localDbPrepare.c | 648 ----- ndb/test/ndbapi/lmc-bench/src/user/macros.h | 51 - ndb/test/ndbapi/lmc-bench/src/user/ndb_error.hpp | 31 - .../lmc-bench/src/user/ndb_user_populate.cpp | 165 -- .../lmc-bench/src/user/ndb_user_transaction.cpp | 825 ------ .../lmc-bench/src/user/ndb_user_transaction2.cpp | 825 ------ .../lmc-bench/src/user/ndb_user_transaction3.cpp | 793 ------ .../lmc-bench/src/user/ndb_user_transaction4.cpp | 770 ------ .../lmc-bench/src/user/ndb_user_transaction5.cpp | 769 ------ .../lmc-bench/src/user/ndb_user_transaction6.cpp | 561 ---- ndb/test/ndbapi/lmc-bench/src/user/old/Makefile | 10 - .../ndbapi/lmc-bench/src/user/old/userHandle.h | 190 -- .../ndbapi/lmc-bench/src/user/old/userInterface.c | 453 ---- .../lmc-bench/src/user/old/userTransaction.c | 473 ---- ndb/test/ndbapi/lmc-bench/src/user/userHandle.h | 51 - .../ndbapi/lmc-bench/src/user/userInterface.cpp | 740 ------ .../ndbapi/lmc-bench/src/user/userTransaction.c | 473 ---- ndb/test/ndbapi/mainAsyncGenerator.cpp | 392 +++ ndb/test/ndbapi/msa.cpp | 1203 +++++++++ ndb/test/ndbapi/ndb_async1.cpp | 647 +++++ ndb/test/ndbapi/ndb_async2.cpp | 754 ++++++ ndb/test/ndbapi/ndb_user_populate.cpp | 165 ++ ndb/test/ndbapi/ndb_user_transaction.cpp | 825 ++++++ ndb/test/ndbapi/ndb_user_transaction2.cpp | 825 ++++++ ndb/test/ndbapi/ndb_user_transaction3.cpp | 793 ++++++ ndb/test/ndbapi/ndb_user_transaction4.cpp | 770 ++++++ ndb/test/ndbapi/ndb_user_transaction5.cpp | 769 ++++++ ndb/test/ndbapi/ndb_user_transaction6.cpp | 561 ++++ ndb/test/ndbapi/old_dirs/acid/Makefile | 10 + ndb/test/ndbapi/old_dirs/acid2/Makefile | 10 + ndb/test/ndbapi/old_dirs/acid2/TraceNdbApi.hpp | 132 + ndb/test/ndbapi/old_dirs/acid2/VerifyNdbApi.hpp | 466 ++++ ndb/test/ndbapi/old_dirs/basicAsynch/Makefile | 9 + ndb/test/ndbapi/old_dirs/bulk_copy/Makefile | 9 + ndb/test/ndbapi/old_dirs/create_all_tabs/Makefile | 11 + ndb/test/ndbapi/old_dirs/create_tab/Makefile | 11 + ndb/test/ndbapi/old_dirs/drop_all_tabs/Makefile | 11 + ndb/test/ndbapi/old_dirs/flexAsynch/Makefile | 11 + ndb/test/ndbapi/old_dirs/flexBench/Makefile.am | 10 + ndb/test/ndbapi/old_dirs/flexBench/Makefile_old | 11 + ndb/test/ndbapi/old_dirs/flexBench/ndbplot.pl | 305 +++ ndb/test/ndbapi/old_dirs/flexHammer/Makefile | 9 + ndb/test/ndbapi/old_dirs/flexHammer/README | 67 + ndb/test/ndbapi/old_dirs/flexScan/Makefile | 9 + ndb/test/ndbapi/old_dirs/flexScan/README | 66 + ndb/test/ndbapi/old_dirs/flexTT/Makefile | 11 + ndb/test/ndbapi/old_dirs/flexTimedAsynch/Makefile | 11 + ndb/test/ndbapi/old_dirs/flex_bench_mysql/Makefile | 15 + ndb/test/ndbapi/old_dirs/indexTest/Makefile | 9 + ndb/test/ndbapi/old_dirs/indexTest2/Makefile | 9 + ndb/test/ndbapi/old_dirs/interpreterInTup/Makefile | 10 + ndb/test/ndbapi/old_dirs/lmc-bench/Makefile | 6 + .../ndbapi/old_dirs/lmc-bench/async-src/Makefile | 8 + .../lmc-bench/async-src/generator/Makefile | 13 + .../lmc-bench/async-src/include/dbGenerator.h | 63 + .../lmc-bench/async-src/include/testData.h | 156 ++ .../lmc-bench/async-src/include/userInterface.h | 79 + .../old_dirs/lmc-bench/async-src/user/Makefile | 11 + .../old_dirs/lmc-bench/async-src/user/macros.h | 51 + .../lmc-bench/async-src/user/ndb_error.hpp | 63 + ndb/test/ndbapi/old_dirs/lmc-bench/bin/.empty | 0 .../old_dirs/lmc-bench/include/ndb_schema.hpp | 78 + .../old_dirs/lmc-bench/include/testDefinitions.h | 90 + ndb/test/ndbapi/old_dirs/lmc-bench/lib/.empty | 0 ndb/test/ndbapi/old_dirs/lmc-bench/script/Makefile | 5 + .../lmc-bench/script/async-lmc-bench-l-p10.sh | 14 + .../old_dirs/lmc-bench/script/async-lmc-bench-l.sh | 14 + .../lmc-bench/script/async-lmc-bench-p10.sh | 14 + .../old_dirs/lmc-bench/script/async-lmc-bench.sh | 14 + ndb/test/ndbapi/old_dirs/lmc-bench/src/Makefile | 8 + ndb/test/ndbapi/old_dirs/lmc-bench/src/README | 8 + .../old_dirs/lmc-bench/src/generator/Makefile | 17 + .../old_dirs/lmc-bench/src/generator/dbGenerator.c | 543 ++++ .../old_dirs/lmc-bench/src/generator/dbGenerator.h | 61 + .../lmc-bench/src/generator/mainGenerator.c | 323 +++ .../old_dirs/lmc-bench/src/include/testData.h | 103 + .../old_dirs/lmc-bench/src/include/userInterface.h | 128 + .../ndbapi/old_dirs/lmc-bench/src/makevars.linux | 6 + .../ndbapi/old_dirs/lmc-bench/src/makevars.sparc | 15 + .../old_dirs/lmc-bench/src/populator/Makefile | 15 + .../old_dirs/lmc-bench/src/populator/dbPopulate.c | 244 ++ .../old_dirs/lmc-bench/src/populator/dbPopulate.h | 59 + .../lmc-bench/src/populator/mainPopulate.c | 76 + .../ndbapi/old_dirs/lmc-bench/src/user/Makefile | 11 + .../old_dirs/lmc-bench/src/user/localDbPrepare.c | 648 +++++ .../ndbapi/old_dirs/lmc-bench/src/user/macros.h | 51 + .../old_dirs/lmc-bench/src/user/ndb_error.hpp | 31 + .../old_dirs/lmc-bench/src/user/old/Makefile | 10 + .../old_dirs/lmc-bench/src/user/old/userHandle.h | 190 ++ .../lmc-bench/src/user/old/userInterface.c | 453 ++++ .../lmc-bench/src/user/old/userTransaction.c | 473 ++++ .../old_dirs/lmc-bench/src/user/userHandle.h | 51 + .../old_dirs/lmc-bench/src/user/userInterface.cpp | 740 ++++++ .../old_dirs/lmc-bench/src/user/userTransaction.c | 473 ++++ ndb/test/ndbapi/old_dirs/restarter/Makefile | 11 + ndb/test/ndbapi/old_dirs/restarter2/Makefile | 11 + ndb/test/ndbapi/old_dirs/restarts/Makefile | 11 + ndb/test/ndbapi/old_dirs/ronja/Makefile | 6 + ndb/test/ndbapi/old_dirs/ronja/benchronja/Makefile | 10 + ndb/test/ndbapi/old_dirs/ronja/initronja/Makefile | 9 + ndb/test/ndbapi/old_dirs/telco/Makefile | 10 + ndb/test/ndbapi/old_dirs/telco/readme | 9 + ndb/test/ndbapi/old_dirs/testBackup/Makefile | 9 + ndb/test/ndbapi/old_dirs/testBasic/Makefile | 9 + ndb/test/ndbapi/old_dirs/testBlobs/Makefile | 11 + ndb/test/ndbapi/old_dirs/testDataBuffers/Makefile | 9 + ndb/test/ndbapi/old_dirs/testDict/Makefile | 11 + ndb/test/ndbapi/old_dirs/testGrep/Makefile | 10 + ndb/test/ndbapi/old_dirs/testGrep/verify/Makefile | 11 + ndb/test/ndbapi/old_dirs/testIndex/Makefile | 11 + ndb/test/ndbapi/old_dirs/testInterpreter/Makefile | 9 + ndb/test/ndbapi/old_dirs/testMgm/Makefile | 9 + ndb/test/ndbapi/old_dirs/testNdbApi/Makefile | 9 + ndb/test/ndbapi/old_dirs/testNodeRestart/Makefile | 9 + ndb/test/ndbapi/old_dirs/testOIBasic/Makefile | 13 + ndb/test/ndbapi/old_dirs/testOIBasic/times.txt | 8 + ndb/test/ndbapi/old_dirs/testOperations/Makefile | 9 + ndb/test/ndbapi/old_dirs/testOrderedIndex/Makefile | 9 + ndb/test/ndbapi/old_dirs/testRestartGci/Makefile | 9 + ndb/test/ndbapi/old_dirs/testScan/Makefile | 9 + .../ndbapi/old_dirs/testScanInterpreter/Makefile | 9 + .../ndbapi/old_dirs/testSystemRestart/Makefile | 11 + ndb/test/ndbapi/old_dirs/testTimeout/Makefile | 9 + ndb/test/ndbapi/old_dirs/testTransactions/Makefile | 10 + ndb/test/ndbapi/old_dirs/test_event/Makefile | 9 + ndb/test/ndbapi/old_dirs/vw_test/Makefile | 11 + ndb/test/ndbapi/old_dirs/vw_test/bcd.h | 26 + .../ndbapi/old_dirs/vw_test/script/client_start | 10 + ndb/test/ndbapi/old_dirs/vw_test/utv.h | 161 ++ ndb/test/ndbapi/old_dirs/vw_test/vcdrfunc.h | 55 + ndb/test/ndbapi/restarter.cpp | 129 + ndb/test/ndbapi/restarter/Makefile | 11 - ndb/test/ndbapi/restarter/restarter.cpp | 129 - ndb/test/ndbapi/restarter2.cpp | 116 + ndb/test/ndbapi/restarter2/Makefile | 11 - ndb/test/ndbapi/restarter2/restarter2.cpp | 116 - ndb/test/ndbapi/restarts.cpp | 115 + ndb/test/ndbapi/restarts/Makefile | 11 - ndb/test/ndbapi/restarts/restarts.cpp | 115 - ndb/test/ndbapi/ronja/Makefile | 6 - ndb/test/ndbapi/ronja/benchronja/Makefile | 10 - ndb/test/ndbapi/ronja/benchronja/benchronja.cpp | 1202 --------- ndb/test/ndbapi/ronja/initronja/Makefile | 9 - ndb/test/ndbapi/ronja/initronja/initronja.cpp | 349 --- ndb/test/ndbapi/size.cpp | 27 + ndb/test/ndbapi/telco/InsertRecs.cpp | 571 ---- ndb/test/ndbapi/telco/Makefile | 10 - ndb/test/ndbapi/telco/adoInsertRecs.cpp | 363 --- ndb/test/ndbapi/telco/msa.cpp | 1203 --------- ndb/test/ndbapi/telco/readme | 9 - ndb/test/ndbapi/testBackup.cpp | 475 ++++ ndb/test/ndbapi/testBackup/Makefile | 9 - ndb/test/ndbapi/testBackup/testBackup.cpp | 476 ---- ndb/test/ndbapi/testBasic.cpp | 1265 +++++++++ ndb/test/ndbapi/testBasic/Makefile | 9 - ndb/test/ndbapi/testBasic/testBasic.cpp | 1265 --------- ndb/test/ndbapi/testBasicAsynch.cpp | 186 ++ ndb/test/ndbapi/testBlobs.cpp | 194 ++ ndb/test/ndbapi/testBlobs/Makefile | 11 - ndb/test/ndbapi/testBlobs/testBlobs.cpp | 195 -- ndb/test/ndbapi/testDataBuffers.cpp | 616 +++++ ndb/test/ndbapi/testDataBuffers/Makefile | 9 - .../ndbapi/testDataBuffers/testDataBuffers.cpp | 616 ----- ndb/test/ndbapi/testDict.cpp | 1578 +++++++++++ ndb/test/ndbapi/testDict/Makefile | 11 - ndb/test/ndbapi/testDict/testDict.cpp | 1578 ----------- ndb/test/ndbapi/testGrep.cpp | 540 ++++ ndb/test/ndbapi/testGrep/Makefile | 10 - ndb/test/ndbapi/testGrep/testGrep.cpp | 540 ---- ndb/test/ndbapi/testGrep/verify/Makefile | 11 - ndb/test/ndbapi/testGrep/verify/testGrepVerify.cpp | 120 - ndb/test/ndbapi/testGrepVerify.cpp | 120 + ndb/test/ndbapi/testIndex.cpp | 1495 +++++++++++ ndb/test/ndbapi/testIndex/Makefile | 11 - ndb/test/ndbapi/testIndex/testIndex.cpp | 1495 ----------- ndb/test/ndbapi/testInterpreter.cpp | 231 ++ ndb/test/ndbapi/testInterpreter/Makefile | 9 - .../ndbapi/testInterpreter/testInterpreter.cpp | 231 -- ndb/test/ndbapi/testMgm.cpp | 184 ++ ndb/test/ndbapi/testMgm/Makefile | 9 - ndb/test/ndbapi/testMgm/testMgm.cpp | 184 -- ndb/test/ndbapi/testNdbApi.cpp | 1013 +++++++ ndb/test/ndbapi/testNdbApi/Makefile | 9 - ndb/test/ndbapi/testNdbApi/testNdbApi.cpp | 1013 ------- ndb/test/ndbapi/testNodeRestart.cpp | 449 ++++ ndb/test/ndbapi/testNodeRestart/Makefile | 9 - .../ndbapi/testNodeRestart/testNodeRestart.cpp | 449 ---- ndb/test/ndbapi/testOIBasic.cpp | 2767 ++++++++++++++++++++ ndb/test/ndbapi/testOIBasic/Makefile | 13 - ndb/test/ndbapi/testOIBasic/testOIBasic.cpp | 2767 -------------------- ndb/test/ndbapi/testOIBasic/times.txt | 8 - ndb/test/ndbapi/testOperations.cpp | 271 ++ ndb/test/ndbapi/testOperations/Makefile | 9 - ndb/test/ndbapi/testOperations/testOperations.cpp | 271 -- ndb/test/ndbapi/testOrderedIndex.cpp | 224 ++ ndb/test/ndbapi/testOrderedIndex/Makefile | 9 - .../ndbapi/testOrderedIndex/testOrderedIndex.cpp | 224 -- ndb/test/ndbapi/testRestartGci.cpp | 218 ++ ndb/test/ndbapi/testRestartGci/Makefile | 9 - ndb/test/ndbapi/testRestartGci/testRestartGci.cpp | 218 -- ndb/test/ndbapi/testScan.cpp | 1311 ++++++++++ ndb/test/ndbapi/testScan/Makefile | 9 - ndb/test/ndbapi/testScan/ScanFunctions.hpp | 392 --- ndb/test/ndbapi/testScan/testScan.cpp | 1311 ---------- ndb/test/ndbapi/testScanInterpreter.cpp | 280 ++ ndb/test/ndbapi/testScanInterpreter/Makefile | 9 - ndb/test/ndbapi/testScanInterpreter/ScanFilter.hpp | 131 - .../testScanInterpreter/ScanInterpretTest.hpp | 528 ---- .../testScanInterpreter/testScanInterpreter.cpp | 280 -- ndb/test/ndbapi/testSystemRestart.cpp | 942 +++++++ ndb/test/ndbapi/testSystemRestart/Makefile | 11 - .../ndbapi/testSystemRestart/testSystemRestart.cpp | 942 ------- ndb/test/ndbapi/testTimeout.cpp | 261 ++ ndb/test/ndbapi/testTimeout/Makefile | 9 - ndb/test/ndbapi/testTimeout/testTimeout.cpp | 261 -- ndb/test/ndbapi/testTransactions.cpp | 411 +++ ndb/test/ndbapi/testTransactions/Makefile | 10 - .../ndbapi/testTransactions/testTransactions.cpp | 411 --- ndb/test/ndbapi/test_event.cpp | 142 + ndb/test/ndbapi/test_event/Makefile | 9 - ndb/test/ndbapi/test_event/test_event.cpp | 142 - ndb/test/ndbapi/userInterface.cpp | 117 + ndb/test/ndbapi/vw_test/Makefile | 11 - ndb/test/ndbapi/vw_test/bcd.h | 26 - ndb/test/ndbapi/vw_test/cdrserver.cpp | 1627 ------------ ndb/test/ndbapi/vw_test/script/client_start | 10 - ndb/test/ndbapi/vw_test/size.cpp | 27 - ndb/test/ndbapi/vw_test/utv.h | 161 -- ndb/test/ndbapi/vw_test/vcdrfunc.h | 55 - ndb/test/run-test/Makefile.am | 16 + ndb/test/tools/Makefile.am | 29 + ndb/test/tools/copy_tab.cpp | 99 + ndb/test/tools/cpcc.cpp | 349 +++ ndb/test/tools/create_index.cpp | 95 + ndb/test/tools/hugoCalculator.cpp | 70 + ndb/test/tools/hugoCalculator/Makefile | 11 - ndb/test/tools/hugoCalculator/hugoCalculator.cpp | 70 - ndb/test/tools/hugoFill.cpp | 78 + ndb/test/tools/hugoFill/Makefile | 11 - ndb/test/tools/hugoFill/hugoFill.cpp | 78 - ndb/test/tools/hugoLoad.cpp | 82 + ndb/test/tools/hugoLoad/Makefile | 11 - ndb/test/tools/hugoLoad/hugoLoad.cpp | 82 - ndb/test/tools/hugoLockRecords.cpp | 90 + ndb/test/tools/hugoLockRecords/Makefile | 9 - ndb/test/tools/hugoLockRecords/hugoLockRecords.cpp | 90 - ndb/test/tools/hugoPkDelete.cpp | 86 + ndb/test/tools/hugoPkDelete/Makefile | 9 - ndb/test/tools/hugoPkDelete/hugoPkDel.cpp | 86 - ndb/test/tools/hugoPkRead.cpp | 91 + ndb/test/tools/hugoPkRead/Makefile | 9 - ndb/test/tools/hugoPkRead/hugoPkRead.cpp | 91 - ndb/test/tools/hugoPkReadRecord.cpp | 194 ++ ndb/test/tools/hugoPkReadRecord/Makefile | 11 - .../tools/hugoPkReadRecord/hugoPkReadRecord.cpp | 194 -- ndb/test/tools/hugoPkUpdate.cpp | 88 + ndb/test/tools/hugoPkUpdate/Makefile | 9 - ndb/test/tools/hugoPkUpdate/hugoPkUpd.cpp | 88 - ndb/test/tools/hugoScanRead.cpp | 90 + ndb/test/tools/hugoScanRead/Makefile | 9 - ndb/test/tools/hugoScanRead/hugoScanRead.cpp | 90 - ndb/test/tools/hugoScanUpdate.cpp | 100 + ndb/test/tools/hugoScanUpdate/Makefile | 9 - ndb/test/tools/hugoScanUpdate/hugoScanUpd.cpp | 100 - ndb/test/tools/old_dirs/hugoCalculator/Makefile | 11 + ndb/test/tools/old_dirs/hugoFill/Makefile | 11 + ndb/test/tools/old_dirs/hugoLoad/Makefile | 11 + ndb/test/tools/old_dirs/hugoLockRecords/Makefile | 9 + ndb/test/tools/old_dirs/hugoPkDelete/Makefile | 9 + ndb/test/tools/old_dirs/hugoPkRead/Makefile | 9 + ndb/test/tools/old_dirs/hugoPkReadRecord/Makefile | 11 + ndb/test/tools/old_dirs/hugoPkUpdate/Makefile | 9 + ndb/test/tools/old_dirs/hugoScanRead/Makefile | 9 + ndb/test/tools/old_dirs/hugoScanUpdate/Makefile | 9 + ndb/test/tools/old_dirs/restart/Makefile | 11 + ndb/test/tools/old_dirs/transproxy/Makefile | 29 + ndb/test/tools/old_dirs/verify_index/Makefile | 9 + ndb/test/tools/old_dirs/waiter/Makefile_old | 11 + ndb/test/tools/old_dirs/waiter/waiter.cpp | 56 + ndb/test/tools/restart.cpp | 83 + ndb/test/tools/restart/Makefile | 11 - ndb/test/tools/restart/restart.cpp | 83 - ndb/test/tools/transproxy.cpp | 362 +++ ndb/test/tools/verify_index.cpp | 85 + ndb/test/tools/waiter.cpp | 56 + ndb/test/tools/waiter/Makefile | 11 - ndb/test/tools/waiter/waiter.cpp | 56 - 435 files changed, 57908 insertions(+), 56687 deletions(-) create mode 100644 ndb/test/ndbapi/InsertRecs.cpp create mode 100644 ndb/test/ndbapi/ScanFilter.hpp create mode 100644 ndb/test/ndbapi/ScanFunctions.hpp create mode 100644 ndb/test/ndbapi/ScanInterpretTest.hpp create mode 100644 ndb/test/ndbapi/TraceNdbApi.cpp create mode 100644 ndb/test/ndbapi/VerifyNdbApi.cpp create mode 100644 ndb/test/ndbapi/acid.cpp delete mode 100644 ndb/test/ndbapi/acid/Makefile delete mode 100644 ndb/test/ndbapi/acid/acid.cpp create mode 100644 ndb/test/ndbapi/acid2.cpp delete mode 100644 ndb/test/ndbapi/acid2/Makefile delete mode 100644 ndb/test/ndbapi/acid2/TraceNdbApi.cpp delete mode 100644 ndb/test/ndbapi/acid2/TraceNdbApi.hpp delete mode 100644 ndb/test/ndbapi/acid2/VerifyNdbApi.cpp delete mode 100644 ndb/test/ndbapi/acid2/VerifyNdbApi.hpp delete mode 100644 ndb/test/ndbapi/acid2/acid2.cpp create mode 100644 ndb/test/ndbapi/adoInsertRecs.cpp create mode 100644 ndb/test/ndbapi/asyncGenerator.cpp create mode 100644 ndb/test/ndbapi/bank/Bank.cpp create mode 100644 ndb/test/ndbapi/bank/BankLoad.cpp delete mode 100644 ndb/test/ndbapi/bank/Makefile create mode 100644 ndb/test/ndbapi/bank/Makefile.am create mode 100644 ndb/test/ndbapi/bank/Makefile_old create mode 100644 ndb/test/ndbapi/bank/bankCreator.cpp delete mode 100644 ndb/test/ndbapi/bank/bankCreator/Makefile delete mode 100644 ndb/test/ndbapi/bank/bankCreator/bankCreator.cpp create mode 100644 ndb/test/ndbapi/bank/bankMakeGL.cpp delete mode 100644 ndb/test/ndbapi/bank/bankMakeGL/Makefile delete mode 100644 ndb/test/ndbapi/bank/bankMakeGL/bankMakeGL.cpp create mode 100644 ndb/test/ndbapi/bank/bankSumAccounts.cpp delete mode 100644 ndb/test/ndbapi/bank/bankSumAccounts/Makefile delete mode 100644 ndb/test/ndbapi/bank/bankSumAccounts/bankSumAccounts.cpp create mode 100644 ndb/test/ndbapi/bank/bankTimer.cpp delete mode 100644 ndb/test/ndbapi/bank/bankTimer/Makefile delete mode 100644 ndb/test/ndbapi/bank/bankTimer/bankTimer.cpp create mode 100644 ndb/test/ndbapi/bank/bankTransactionMaker.cpp delete mode 100644 ndb/test/ndbapi/bank/bankTransactionMaker/Makefile delete mode 100644 ndb/test/ndbapi/bank/bankTransactionMaker/bankTransactionMaker.cpp create mode 100644 ndb/test/ndbapi/bank/bankValidateAllGLs.cpp delete mode 100644 ndb/test/ndbapi/bank/bankValidateAllGLs/Makefile delete mode 100644 ndb/test/ndbapi/bank/bankValidateAllGLs/bankValidateAllGLs.cpp create mode 100644 ndb/test/ndbapi/bank/old_dirs/bankCreator/Makefile create mode 100644 ndb/test/ndbapi/bank/old_dirs/bankMakeGL/Makefile create mode 100644 ndb/test/ndbapi/bank/old_dirs/bankSumAccounts/Makefile create mode 100644 ndb/test/ndbapi/bank/old_dirs/bankTimer/Makefile create mode 100644 ndb/test/ndbapi/bank/old_dirs/bankTransactionMaker/Makefile create mode 100644 ndb/test/ndbapi/bank/old_dirs/bankValidateAllGLs/Makefile create mode 100644 ndb/test/ndbapi/bank/old_dirs/src/Makefile create mode 100644 ndb/test/ndbapi/bank/old_dirs/testBank/Makefile delete mode 100644 ndb/test/ndbapi/bank/src/Bank.cpp delete mode 100644 ndb/test/ndbapi/bank/src/BankLoad.cpp delete mode 100644 ndb/test/ndbapi/bank/src/Makefile create mode 100644 ndb/test/ndbapi/bank/testBank.cpp delete mode 100644 ndb/test/ndbapi/bank/testBank/Makefile delete mode 100644 ndb/test/ndbapi/bank/testBank/testBank.cpp delete mode 100755 ndb/test/ndbapi/basicAsynch/Makefile delete mode 100755 ndb/test/ndbapi/basicAsynch/testBasicAsynch.cpp create mode 100644 ndb/test/ndbapi/benchronja.cpp create mode 100644 ndb/test/ndbapi/bulk_copy.cpp delete mode 100644 ndb/test/ndbapi/bulk_copy/Makefile delete mode 100644 ndb/test/ndbapi/bulk_copy/bulk_copy.cpp create mode 100644 ndb/test/ndbapi/cdrserver.cpp delete mode 100644 ndb/test/ndbapi/cello-sessionDb/celloDb.cpp create mode 100644 ndb/test/ndbapi/celloDb.cpp create mode 100644 ndb/test/ndbapi/create_all_tabs.cpp delete mode 100644 ndb/test/ndbapi/create_all_tabs/Makefile delete mode 100644 ndb/test/ndbapi/create_all_tabs/create_all_tabs.cpp create mode 100644 ndb/test/ndbapi/create_tab.cpp delete mode 100644 ndb/test/ndbapi/create_tab/Makefile delete mode 100644 ndb/test/ndbapi/create_tab/create_tab.cpp create mode 100644 ndb/test/ndbapi/drop_all_tabs.cpp delete mode 100644 ndb/test/ndbapi/drop_all_tabs/Makefile delete mode 100644 ndb/test/ndbapi/drop_all_tabs/drop_all_tabs.cpp create mode 100644 ndb/test/ndbapi/flexAsynch.cpp delete mode 100644 ndb/test/ndbapi/flexAsynch/Makefile delete mode 100644 ndb/test/ndbapi/flexAsynch/flexAsynch.cpp create mode 100644 ndb/test/ndbapi/flexBench.cpp delete mode 100644 ndb/test/ndbapi/flexBench/Makefile.am delete mode 100644 ndb/test/ndbapi/flexBench/Makefile_old delete mode 100644 ndb/test/ndbapi/flexBench/flexBench.cpp delete mode 100755 ndb/test/ndbapi/flexBench/ndbplot.pl create mode 100644 ndb/test/ndbapi/flexHammer.cpp delete mode 100644 ndb/test/ndbapi/flexHammer/Makefile delete mode 100644 ndb/test/ndbapi/flexHammer/README delete mode 100644 ndb/test/ndbapi/flexHammer/flexHammer.cpp create mode 100644 ndb/test/ndbapi/flexScan.cpp delete mode 100644 ndb/test/ndbapi/flexScan/Makefile delete mode 100644 ndb/test/ndbapi/flexScan/README delete mode 100644 ndb/test/ndbapi/flexScan/flexScan.cpp create mode 100644 ndb/test/ndbapi/flexTT.cpp delete mode 100644 ndb/test/ndbapi/flexTT/Makefile delete mode 100644 ndb/test/ndbapi/flexTT/flexTT.cpp create mode 100644 ndb/test/ndbapi/flexTimedAsynch.cpp delete mode 100644 ndb/test/ndbapi/flexTimedAsynch/Makefile delete mode 100644 ndb/test/ndbapi/flexTimedAsynch/flexTimedAsynch.cpp create mode 100644 ndb/test/ndbapi/flex_bench_mysql.cpp delete mode 100644 ndb/test/ndbapi/flex_bench_mysql/Makefile delete mode 100644 ndb/test/ndbapi/flex_bench_mysql/flex_bench_mysql.cpp create mode 100644 ndb/test/ndbapi/index.cpp create mode 100644 ndb/test/ndbapi/index2.cpp delete mode 100644 ndb/test/ndbapi/indexTest/Makefile delete mode 100644 ndb/test/ndbapi/indexTest/index.cpp delete mode 100644 ndb/test/ndbapi/indexTest2/Makefile delete mode 100644 ndb/test/ndbapi/indexTest2/index2.cpp create mode 100644 ndb/test/ndbapi/initronja.cpp create mode 100644 ndb/test/ndbapi/interpreterInTup.cpp delete mode 100644 ndb/test/ndbapi/interpreterInTup/Makefile delete mode 100644 ndb/test/ndbapi/interpreterInTup/interpreterInTup.cpp delete mode 100644 ndb/test/ndbapi/lmc-bench/Makefile delete mode 100644 ndb/test/ndbapi/lmc-bench/async-src/Makefile delete mode 100644 ndb/test/ndbapi/lmc-bench/async-src/generator/Makefile delete mode 100644 ndb/test/ndbapi/lmc-bench/async-src/generator/asyncGenerator.cpp delete mode 100644 ndb/test/ndbapi/lmc-bench/async-src/generator/mainAsyncGenerator.cpp delete mode 100644 ndb/test/ndbapi/lmc-bench/async-src/include/dbGenerator.h delete mode 100644 ndb/test/ndbapi/lmc-bench/async-src/include/testData.h delete mode 100644 ndb/test/ndbapi/lmc-bench/async-src/include/userInterface.h delete mode 100644 ndb/test/ndbapi/lmc-bench/async-src/user/Makefile delete mode 100644 ndb/test/ndbapi/lmc-bench/async-src/user/macros.h delete mode 100644 ndb/test/ndbapi/lmc-bench/async-src/user/ndb_async1.cpp delete mode 100644 ndb/test/ndbapi/lmc-bench/async-src/user/ndb_async2.cpp delete mode 100644 ndb/test/ndbapi/lmc-bench/async-src/user/ndb_error.hpp delete mode 100644 ndb/test/ndbapi/lmc-bench/async-src/user/userInterface.cpp delete mode 100644 ndb/test/ndbapi/lmc-bench/bin/.empty delete mode 100644 ndb/test/ndbapi/lmc-bench/include/ndb_schema.hpp delete mode 100644 ndb/test/ndbapi/lmc-bench/include/testDefinitions.h delete mode 100644 ndb/test/ndbapi/lmc-bench/lib/.empty delete mode 100644 ndb/test/ndbapi/lmc-bench/script/Makefile delete mode 100755 ndb/test/ndbapi/lmc-bench/script/async-lmc-bench-l-p10.sh delete mode 100755 ndb/test/ndbapi/lmc-bench/script/async-lmc-bench-l.sh delete mode 100755 ndb/test/ndbapi/lmc-bench/script/async-lmc-bench-p10.sh delete mode 100755 ndb/test/ndbapi/lmc-bench/script/async-lmc-bench.sh delete mode 100644 ndb/test/ndbapi/lmc-bench/src/Makefile delete mode 100644 ndb/test/ndbapi/lmc-bench/src/README delete mode 100644 ndb/test/ndbapi/lmc-bench/src/generator/Makefile delete mode 100644 ndb/test/ndbapi/lmc-bench/src/generator/dbGenerator.c delete mode 100644 ndb/test/ndbapi/lmc-bench/src/generator/dbGenerator.h delete mode 100644 ndb/test/ndbapi/lmc-bench/src/generator/mainGenerator.c delete mode 100644 ndb/test/ndbapi/lmc-bench/src/include/testData.h delete mode 100644 ndb/test/ndbapi/lmc-bench/src/include/userInterface.h delete mode 100644 ndb/test/ndbapi/lmc-bench/src/makevars.linux delete mode 100644 ndb/test/ndbapi/lmc-bench/src/makevars.sparc delete mode 100644 ndb/test/ndbapi/lmc-bench/src/populator/Makefile delete mode 100644 ndb/test/ndbapi/lmc-bench/src/populator/dbPopulate.c delete mode 100644 ndb/test/ndbapi/lmc-bench/src/populator/dbPopulate.h delete mode 100644 ndb/test/ndbapi/lmc-bench/src/populator/mainPopulate.c delete mode 100644 ndb/test/ndbapi/lmc-bench/src/user/Makefile delete mode 100644 ndb/test/ndbapi/lmc-bench/src/user/localDbPrepare.c delete mode 100644 ndb/test/ndbapi/lmc-bench/src/user/macros.h delete mode 100644 ndb/test/ndbapi/lmc-bench/src/user/ndb_error.hpp delete mode 100644 ndb/test/ndbapi/lmc-bench/src/user/ndb_user_populate.cpp delete mode 100644 ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction.cpp delete mode 100644 ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction2.cpp delete mode 100644 ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction3.cpp delete mode 100644 ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction4.cpp delete mode 100644 ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction5.cpp delete mode 100644 ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction6.cpp delete mode 100644 ndb/test/ndbapi/lmc-bench/src/user/old/Makefile delete mode 100644 ndb/test/ndbapi/lmc-bench/src/user/old/userHandle.h delete mode 100644 ndb/test/ndbapi/lmc-bench/src/user/old/userInterface.c delete mode 100644 ndb/test/ndbapi/lmc-bench/src/user/old/userTransaction.c delete mode 100644 ndb/test/ndbapi/lmc-bench/src/user/userHandle.h delete mode 100644 ndb/test/ndbapi/lmc-bench/src/user/userInterface.cpp delete mode 100644 ndb/test/ndbapi/lmc-bench/src/user/userTransaction.c create mode 100644 ndb/test/ndbapi/mainAsyncGenerator.cpp create mode 100644 ndb/test/ndbapi/msa.cpp create mode 100644 ndb/test/ndbapi/ndb_async1.cpp create mode 100644 ndb/test/ndbapi/ndb_async2.cpp create mode 100644 ndb/test/ndbapi/ndb_user_populate.cpp create mode 100644 ndb/test/ndbapi/ndb_user_transaction.cpp create mode 100644 ndb/test/ndbapi/ndb_user_transaction2.cpp create mode 100644 ndb/test/ndbapi/ndb_user_transaction3.cpp create mode 100644 ndb/test/ndbapi/ndb_user_transaction4.cpp create mode 100644 ndb/test/ndbapi/ndb_user_transaction5.cpp create mode 100644 ndb/test/ndbapi/ndb_user_transaction6.cpp create mode 100644 ndb/test/ndbapi/old_dirs/acid/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/acid2/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/acid2/TraceNdbApi.hpp create mode 100644 ndb/test/ndbapi/old_dirs/acid2/VerifyNdbApi.hpp create mode 100755 ndb/test/ndbapi/old_dirs/basicAsynch/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/bulk_copy/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/create_all_tabs/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/create_tab/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/drop_all_tabs/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/flexAsynch/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/flexBench/Makefile.am create mode 100644 ndb/test/ndbapi/old_dirs/flexBench/Makefile_old create mode 100755 ndb/test/ndbapi/old_dirs/flexBench/ndbplot.pl create mode 100644 ndb/test/ndbapi/old_dirs/flexHammer/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/flexHammer/README create mode 100644 ndb/test/ndbapi/old_dirs/flexScan/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/flexScan/README create mode 100644 ndb/test/ndbapi/old_dirs/flexTT/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/flexTimedAsynch/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/flex_bench_mysql/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/indexTest/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/indexTest2/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/interpreterInTup/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/async-src/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/async-src/generator/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/async-src/include/dbGenerator.h create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/async-src/include/testData.h create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/async-src/include/userInterface.h create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/async-src/user/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/async-src/user/macros.h create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/async-src/user/ndb_error.hpp create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/bin/.empty create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/include/ndb_schema.hpp create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/include/testDefinitions.h create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/lib/.empty create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/script/Makefile create mode 100755 ndb/test/ndbapi/old_dirs/lmc-bench/script/async-lmc-bench-l-p10.sh create mode 100755 ndb/test/ndbapi/old_dirs/lmc-bench/script/async-lmc-bench-l.sh create mode 100755 ndb/test/ndbapi/old_dirs/lmc-bench/script/async-lmc-bench-p10.sh create mode 100755 ndb/test/ndbapi/old_dirs/lmc-bench/script/async-lmc-bench.sh create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/src/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/src/README create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/dbGenerator.c create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/dbGenerator.h create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/mainGenerator.c create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/src/include/testData.h create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/src/include/userInterface.h create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/src/makevars.linux create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/src/makevars.sparc create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/src/populator/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/src/populator/dbPopulate.c create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/src/populator/dbPopulate.h create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/src/populator/mainPopulate.c create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/src/user/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/src/user/localDbPrepare.c create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/src/user/macros.h create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/src/user/ndb_error.hpp create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/src/user/old/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/src/user/old/userHandle.h create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/src/user/old/userInterface.c create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/src/user/old/userTransaction.c create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/src/user/userHandle.h create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/src/user/userInterface.cpp create mode 100644 ndb/test/ndbapi/old_dirs/lmc-bench/src/user/userTransaction.c create mode 100644 ndb/test/ndbapi/old_dirs/restarter/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/restarter2/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/restarts/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/ronja/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/ronja/benchronja/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/ronja/initronja/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/telco/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/telco/readme create mode 100644 ndb/test/ndbapi/old_dirs/testBackup/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/testBasic/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/testBlobs/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/testDataBuffers/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/testDict/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/testGrep/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/testGrep/verify/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/testIndex/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/testInterpreter/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/testMgm/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/testNdbApi/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/testNodeRestart/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/testOIBasic/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/testOIBasic/times.txt create mode 100644 ndb/test/ndbapi/old_dirs/testOperations/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/testOrderedIndex/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/testRestartGci/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/testScan/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/testScanInterpreter/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/testSystemRestart/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/testTimeout/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/testTransactions/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/test_event/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/vw_test/Makefile create mode 100644 ndb/test/ndbapi/old_dirs/vw_test/bcd.h create mode 100644 ndb/test/ndbapi/old_dirs/vw_test/script/client_start create mode 100644 ndb/test/ndbapi/old_dirs/vw_test/utv.h create mode 100644 ndb/test/ndbapi/old_dirs/vw_test/vcdrfunc.h create mode 100644 ndb/test/ndbapi/restarter.cpp delete mode 100644 ndb/test/ndbapi/restarter/Makefile delete mode 100644 ndb/test/ndbapi/restarter/restarter.cpp create mode 100644 ndb/test/ndbapi/restarter2.cpp delete mode 100644 ndb/test/ndbapi/restarter2/Makefile delete mode 100644 ndb/test/ndbapi/restarter2/restarter2.cpp create mode 100644 ndb/test/ndbapi/restarts.cpp delete mode 100644 ndb/test/ndbapi/restarts/Makefile delete mode 100644 ndb/test/ndbapi/restarts/restarts.cpp delete mode 100644 ndb/test/ndbapi/ronja/Makefile delete mode 100644 ndb/test/ndbapi/ronja/benchronja/Makefile delete mode 100644 ndb/test/ndbapi/ronja/benchronja/benchronja.cpp delete mode 100644 ndb/test/ndbapi/ronja/initronja/Makefile delete mode 100644 ndb/test/ndbapi/ronja/initronja/initronja.cpp create mode 100644 ndb/test/ndbapi/size.cpp delete mode 100644 ndb/test/ndbapi/telco/InsertRecs.cpp delete mode 100644 ndb/test/ndbapi/telco/Makefile delete mode 100644 ndb/test/ndbapi/telco/adoInsertRecs.cpp delete mode 100644 ndb/test/ndbapi/telco/msa.cpp delete mode 100644 ndb/test/ndbapi/telco/readme create mode 100644 ndb/test/ndbapi/testBackup.cpp delete mode 100644 ndb/test/ndbapi/testBackup/Makefile delete mode 100644 ndb/test/ndbapi/testBackup/testBackup.cpp create mode 100644 ndb/test/ndbapi/testBasic.cpp delete mode 100644 ndb/test/ndbapi/testBasic/Makefile delete mode 100644 ndb/test/ndbapi/testBasic/testBasic.cpp create mode 100644 ndb/test/ndbapi/testBasicAsynch.cpp create mode 100644 ndb/test/ndbapi/testBlobs.cpp delete mode 100644 ndb/test/ndbapi/testBlobs/Makefile delete mode 100644 ndb/test/ndbapi/testBlobs/testBlobs.cpp create mode 100644 ndb/test/ndbapi/testDataBuffers.cpp delete mode 100644 ndb/test/ndbapi/testDataBuffers/Makefile delete mode 100644 ndb/test/ndbapi/testDataBuffers/testDataBuffers.cpp create mode 100644 ndb/test/ndbapi/testDict.cpp delete mode 100644 ndb/test/ndbapi/testDict/Makefile delete mode 100644 ndb/test/ndbapi/testDict/testDict.cpp create mode 100644 ndb/test/ndbapi/testGrep.cpp delete mode 100644 ndb/test/ndbapi/testGrep/Makefile delete mode 100644 ndb/test/ndbapi/testGrep/testGrep.cpp delete mode 100644 ndb/test/ndbapi/testGrep/verify/Makefile delete mode 100644 ndb/test/ndbapi/testGrep/verify/testGrepVerify.cpp create mode 100644 ndb/test/ndbapi/testGrepVerify.cpp create mode 100644 ndb/test/ndbapi/testIndex.cpp delete mode 100644 ndb/test/ndbapi/testIndex/Makefile delete mode 100644 ndb/test/ndbapi/testIndex/testIndex.cpp create mode 100644 ndb/test/ndbapi/testInterpreter.cpp delete mode 100644 ndb/test/ndbapi/testInterpreter/Makefile delete mode 100644 ndb/test/ndbapi/testInterpreter/testInterpreter.cpp create mode 100644 ndb/test/ndbapi/testMgm.cpp delete mode 100644 ndb/test/ndbapi/testMgm/Makefile delete mode 100644 ndb/test/ndbapi/testMgm/testMgm.cpp create mode 100644 ndb/test/ndbapi/testNdbApi.cpp delete mode 100644 ndb/test/ndbapi/testNdbApi/Makefile delete mode 100644 ndb/test/ndbapi/testNdbApi/testNdbApi.cpp create mode 100644 ndb/test/ndbapi/testNodeRestart.cpp delete mode 100644 ndb/test/ndbapi/testNodeRestart/Makefile delete mode 100644 ndb/test/ndbapi/testNodeRestart/testNodeRestart.cpp create mode 100644 ndb/test/ndbapi/testOIBasic.cpp delete mode 100644 ndb/test/ndbapi/testOIBasic/Makefile delete mode 100644 ndb/test/ndbapi/testOIBasic/testOIBasic.cpp delete mode 100644 ndb/test/ndbapi/testOIBasic/times.txt create mode 100644 ndb/test/ndbapi/testOperations.cpp delete mode 100644 ndb/test/ndbapi/testOperations/Makefile delete mode 100644 ndb/test/ndbapi/testOperations/testOperations.cpp create mode 100644 ndb/test/ndbapi/testOrderedIndex.cpp delete mode 100644 ndb/test/ndbapi/testOrderedIndex/Makefile delete mode 100644 ndb/test/ndbapi/testOrderedIndex/testOrderedIndex.cpp create mode 100644 ndb/test/ndbapi/testRestartGci.cpp delete mode 100644 ndb/test/ndbapi/testRestartGci/Makefile delete mode 100644 ndb/test/ndbapi/testRestartGci/testRestartGci.cpp create mode 100644 ndb/test/ndbapi/testScan.cpp delete mode 100644 ndb/test/ndbapi/testScan/Makefile delete mode 100644 ndb/test/ndbapi/testScan/ScanFunctions.hpp delete mode 100644 ndb/test/ndbapi/testScan/testScan.cpp create mode 100644 ndb/test/ndbapi/testScanInterpreter.cpp delete mode 100644 ndb/test/ndbapi/testScanInterpreter/Makefile delete mode 100644 ndb/test/ndbapi/testScanInterpreter/ScanFilter.hpp delete mode 100644 ndb/test/ndbapi/testScanInterpreter/ScanInterpretTest.hpp delete mode 100644 ndb/test/ndbapi/testScanInterpreter/testScanInterpreter.cpp create mode 100644 ndb/test/ndbapi/testSystemRestart.cpp delete mode 100644 ndb/test/ndbapi/testSystemRestart/Makefile delete mode 100644 ndb/test/ndbapi/testSystemRestart/testSystemRestart.cpp create mode 100644 ndb/test/ndbapi/testTimeout.cpp delete mode 100644 ndb/test/ndbapi/testTimeout/Makefile delete mode 100644 ndb/test/ndbapi/testTimeout/testTimeout.cpp create mode 100644 ndb/test/ndbapi/testTransactions.cpp delete mode 100644 ndb/test/ndbapi/testTransactions/Makefile delete mode 100644 ndb/test/ndbapi/testTransactions/testTransactions.cpp create mode 100644 ndb/test/ndbapi/test_event.cpp delete mode 100644 ndb/test/ndbapi/test_event/Makefile delete mode 100644 ndb/test/ndbapi/test_event/test_event.cpp create mode 100644 ndb/test/ndbapi/userInterface.cpp delete mode 100644 ndb/test/ndbapi/vw_test/Makefile delete mode 100644 ndb/test/ndbapi/vw_test/bcd.h delete mode 100644 ndb/test/ndbapi/vw_test/cdrserver.cpp delete mode 100644 ndb/test/ndbapi/vw_test/script/client_start delete mode 100644 ndb/test/ndbapi/vw_test/size.cpp delete mode 100644 ndb/test/ndbapi/vw_test/utv.h delete mode 100644 ndb/test/ndbapi/vw_test/vcdrfunc.h create mode 100644 ndb/test/run-test/Makefile.am create mode 100644 ndb/test/tools/Makefile.am create mode 100644 ndb/test/tools/copy_tab.cpp create mode 100644 ndb/test/tools/cpcc.cpp create mode 100644 ndb/test/tools/create_index.cpp create mode 100644 ndb/test/tools/hugoCalculator.cpp delete mode 100644 ndb/test/tools/hugoCalculator/Makefile delete mode 100644 ndb/test/tools/hugoCalculator/hugoCalculator.cpp create mode 100644 ndb/test/tools/hugoFill.cpp delete mode 100644 ndb/test/tools/hugoFill/Makefile delete mode 100644 ndb/test/tools/hugoFill/hugoFill.cpp create mode 100644 ndb/test/tools/hugoLoad.cpp delete mode 100644 ndb/test/tools/hugoLoad/Makefile delete mode 100644 ndb/test/tools/hugoLoad/hugoLoad.cpp create mode 100644 ndb/test/tools/hugoLockRecords.cpp delete mode 100644 ndb/test/tools/hugoLockRecords/Makefile delete mode 100644 ndb/test/tools/hugoLockRecords/hugoLockRecords.cpp create mode 100644 ndb/test/tools/hugoPkDelete.cpp delete mode 100644 ndb/test/tools/hugoPkDelete/Makefile delete mode 100644 ndb/test/tools/hugoPkDelete/hugoPkDel.cpp create mode 100644 ndb/test/tools/hugoPkRead.cpp delete mode 100644 ndb/test/tools/hugoPkRead/Makefile delete mode 100644 ndb/test/tools/hugoPkRead/hugoPkRead.cpp create mode 100644 ndb/test/tools/hugoPkReadRecord.cpp delete mode 100644 ndb/test/tools/hugoPkReadRecord/Makefile delete mode 100644 ndb/test/tools/hugoPkReadRecord/hugoPkReadRecord.cpp create mode 100644 ndb/test/tools/hugoPkUpdate.cpp delete mode 100644 ndb/test/tools/hugoPkUpdate/Makefile delete mode 100644 ndb/test/tools/hugoPkUpdate/hugoPkUpd.cpp create mode 100644 ndb/test/tools/hugoScanRead.cpp delete mode 100644 ndb/test/tools/hugoScanRead/Makefile delete mode 100644 ndb/test/tools/hugoScanRead/hugoScanRead.cpp create mode 100644 ndb/test/tools/hugoScanUpdate.cpp delete mode 100644 ndb/test/tools/hugoScanUpdate/Makefile delete mode 100644 ndb/test/tools/hugoScanUpdate/hugoScanUpd.cpp create mode 100644 ndb/test/tools/old_dirs/hugoCalculator/Makefile create mode 100644 ndb/test/tools/old_dirs/hugoFill/Makefile create mode 100644 ndb/test/tools/old_dirs/hugoLoad/Makefile create mode 100644 ndb/test/tools/old_dirs/hugoLockRecords/Makefile create mode 100644 ndb/test/tools/old_dirs/hugoPkDelete/Makefile create mode 100644 ndb/test/tools/old_dirs/hugoPkRead/Makefile create mode 100644 ndb/test/tools/old_dirs/hugoPkReadRecord/Makefile create mode 100644 ndb/test/tools/old_dirs/hugoPkUpdate/Makefile create mode 100644 ndb/test/tools/old_dirs/hugoScanRead/Makefile create mode 100644 ndb/test/tools/old_dirs/hugoScanUpdate/Makefile create mode 100644 ndb/test/tools/old_dirs/restart/Makefile create mode 100644 ndb/test/tools/old_dirs/transproxy/Makefile create mode 100644 ndb/test/tools/old_dirs/verify_index/Makefile create mode 100644 ndb/test/tools/old_dirs/waiter/Makefile_old create mode 100644 ndb/test/tools/old_dirs/waiter/waiter.cpp create mode 100644 ndb/test/tools/restart.cpp delete mode 100644 ndb/test/tools/restart/Makefile delete mode 100644 ndb/test/tools/restart/restart.cpp create mode 100644 ndb/test/tools/transproxy.cpp create mode 100644 ndb/test/tools/verify_index.cpp create mode 100644 ndb/test/tools/waiter.cpp delete mode 100644 ndb/test/tools/waiter/Makefile delete mode 100644 ndb/test/tools/waiter/waiter.cpp (limited to 'ndb/test') diff --git a/ndb/test/Makefile.am b/ndb/test/Makefile.am index 2805ae78984..cecbd0b8717 100644 --- a/ndb/test/Makefile.am +++ b/ndb/test/Makefile.am @@ -1,2 +1 @@ -SUBDIRS = src ndbapi -#SUBDIRS = src tools ndbapi run-test +SUBDIRS = src tools ndbapi run-test diff --git a/ndb/test/ndbapi/InsertRecs.cpp b/ndb/test/ndbapi/InsertRecs.cpp new file mode 100644 index 00000000000..f42786d666d --- /dev/null +++ b/ndb/test/ndbapi/InsertRecs.cpp @@ -0,0 +1,571 @@ +/* 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 */ + +// InsertRecs.cpp : Defines the entry point for the console application. +// + + +#include +#include +#include + + +// data for CALL_CONTEXT and GROUP_RESOURCE +static TCHAR STATUS_DATA[]=_T("000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F") + _T("101112131415161718191A1B1C1D1E1F000102030405060708090A0B0C0D0E0F") + _T("202122232425262728292A2B2C2D2E2F000102030405060708090A0B0C0D0E0F") + _T("303132333435363738393A3B3C3D3E3F000102030405060708090A0B0C0D0E0F") + _T("404142434445464748494A4B4C4D4E4F000102030405060708090A0B0C0D0E0F") + _T("505152535455565758595A5B5C5D5E5F000102030405060708090A0B0C0D0E0F") + _T("606162636465666768696A6B6C6D6E6F000102030405060708090A0B0C0D0E0F") + _T("707172737475767778797A7B7C7D7E7F000102030405060708090A0B0C0D0E0F") + _T("808182838485868788898A8B8C8D8E8F000102030405060708090A0B0C0D0E0F") + _T("909192939495969798999A9B9C9D9E9F000102030405060708090A0B0C0D0E0F") + _T("10010110210310410510610710810910A000102030405060708090A0B0C0D0EF") + _T("10B10C10D10E10F110111112113114115000102030405060708090A0B0C0D0EF") + _T("11611711811911A11B11C11D11E11F120000102030405060708090A0B0C0D0EF") + _T("12112212312412512612712812912A12B000102030405060708090A0B0C0D0EF") + _T("12C12D12E12F130131132134135136137000102030405060708090A0B0C0D0EF") + _T("13813913A13B13C13D13E13F140141142000102030405060708090A0B0C0D0EF") + _T("14314414514614714814914A14B14C14D000102030405060708090A0B0C0D0EF") + _T("14E14F150151152153154155156157158000102030405060708090A0B0C0D0EF") + _T("15915A15B15C15D15E15F160161162163000102030405060708090A0B0C0D0EF") + _T("16416516616716816916A16B16C16D16E000102030405060708090A0B0C0D0EF") + _T("16F170171172173174175176177178179000102030405060708090A0B0C0D0EF") + _T("17A17B17C17D17E17F180181182183184000102030405060708090A0B0C0D0EF") + _T("18518618718818918A18B18C18D18E18F000102030405060708090A0B0C0D0EF") + _T("19019119219319419519619719819919A000102030405060708090A0B0C0D0EF") + _T("19B19C19D19E19F200201202203204205000102030405060708090A0B0C0D0EF") + _T("20620720820920A20B20C20D20F210211000102030405060708090A0B0C0D0EF") + _T("21221321421521621721821921A21B21C000102030405060708090A0B0C0D0EF") + _T("21D21E21F220221222223224225226227000102030405060708090A0B0C0D0EF") + _T("22822922A22B22C22D22E22F230231232000102030405060708090A0B0C0D0EF") + _T("23323423523623723823923A23B23C23D000102030405060708090A0B0C0D0EF") + _T("23E23F240241242243244245246247248000102030405060708090A0B0C0D0EF") + _T("24924A24B24C24D24E24F250251252253000102030405060708090A0B0C0D0EF") + _T("101112131415161718191A1B1C1D1E1F000102030405060708090A0B0C0D0E0F") + _T("202122232425262728292A2B2C2D2E2F000102030405060708090A0B0C0D0E0F") + _T("303132333435363738393A3B3C3D3E3F000102030405060708090A0B0C0D0E0F") + _T("404142434445464748494A4B4C4D4E4F000102030405060708090A0B0C0D0E0F") + _T("505152535455565758595A5B5C5D5E5F000102030405060708090A0B0C0D0E0F") + _T("606162636465666768696A6B6C6D6E6F000102030405060708090A0B0C0D0E0F") + _T("707172737475767778797A7B7C7D7E7F000102030405060708090A0B0C0D0E0F") + _T("808182838485868788898A8B8C8D8E8F000102030405060708090A0B0C0D0E0F") + _T("909192939495969798999A9B9C9D9E9F000102030405060708090A0B0C0D0E0F") + _T("10010110210310410510610710810910A000102030405060708090A0B0C0D0EF") + _T("10B10C10D10E10F110111112113114115000102030405060708090A0B0C0D0EF") + _T("11611711811911A11B11C11D11E11F120000102030405060708090A0B0C0D0EF") + _T("12112212312412512612712812912A12B000102030405060708090A0B0C0D0EF") + _T("12C12D12E12F130131132134135136137000102030405060708090A0B0C0D0EF") + _T("13813913A13B13C13D13E13F140141142000102030405060708090A0B0C0D0EF") + _T("14314414514614714814914A14B14C14D000102030405060708090A0B0C0D0EF") + _T("14E14F150151152153154155156157158000102030405060708090A0B0C0D0EF") + _T("15915A15B15C15D15E15F160161162163000102030405060708090A0B0C0D0EF") + _T("16416516616716816916A16B16C16D16E000102030405060708090A0B0C0D0EF") + _T("16F170171172173174175176177178179000102030405060708090A0B0C0D0EF") + _T("17A17B17C17D17E17F180181182183184000102030405060708090A0B0C0D0EF") + _T("18518618718818918A18B18C18D18E18F000102030405060708090A0B0C0D0EF") + _T("19019119219319419519619719819919A000102030405060708090A0B0C0D0EF") + _T("19B19C19D19E19F200201202203204205000102030405060708090A0B0C0D0EF") + _T("20620720820920A20B20C20D20F210211000102030405060708090A0B0C0D0EF") + _T("21221321421521621721821921A21B21C000102030405060708090A0B0C0D0EF") + _T("21D21E21F220221222223224225226227000102030405060708090A0B0C0D0EF") + _T("22822922A22B22C22D22E22F230231232000102030405060708090A0B0C0D0EF") + _T("23323423523623723823923A23B23C23D000102030405060708090A0B0C0D0EF") + _T("2366890FE1438751097E7F6325DC0E6326F") + _T("25425525625725825925A25B25C25D25E25F000102030405060708090A0B0C0F"); +// Thread function for Call Context Inserts + +struct _ParamStruct +{ + HANDLE hShutdownEvent; + int nStartingRecordNum; + long* pnNumCallsProcessed; +}; + +HANDLE hShutdownEvent = 0; + +BOOL WINAPI ConsoleCtrlHandler(DWORD dwCtrlType) +{ + if(CTRL_C_EVENT == dwCtrlType) + { + SetEvent(hShutdownEvent); + return TRUE; + } + return FALSE; +} + + + + +DWORD WINAPI RuntimeCallContext(LPVOID lpParam) +{ + long nNumCallsProcessed = 0; + + struct _ParamStruct* pData = (struct _ParamStruct*)lpParam; + int nStartingRecordID = pData->nStartingRecordNum; + + Ndb* pNdb; + NdbConnection* pNdbConnection; + NdbOperation* pNdbOperation; + NdbRecAttr* pNdbRecAttrContextData; + + char pchContextData[4008]; + + LARGE_INTEGER freq; + LARGE_INTEGER liStartTime, liEndTime; + + pNdb = new Ndb("TEST_DB"); + if(!pNdb) + { + printf("new Ndb failed\n"); + return 0; + } + + try + { + if(pNdb->init(1) + || pNdb->waitUntilReady()) + { + throw pNdb; + } + + while(WaitForSingleObject(pData->hShutdownEvent,0) != WAIT_OBJECT_0) + { + nStartingRecordID++; + + bool bTimeLatency = (nStartingRecordID == 100) ? TRUE : FALSE; + + if (bTimeLatency) + { + BOOL bSuccess = QueryPerformanceFrequency(&freq); + if (!bSuccess) + printf("Error retrieving frequency: %d\n", GetLastError()); + + } + + for (int i=0; i < 20; i++) + { + switch(i) + { + case 3: + case 6: + case 9: + case 11: + case 12: + case 15: + case 18: // Query Record + if (bTimeLatency) + QueryPerformanceCounter(&liStartTime); + + pNdbConnection = pNdb->startTransaction((Uint32)0, (const char*)&nStartingRecordID, (Uint32)4); + if(!pNdbConnection) + { + throw pNdb; + } + pNdbOperation = pNdbConnection->getNdbOperation(_T("CallContext")); + if(!pNdbOperation) + { + throw pNdbConnection; + } + if(pNdbOperation->readTuple() + || pNdbOperation->equal(_T("ContextId"), nStartingRecordID)) + { + throw pNdbOperation; + } + pNdbRecAttrContextData = pNdbOperation->getValue(_T("ContextData"), pchContextData); + if(!pNdbRecAttrContextData) + { + throw pNdbOperation; + } + if(pNdbConnection->execute(Commit)) + { + throw pNdbConnection; + } + pNdb->closeTransaction(pNdbConnection); + + if (bTimeLatency) + { + QueryPerformanceCounter(&liEndTime); + printf("Read = %d msec.\n", (liEndTime.QuadPart - liStartTime.QuadPart) / (freq.QuadPart/1000)); + } + break; + + case 19: // Delete Record + if (bTimeLatency) + QueryPerformanceCounter(&liStartTime); + + pNdbConnection = pNdb->startTransaction((Uint32)0, (const char*)&nStartingRecordID, (Uint32)4); + if(!pNdbConnection) + { + throw pNdb; + } + pNdbOperation = pNdbConnection->getNdbOperation(_T("CallContext")); + if(!pNdbOperation) + { + throw pNdbConnection; + } + if(pNdbOperation->deleteTuple() + || pNdbOperation->equal(_T("ContextId"), nStartingRecordID)) + { + throw pNdbOperation; + } + if(pNdbConnection->execute(Commit)) + { + throw pNdbConnection; + } + pNdb->closeTransaction(pNdbConnection); + + if (bTimeLatency) + { + QueryPerformanceCounter(&liEndTime); + printf("Delete = %d msec.\n", (liEndTime.QuadPart - liStartTime.QuadPart) / (freq.QuadPart/1000)); + } + break; + + case 0: // Insert Record + if (bTimeLatency) + QueryPerformanceCounter(&liStartTime); + + pNdbConnection = pNdb->startTransaction((Uint32)0, (const char*)&nStartingRecordID, (Uint32)4); + if(!pNdbConnection) + { + throw pNdb; + } + pNdbOperation = pNdbConnection->getNdbOperation(_T("CallContext")); + if(!pNdbOperation) + { + throw pNdbConnection; + } + if(pNdbOperation->insertTuple() + || pNdbOperation->equal(_T("ContextId"), nStartingRecordID) + || pNdbOperation->setValue(_T("Version"), Int32(1)) + || pNdbOperation->setValue(_T("LockFlag"), Int32(1)) + || pNdbOperation->setValue(_T("LockTime"), Int32(1)) + || pNdbOperation->setValue(_T("LockTimeUSec"), Int32(1)) + || pNdbOperation->setValue(_T("ContextData"), STATUS_DATA, sizeof(STATUS_DATA))) + { + throw pNdbOperation; + } + if(pNdbConnection->execute(Commit)) + { + throw pNdbConnection; + } + pNdb->closeTransaction(pNdbConnection); + + if (bTimeLatency) + { + QueryPerformanceCounter(&liEndTime); + printf("Insert = %d msec.\n", (liEndTime.QuadPart - liStartTime.QuadPart) / (freq.QuadPart/1000)); + } + break; + + default: // Update Record + if (bTimeLatency) + QueryPerformanceCounter(&liStartTime); + + pNdbConnection = pNdb->startTransaction((Uint32)0, (const char*)&nStartingRecordID, (Uint32)4); + if(!pNdbConnection) + { + throw pNdb; + } + pNdbOperation = pNdbConnection->getNdbOperation(_T("CallContext")); + if(!pNdbOperation) + { + throw pNdbConnection; + } + if(pNdbOperation->updateTuple()) + { + throw pNdbOperation; + } + if(pNdbOperation->equal(_T("ContextId"), nStartingRecordID) + || pNdbOperation->setValue(_T("ContextData"), STATUS_DATA, sizeof(STATUS_DATA))) + { + throw pNdbOperation; + } + if(pNdbConnection->execute(Commit)) + { + throw pNdbConnection; + } + pNdb->closeTransaction(pNdbConnection); + + if (bTimeLatency) + { + QueryPerformanceCounter(&liEndTime); + printf("Update = %d msec.\n", (liEndTime.QuadPart - liStartTime.QuadPart) / (freq.QuadPart/1000)); + } + + break; + } + } + + nNumCallsProcessed++; + + InterlockedIncrement(pData->pnNumCallsProcessed); + } + + delete pNdb; + } + catch(Ndb* pNdb) + { + printf("%d: \n\t%s\n\t%s\n", + pNdb->getNdbError(), + pNdb->getNdbErrorString(), + "Ndb"); + delete pNdb; + } + catch(NdbConnection* pNdbConnection) + { + printf("%d: \n\t%s\n\t%s\n", + pNdbConnection->getNdbError(), + pNdbConnection->getNdbErrorString(), + "NdbConnection"); + pNdb->closeTransaction(pNdbConnection); + delete pNdb; + } + catch(NdbOperation* pNdbOperation) + { + printf("%d: \n\t%s\n\t%s\n", + pNdbOperation->getNdbError(), + pNdbOperation->getNdbErrorString(), + "NdbOperation"); + pNdb->closeTransaction(pNdbConnection); + delete pNdb; + } + + return 0; +} + + +void Initialize(Ndb* pNdb, long nInsert, bool bStoredTable) +{ + NdbSchemaCon* pNdbSchemaCon; + NdbSchemaOp* pNdbSchemaOp; + NdbConnection* pNdbConnection; + NdbOperation* pNdbOperation; + + try + { + _tprintf(_T("Create CallContext table\n")); + + pNdbSchemaCon = pNdb->startSchemaTransaction(); + if(!pNdbSchemaCon) + { + throw pNdb; + } + pNdbSchemaOp = pNdbSchemaCon->getNdbSchemaOp(); + if(!pNdbSchemaOp) + { + throw pNdbSchemaCon; + } + if(pNdbSchemaOp->createTable(_T("CallContext"), 8, TupleKey, 2, All, 6, 78, 80, 1, bStoredTable) + || pNdbSchemaOp->createAttribute(_T("ContextId"), TupleKey, 32, 1, Signed) + || pNdbSchemaOp->createAttribute(_T("Version"), NoKey, 32, 1, Signed) + || pNdbSchemaOp->createAttribute(_T("LockFlag"), NoKey, 32, 1, Signed) + || pNdbSchemaOp->createAttribute(_T("LockTime"), NoKey, 32, 1, Signed) + || pNdbSchemaOp->createAttribute(_T("LockTimeUSec"), NoKey, 32, 1, Signed) + || pNdbSchemaOp->createAttribute(_T("ContextData"), NoKey, 8, 4004, String)) + { + throw pNdbSchemaOp; + } + if(pNdbSchemaCon->execute()) + { + throw pNdbSchemaCon; + } + pNdb->closeSchemaTransaction(pNdbSchemaCon); + + _tprintf(_T("Insert %d tuples in the CallContext table\n"), nInsert); + for(long i=0; istartTransaction((Uint32)0, (const char*)&iContextId, (Uint32)4); + if(!pNdbConnection) + { + throw pNdb; + } + pNdbOperation = pNdbConnection->getNdbOperation(_T("CallContext")); + if(!pNdbOperation) + { + throw pNdbConnection; + } + if(pNdbOperation->insertTuple() + || pNdbOperation->equal(_T("ContextId"), iContextId) + || pNdbOperation->setValue(_T("Version"), Int32(1)) + || pNdbOperation->setValue(_T("LockFlag"), Int32(1)) + || pNdbOperation->setValue(_T("LockTime"), Int32(1)) + || pNdbOperation->setValue(_T("LockTimeUSec"), Int32(1)) + || pNdbOperation->setValue(_T("ContextData"), STATUS_DATA, sizeof(STATUS_DATA))) + { + throw pNdbOperation; + } + if(pNdbConnection->execute(Commit)) + { + throw pNdbConnection; + } + pNdb->closeTransaction(pNdbConnection); + } + _tprintf(_T("initialisation done\n")); + } + catch(Ndb* pNdb) + { + printf("%d: \n\t%s\n\t%s\n", + pNdb->getNdbError(), + pNdb->getNdbErrorString(), + "Ndb"); + delete pNdb; + } + catch(NdbConnection* pNdbConnection) + { + printf("%d: \n\t%s\n\t%s\n", + pNdbConnection->getNdbError(), + pNdbConnection->getNdbErrorString(), + "NdbConnection"); + pNdb->closeTransaction(pNdbConnection); + delete pNdb; + } + catch(NdbOperation* pNdbOperation) + { + printf("%d: \n\t%s\n\t%s\n", + pNdbOperation->getNdbError(), + pNdbOperation->getNdbErrorString(), + "NdbOperation"); + pNdb->closeTransaction(pNdbConnection); + delete pNdb; + } + catch(NdbSchemaCon* pNdbSchemaCon) + { + printf("%d: \n\t%s\n\t%s\n", + pNdbSchemaCon->getNdbError(), + pNdbSchemaCon->getNdbErrorString(), + "pNdbSchemaCon"); + pNdb->closeSchemaTransaction(pNdbSchemaCon); + delete pNdb; + } + catch(NdbSchemaOp* pNdbSchemaOp) + { + printf("%d: \n\t%s\n\t%s\n", + pNdbSchemaOp->getNdbError(), + pNdbSchemaOp->getNdbErrorString(), + "pNdbSchemaOp"); + pNdb->closeTransaction(pNdbConnection); + delete pNdb; + } +} + + +int _tmain(int argc, _TCHAR* argv[]) +{ + long nNumThreads=4; + long nSeed = 0; + long nInsert = 0; + bool bStoredTable = true; + if(lstrcmp(argv[1],_T("/?")) == 0) + { + _tprintf(_T("InsertRecs [No.Of Threads] [Record Seed No.] [Init no. of rec.] [Stored?]\n")); + return 0; + } + + if(argc > 1) + nNumThreads = _ttol(argv[1]); + else + nNumThreads = 4; + if (argc > 2) + nSeed = _ttol(argv[2]); + _tprintf(_T("Num of Threads = %d, Seed = %d"), nNumThreads, nSeed); + + if(argc>3) + nInsert = _ttol(argv[3]); + if(argc>4) + bStoredTable = (_ttol(argv[4])!=0); + + long nNumCallsProcessed = 0; + + SetConsoleCtrlHandler(ConsoleCtrlHandler,true); + hShutdownEvent = CreateEvent(NULL,TRUE,FALSE,NULL); + + // initiate windows sockets + WORD wVersionRequested; + WSADATA wsaData; + int err; + wVersionRequested = MAKEWORD( 2, 2 ); + err = WSAStartup( wVersionRequested, &wsaData ); + if ( err != 0 ) { + _tprintf(_T("could not find a usable WinSock DLL\n")); + return 0; + } + if ( LOBYTE( wsaData.wVersion ) != 2 + || HIBYTE( wsaData.wVersion ) != 2 ) + { + _tprintf(_T("could not find a usable WinSock DLL\n")); + WSACleanup(); + return 0; + } + + Ndb* pNdb = new Ndb("TEST_DB"); + if(!pNdb) + { + _tprintf(_T("could not construct ndb\n")); + return 0; + } + if(pNdb->init(1) + || pNdb->waitUntilReady()) + { + _tprintf(_T("could not initialize ndb\n")); + return 0; + } + + if(nInsert>0) + { + Initialize(pNdb, nInsert, bStoredTable); + } + + if(nNumThreads>0) + { + _tprintf(_T("creating %d threads\n"), nNumThreads); + DWORD dwStartTime = GetTickCount(); + + DWORD dwThreadID = 0; + HANDLE hThreads[50]; + + struct _ParamStruct params[50]; + + for(int ij=0;ijload_const_u32(1, compare_value) != 0) + return NDBT_FAILED; + + if (pOp->read_attr("KOL2", 2) != 0) + return NDBT_FAILED; + + if (pOp->branch_lt(1, 2, 0) != 0) + return NDBT_FAILED; + + if (pOp->interpret_exit_nok() != 0) + return NDBT_FAILED; + + if (pOp->def_label(0) != 0) + return NDBT_FAILED; + + if (pOp->interpret_exit_ok() != 0) + return NDBT_FAILED; + + return NDBT_OK; +} + +int LessThanFilter::verifyRecord(NDBT_ResultRow& row){ + NdbRecAttr* rec = row.attributeStore(1); + if (rec->u_32_value() < compare_value) + return NDBT_OK; + return NDBT_FAILED; +} + +int EqualFilter::filterOp(NdbOperation* pOp){ + + if (pOp->load_const_u32(1, compare_value) != 0) + return NDBT_FAILED; + + if (pOp->read_attr("KOL2", 2) != 0) + return NDBT_FAILED; + + if (pOp->branch_eq(1, 2, 0) != 0) + return NDBT_FAILED; + + if (pOp->interpret_exit_nok() != 0) + return NDBT_FAILED; + + if (pOp->def_label(0) != 0) + return NDBT_FAILED; + + if (pOp->interpret_exit_ok() != 0) + return NDBT_FAILED; + + return NDBT_OK; +} + +int EqualFilter::verifyRecord(NDBT_ResultRow& row){ + NdbRecAttr* rec = row.attributeStore(1); + if (rec->u_32_value() == compare_value) + return NDBT_OK; + return NDBT_FAILED; +} + +int NoFilter::filterOp(NdbOperation* pOp){ + return NDBT_OK; +} + +int NoFilter::verifyRecord(NDBT_ResultRow& row){ + // Check if this record should be in the result set or not + return NDBT_OK; +} + +#endif diff --git a/ndb/test/ndbapi/ScanFunctions.hpp b/ndb/test/ndbapi/ScanFunctions.hpp new file mode 100644 index 00000000000..36d01909861 --- /dev/null +++ b/ndb/test/ndbapi/ScanFunctions.hpp @@ -0,0 +1,392 @@ +/* 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 */ + +#include +#include + + + +struct Attrib { + int numAttribs; + int attribs[1024]; +}; +class AttribList { +public: + AttribList(){}; + ~AttribList(){ + for(size_t i = 0; i < attriblist.size(); i++){ + delete attriblist[i]; + } + }; + void buildAttribList(const NdbDictionary::Table* pTab); + Vector attriblist; +}; + + +// Functions that help out in testing that we may call +// scan functions in wrong order etc +// and receive a proper errormessage +class ScanFunctions { +public: + ScanFunctions(const NdbDictionary::Table& _tab) : tab(_tab){ + } + enum ActionType { + CloseWithoutStop, + NextScanWhenNoMore, + ExecuteScanWithOutOpenScan, + OnlyOneScanPerTrans, + OnlyOneOpBeforeOpenScan, + OnlyOpenScanOnce, + OnlyOneOpInScanTrans, + CheckInactivityTimeOut, + CheckInactivityBeforeClose , + NoCloseTransaction, + EqualAfterOpenScan + }; + + + int scanReadFunctions(Ndb* pNdb, + int records, + int parallelism, + ActionType action, + bool exclusive); +private: + const NdbDictionary::Table& tab; +}; + + +inline +int +ScanFunctions::scanReadFunctions(Ndb* pNdb, + int records, + int parallelism, + ActionType action, + bool exclusive){ + int retryAttempt = 0; + const int retryMax = 100; + int sleepTime = 10; + int check; + NdbConnection *pTrans; + NdbOperation *pOp; + + while (true){ + if (retryAttempt >= retryMax){ + g_err << "ERROR: has retried this operation " << retryAttempt + << " times, failing!" << endl; + return NDBT_FAILED; + } + + pTrans = pNdb->startTransaction(); + if (pTrans == NULL) { + const NdbError err = pNdb->getNdbError(); + if (err.status == NdbError::TemporaryError){ + ERR(err); + NdbSleep_MilliSleep(50); + retryAttempt++; + continue; + } + ERR(err); + return NDBT_FAILED; + } + + // Execute the scan without defining a scan operation + if(action != ExecuteScanWithOutOpenScan){ + + if (action == OnlyOneOpBeforeOpenScan){ + // There can only be one operation defined when calling openScan + NdbOperation* pOp3; + pOp3 = pTrans->getNdbOperation(tab.getName()); + if (pOp3 == NULL) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + } + + pOp = pTrans->getNdbOperation(tab.getName()); + if (pOp == NULL) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + if (exclusive == true) + check = pOp->openScanExclusive(parallelism); + else + check = pOp->openScanRead(parallelism); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + + if (action == OnlyOneScanPerTrans){ + // There can only be one operation in a scan transaction + NdbOperation* pOp4; + pOp4 = pTrans->getNdbOperation(tab.getName()); + if (pOp4 == NULL) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + } + + if (action == OnlyOpenScanOnce){ + // Call openScan one more time when it's already defined + check = pOp->openScanRead(parallelism); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + } + + if (action == OnlyOneOpInScanTrans){ + // Try to add another op to this scanTransaction + NdbOperation* pOp2; + pOp2 = pTrans->getNdbOperation(tab.getName()); + if (pOp2 == NULL) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + } + + + if (action==EqualAfterOpenScan){ + check = pOp->equal(tab.getColumn(0)->getName(), 10); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + } + + check = pOp->interpret_exit_ok(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + for(int a = 0; agetValue(tab.getColumn(a)->getName()) == NULL) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + } + } + check = pTrans->executeScan(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + + int abortCount = records / 10; + bool abortTrans = (action==CloseWithoutStop); + int eof; + int rows = 0; + eof = pTrans->nextScanResult(); + + while(eof == 0){ + rows++; + + if (abortCount == rows && abortTrans == true){ + g_info << "Scan is aborted after "<stopScan(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + } + + + pNdb->closeTransaction(pTrans); + return NDBT_OK; + } + + if(action == CheckInactivityTimeOut){ + if ((rows % (records / 10)) == 0){ + // Sleep for a long time before calling nextScanResult + if (sleepTime > 1) + sleepTime--; + g_info << "Sleeping "<nextScanResult(); + } + if (eof == -1) { + const NdbError err = pTrans->getNdbError(); + + if (err.status == NdbError::TemporaryError){ + ERR(err); + + // Be cruel, call nextScanResult after error + for(int i=0; i<10; i++){ + eof =pTrans->nextScanResult(); + if(eof == 0){ + g_err << "nextScanResult returned eof = " << eof << endl + << " That is an error when there are no more records" << endl; + return NDBT_FAILED; + } + } + // Be cruel end + + pNdb->closeTransaction(pTrans); + NdbSleep_MilliSleep(50); + retryAttempt++; + g_info << "Starting over" << endl; + + // If test is CheckInactivityTimeOut + // error 296 is expected + if ((action == CheckInactivityTimeOut) && + (err.code == 296)) + return NDBT_OK; + + continue; + } + ERR(err); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + if (action == NextScanWhenNoMore){ + g_info << "Calling nextScanresult when there are no more records" << endl; + for(int i=0; i<10; i++){ + eof =pTrans->nextScanResult(); + if(eof == 0){ + g_err << "nextScanResult returned eof = " << eof << endl + << " That is an error when there are no more records" << endl; + return NDBT_FAILED; + } + } + + } + if(action ==CheckInactivityBeforeClose){ + // Sleep for a long time before calling close + g_info << "NdbSleep_SecSleep(5) before close transaction" << endl; + NdbSleep_SecSleep(5); + } + if(action == NoCloseTransaction) + g_info << "Forgetting to close transaction" << endl; + else + pNdb->closeTransaction(pTrans); + + g_info << rows << " rows have been read" << endl; + if (records != 0 && rows != records){ + g_err << "Check expected number of records failed" << endl + << " expected=" << records <<", " << endl + << " read=" << rows << endl; + return NDBT_FAILED; + } + + return NDBT_OK; + } + return NDBT_FAILED; + + +} + +void AttribList::buildAttribList(const NdbDictionary::Table* pTab){ + attriblist.clear(); + + Attrib* attr; + // Build attrib definitions that describes which attributes to read + // Try to build strange combinations, not just "all" or all PK's + + // Scan without reading any attributes + attr = new Attrib; + attr->numAttribs = 0; + attriblist.push_back(attr); + + for(int i = 1; i < pTab->getNoOfColumns(); i++){ + attr = new Attrib; + attr->numAttribs = i; + for(int a = 0; aattribs[a] = a; + attriblist.push_back(attr); + } + for(int i = pTab->getNoOfColumns()-1; i > 0; i--){ + attr = new Attrib; + attr->numAttribs = i; + for(int a = 0; aattribs[a] = a; + attriblist.push_back(attr); + } + for(int i = pTab->getNoOfColumns(); i > 0; i--){ + attr = new Attrib; + attr->numAttribs = pTab->getNoOfColumns() - i; + for(int a = 0; agetNoOfColumns() - i; a++) + attr->attribs[a] = pTab->getNoOfColumns()-a-1; + attriblist.push_back(attr); + } + for(int i = 1; i < pTab->getNoOfColumns(); i++){ + attr = new Attrib; + attr->numAttribs = pTab->getNoOfColumns() - i; + for(int a = 0; agetNoOfColumns() - i; a++) + attr->attribs[a] = pTab->getNoOfColumns()-a-1; + attriblist.push_back(attr); + } + for(int i = 1; i < pTab->getNoOfColumns(); i++){ + attr = new Attrib; + attr->numAttribs = 2; + for(int a = 0; a<2; a++){ + attr->attribs[a] = i%pTab->getNoOfColumns(); + } + attriblist.push_back(attr); + } + + // Last + attr = new Attrib; + attr->numAttribs = 1; + attr->attribs[0] = pTab->getNoOfColumns()-1; + attriblist.push_back(attr); + + // Last and first + attr = new Attrib; + attr->numAttribs = 2; + attr->attribs[0] = pTab->getNoOfColumns()-1; + attr->attribs[1] = 0; + attriblist.push_back(attr); + + // First and last + attr = new Attrib; + attr->numAttribs = 2; + attr->attribs[0] = 0; + attr->attribs[1] = pTab->getNoOfColumns()-1; + attriblist.push_back(attr); + +#if 1 + for(size_t i = 0; i < attriblist.size(); i++){ + + g_info << attriblist[i]->numAttribs << ": " ; + for(int a = 0; a < attriblist[i]->numAttribs; a++) + g_info << attriblist[i]->attribs[a] << ", "; + g_info << endl; + } +#endif + +} diff --git a/ndb/test/ndbapi/ScanInterpretTest.hpp b/ndb/test/ndbapi/ScanInterpretTest.hpp new file mode 100644 index 00000000000..3862de34111 --- /dev/null +++ b/ndb/test/ndbapi/ScanInterpretTest.hpp @@ -0,0 +1,528 @@ +/* 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 */ + +#ifndef SCAN_INTERPRET_TEST_HPP +#define SCAN_INTERPRET_TEST_HPP + +#include "ScanFilter.hpp" + +class ScanInterpretTest { +public: + ScanInterpretTest(const NdbDictionary::Table& _tab, + const NdbDictionary::Table& _restab) : + tab(_tab), + restab(_restab), + row(_tab){ + } + + int scanRead(Ndb*, + int records, + int parallelism, + ScanFilter& filter); + int scanReadVerify(Ndb*, + int records, + int parallelism, + ScanFilter& filter); + + int addRowToInsert(Ndb* pNdb, + NdbConnection* pInsTrans); + int addRowToCheckTrans(Ndb* pNdb, + NdbConnection* pCheckTrans); +private: + const NdbDictionary::Table& tab; + const NdbDictionary::Table& restab; + NDBT_ResultRow row; + +}; + + +inline +int +ScanInterpretTest::addRowToInsert(Ndb* pNdb, + NdbConnection* pInsTrans){ + + NdbOperation* pOp = + pInsTrans->getNdbOperation(restab.getName()); + if (pOp == NULL) { + ERR(pInsTrans->getNdbError()); + pNdb->closeTransaction(pInsTrans); + return NDBT_FAILED; + } + + if( pOp->insertTuple() == -1 ) { + ERR(pInsTrans->getNdbError()); + pNdb->closeTransaction(pInsTrans); + return NDBT_FAILED; + } + + // Copy all attribute to the new operation + for (int a = 0; agetType()){ + case NdbDictionary::Column::Char: + case NdbDictionary::Column::Varchar: + case NdbDictionary::Column::Binary: + case NdbDictionary::Column::Varbinary:{ + check = pOp->setValue( attr->getName(), + reca->aRef()); + break; + } + case NdbDictionary::Column::Int:{ + check = pOp->setValue( attr->getName(), + reca->int32_value()); + } + break; + case NdbDictionary::Column::Bigint:{ + check = pOp->setValue( attr->getName(), + reca->int64_value()); + } + break; + case NdbDictionary::Column::Unsigned:{ + check = pOp->setValue( attr->getName(), + reca->u_32_value()); + } + break; + case NdbDictionary::Column::Bigunsigned:{ + check = pOp->setValue( attr->getName(), + reca->u_64_value()); + } + break; + case NdbDictionary::Column::Float: + check = pOp->setValue( attr->getName(), + reca->float_value()); + + break; + default: + check = -1; + break; + } + if(check != 0){ + ERR(pInsTrans->getNdbError()); + pNdb->closeTransaction(pInsTrans); + return NDBT_FAILED; + } + } + + return NDBT_OK; +} + +inline +int +ScanInterpretTest::addRowToCheckTrans(Ndb* pNdb, + NdbConnection* pCheckTrans){ + + NdbOperation* pOp = + pCheckTrans->getNdbOperation(restab.getName()); + if (pOp == NULL) { + ERR(pNdb->getNdbError()); + return NDBT_FAILED; + } + + if(pOp->readTuple() != 0) { + ERR(pNdb->getNdbError()); + return NDBT_FAILED; + } + + // Copy pk attribute's to the new operation + for (int a = 0; agetPrimaryKey() == true){ + NdbRecAttr* reca = row.attributeStore(a); + int check = -1; + switch (attr->getType()){ + case NdbDictionary::Column::Char: + case NdbDictionary::Column::Varchar: + case NdbDictionary::Column::Binary: + case NdbDictionary::Column::Varbinary:{ + check = pOp->equal( attr->getName(), + reca->aRef()); + break; + } + case NdbDictionary::Column::Int:{ + check = pOp->equal( attr->getName(), + reca->int32_value()); + } + break; + case NdbDictionary::Column::Bigint:{ + check = pOp->equal( attr->getName(), + reca->int64_value()); + } + break; + case NdbDictionary::Column::Unsigned:{ + check = pOp->equal( attr->getName(), + reca->u_32_value()); + } + break; + case NdbDictionary::Column::Bigunsigned:{ + check = pOp->equal( attr->getName(), + reca->u_64_value()); + } + break; + default: + check = -1; + break; + } + if(check != 0){ + ERR(pNdb->getNdbError()); + return NDBT_FAILED; + } + } + } + + return NDBT_OK; +} + +inline +int +ScanInterpretTest::scanRead(Ndb* pNdb, + int records, + int parallelism, + ScanFilter& filter){ + int retryAttempt = 0; + int retryMax = 100; + int check; + NdbConnection *pTrans; + NdbOperation *pOp; + + while (true){ + + if (retryAttempt >= retryMax){ + ndbout << "ERROR: has retried this operation " << retryAttempt + << " times, failing!" << endl; + return NDBT_FAILED; + } + + pTrans = pNdb->startTransaction(); + if (pTrans == NULL) { + const NdbError err = pNdb->getNdbError(); + if (err.status == NdbError::TemporaryError){ + ERR(err); + NdbSleep_MilliSleep(50); + retryAttempt++; + continue; + } + ERR(err); + return NDBT_FAILED; + } + + pOp = pTrans->getNdbOperation(tab.getName()); + if (pOp == NULL) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp->openScanRead(parallelism); + //check = pOp->openScanExclusive(parallelism); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + if (filter.filterOp(pOp) != 0){ + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + // Read all attributes + for(int a = 0; agetValue(tab.getColumn(a)->getName())) == 0) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + } + check = pTrans->executeScan(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + int eof; + int rows = 0; + NdbConnection* pInsTrans; + + while((eof = pTrans->nextScanResult(true)) == 0){ + pInsTrans = pNdb->startTransaction(); + if (pInsTrans == NULL) { + const NdbError err = pNdb->getNdbError(); + ERR(err); + return NDBT_FAILED; + } + do { + rows++; + if (addRowToInsert(pNdb, pInsTrans) != 0){ + pNdb->closeTransaction(pTrans); + pNdb->closeTransaction(pInsTrans); + return NDBT_FAILED; + } + } while((eof = pTrans->nextScanResult(false)) == 0); + + check = pInsTrans->execute(Commit); + if( check == -1 ) { + const NdbError err = pInsTrans->getNdbError(); + ERR(err); + pNdb->closeTransaction(pInsTrans); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + pNdb->closeTransaction(pInsTrans); + + } + if (eof == -1) { + const NdbError err = pTrans->getNdbError(); + + if (err.status == NdbError::TemporaryError){ + ERR(err); + pNdb->closeTransaction(pTrans); + NdbSleep_MilliSleep(50); + retryAttempt++; + continue; + } + ERR(err); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + pNdb->closeTransaction(pTrans); + + g_info << rows << " rows have been scanned" << endl; + + return NDBT_OK; + } + return NDBT_FAILED; +} + +inline +int +ScanInterpretTest::scanReadVerify(Ndb* pNdb, + int records, + int parallelism, + ScanFilter& filter){ + int retryAttempt = 0; + const int retryMax = 100; + int check; + NdbConnection *pTrans; + NdbOperation *pOp; + + while (true){ + + if (retryAttempt >= retryMax){ + ndbout << "ERROR: has retried this operation " << retryAttempt + << " times, failing!" << endl; + return NDBT_FAILED; + } + + pTrans = pNdb->startTransaction(); + if (pTrans == NULL) { + const NdbError err = pNdb->getNdbError(); + if (err.status == NdbError::TemporaryError){ + ERR(err); + NdbSleep_MilliSleep(50); + retryAttempt++; + continue; + } + ERR(err); + return NDBT_FAILED; + } + + + pOp = pTrans->getNdbOperation(tab.getName()); + if (pOp == NULL) { if (pOp->getValue("KOL2") == 0){ + ERR(pNdb->getNdbError()); + return NDBT_FAILED; + } + + + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp->openScanRead(parallelism); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp->interpret_exit_ok(); + if (check == -1) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + + // Read all attributes + for(int a = 0; agetValue(tab.getColumn(a)->getName())) == 0) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + } + check = pTrans->executeScan(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + int eof; + int rows = 0; + int rowsNoExist = 0; + int rowsExist = 0; + int existingRecordsNotFound = 0; + int nonExistingRecordsFound = 0; + + + NdbConnection* pExistTrans; + NdbConnection* pNoExistTrans; + + while((eof = pTrans->nextScanResult(true)) == 0){ + pExistTrans = pNdb->startTransaction(); + if (pExistTrans == NULL) { + const NdbError err = pNdb->getNdbError(); + ERR(err); + return NDBT_FAILED; + } + pNoExistTrans = pNdb->startTransaction(); + if (pNoExistTrans == NULL) { + const NdbError err = pNdb->getNdbError(); + ERR(err); + return NDBT_FAILED; + } + do { + rows++; + if (filter.verifyRecord(row) == NDBT_OK){ + rowsExist++; + if (addRowToCheckTrans(pNdb, pExistTrans) != 0){ + pNdb->closeTransaction(pTrans); + pNdb->closeTransaction(pExistTrans); + pNdb->closeTransaction(pNoExistTrans); + return NDBT_FAILED; + } + }else{ + rowsNoExist++; + if (addRowToCheckTrans(pNdb, pNoExistTrans) != 0){ + pNdb->closeTransaction(pTrans); + pNdb->closeTransaction(pExistTrans); + pNdb->closeTransaction(pNoExistTrans); + return NDBT_FAILED; + } + } + } while((eof = pTrans->nextScanResult(false)) == 0); + + + // Execute the transaction containing reads of + // all the records that should be in the result table + check = pExistTrans->execute(Commit); + if( check == -1 ) { + const NdbError err = pExistTrans->getNdbError(); + ERR(err); + if (err.code != 626){ + pNdb->closeTransaction(pExistTrans); + pNdb->closeTransaction(pNoExistTrans); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + }else{ + // Some of the records expected to be found wasn't + // there + existingRecordsNotFound = 1; + } + } + pNdb->closeTransaction(pExistTrans); + + // Execute the transaction containing reads of + // all the records that should NOT be in the result table + check = pNoExistTrans->execute(Commit, CommitAsMuchAsPossible); + if( check == -1 ) { + const NdbError err = pNoExistTrans->getNdbError(); + // The transactions error code should be zero + if (err.code != 626){ + ERR(err); + pNdb->closeTransaction(pNoExistTrans); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + // Loop through the no existing transaction and check that no + // operations where successful + const NdbOperation* pOp2 = NULL; + while ((pOp2 = pNoExistTrans->getNextCompletedOperation(pOp2)) != NULL){ + const NdbError err = pOp2->getNdbError(); + if (err.code != 626){ + ndbout << "err.code = " << err.code<< endl; + nonExistingRecordsFound = 1; + } + } + } + + pNdb->closeTransaction(pNoExistTrans); + + + } + if (eof == -1) { + const NdbError err = pTrans->getNdbError(); + + if (err.status == NdbError::TemporaryError){ + ERR(err); + pNdb->closeTransaction(pTrans); + NdbSleep_MilliSleep(50); + retryAttempt++; + continue; + } + ERR(err); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + int testResult = NDBT_OK; + int rowsResult = 0; + UtilTransactions utilTrans(restab); + if (utilTrans.selectCount(pNdb, + 240, + &rowsResult) != 0){ + return NDBT_FAILED; + } + if (existingRecordsNotFound == 1){ + ndbout << "!!! Expected records not found" << endl; + testResult = NDBT_FAILED; + } + if (nonExistingRecordsFound == 1){ + ndbout << "!!! Unxpected records found" << endl; + testResult = NDBT_FAILED; + } + ndbout << rows << " rows scanned(" + << rowsExist << " found, " << rowsResult<<" expected)" << endl; + if (rowsResult != rowsExist){ + ndbout << "!!! Number of rows in result table different from expected" << endl; + testResult = NDBT_FAILED; + } + + return testResult; + } + return NDBT_FAILED; +} + +#endif diff --git a/ndb/test/ndbapi/TraceNdbApi.cpp b/ndb/test/ndbapi/TraceNdbApi.cpp new file mode 100644 index 00000000000..bd43b15f2e6 --- /dev/null +++ b/ndb/test/ndbapi/TraceNdbApi.cpp @@ -0,0 +1,543 @@ +/* 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 */ + +#include +#include +#include + +#include "TraceNdbApi.hpp" + + +int g_nParamTrace; +NdbMutex* g_pNdbMutexTrace = 0; + + +void TraceBegin(void) +{ + if(!g_pNdbMutexTrace) + { + g_pNdbMutexTrace = NdbMutex_Create(); + } + NdbMutex_Lock(g_pNdbMutexTrace); + g_nParamTrace = 0; +} + +void TraceEnd(void) +{ + ndbout << endl; + g_nParamTrace = 0; + NdbMutex_Unlock(g_pNdbMutexTrace); +} + +void TraceMethod(const char* szMethod) +{ + ndbout << "->" << szMethod << "("; + g_nParamTrace = 0; +} + +void TraceParamComma(void) +{ + if(g_nParamTrace) + { + ndbout << ", "; + } + ++g_nParamTrace; +} + +void TraceNdb(Ndb* pNdb) +{ + TraceParamComma(); + ndbout << "((Ndb*)" << hex << (Uint32)pNdb << ")"; +} + +void TraceNdbSchemaCon(NdbSchemaCon* pNdbSchemaCon) +{ + TraceParamComma(); + ndbout << "((NdbSchemaCon*)" << hex << (Uint32)pNdbSchemaCon << ")"; +} + +void TraceNdbSchemaOp(NdbSchemaOp* pNdbSchemaOp) +{ + TraceParamComma(); + ndbout << "((NdbSchemaOp*)" << hex << (Uint32)pNdbSchemaOp << ")"; +} + +void TraceNdbConnection(const NdbConnection* pNdbConnection) +{ + TraceParamComma(); + ndbout << "((NdbConnection*)" << hex << (Uint32)pNdbConnection << ")"; +} + +void TraceNdbOperation(NdbOperation* pNdbOperation) +{ + TraceParamComma(); + ndbout << "((NdbOperation*)" << hex << (Uint32)pNdbOperation << ")"; +} + +void TraceNdbIndexOperation(NdbIndexOperation* pNdbIndexOperation) +{ + TraceParamComma(); + ndbout << "((NdbIndexOperation*)" << hex << (Uint32)pNdbIndexOperation << ")"; +} + +void TraceNdbRecAttr(NdbRecAttr* pNdbRecAttr) +{ + TraceParamComma(); + ndbout << "((NdbRecAttr*)" << hex << (Uint32)pNdbRecAttr << ")"; +} + +void TraceTable(Table* pTable) +{ + TraceParamComma(); + ndbout << "((Table*)" << hex << (Uint32)pTable << ")"; +} + +void TraceString(const char* szParam) +{ + TraceParamComma(); + ndbout << "\"" << szParam << "\""; +} + +void TraceInt(const int i) +{ + TraceParamComma(); + ndbout << "(int)" << dec << i; +} + +void TraceUint32(const Uint32 n) +{ + TraceParamComma(); + ndbout << "(Uint32)" << dec << n; +} + +void TraceKeyType(const KeyType aKeyType) +{ + TraceParamComma(); + switch(aKeyType) + { + case Undefined: ndbout << "Undefined"; break; + case NoKey: ndbout << "NoKey"; break; + case TupleKey: ndbout << "TupleKey"; break; + case TupleId: ndbout << "TupleId"; break; + default: ndbout << "(KeyType)" << aKeyType; break; + } +} + +void TraceExecType(const ExecType aExecType) +{ + switch(aExecType) + { + case NoExecTypeDef: ndbout << "NoExecTypeDef"; break; + case Prepare: ndbout << "Prepare"; break; + case NoCommit: ndbout << "NoCommit"; break; + case Commit: ndbout << "Commit"; break; + case Rollback: ndbout << "Rollback"; break; + default: ndbout << "(ExecType)" << aExecType; break; + } +} + + +void TraceNdbError(const NdbError& err) +{ + TraceParamComma(); + ndbout << "(NdbError)" << err; +} + + + +void TraceVoid(void) +{ + ndbout << "void"; +} + +void TraceReturn(void) +{ + ndbout << "); // return "; + g_nParamTrace = 0; +} + + +// TraceNdbSchemaOp + +int CTraceNdbSchemaOp::createTable(const char* aTableName) +{ + int i = NdbSchemaOp::createTable(aTableName); + TraceBegin(); + TraceNdbSchemaOp(this); + TraceMethod("createTable"); + TraceString(aTableName); + TraceReturn(); + TraceInt(i); + TraceEnd(); + return i; +} + +int CTraceNdbSchemaOp::createAttribute(const char* aAttrName, KeyType aTupleyKey) +{ + int i = NdbSchemaOp::createAttribute(aAttrName, aTupleyKey); + TraceBegin(); + TraceNdbSchemaOp(this); + TraceMethod("createAttribute"); + TraceString(aAttrName); + TraceKeyType(aTupleyKey); + TraceReturn(); + TraceInt(i); + TraceEnd(); + return i; +} + + + +// TraceNdbSchemaCon + +CTraceNdbSchemaOp* CTraceNdbSchemaCon::getNdbSchemaOp() +{ + NdbSchemaOp* pNdbSchemaOp = NdbSchemaCon::getNdbSchemaOp(); + TraceBegin(); + TraceNdbSchemaCon(this); + TraceMethod("getNdbSchemaOp"); + TraceReturn(); + TraceNdbSchemaOp(pNdbSchemaOp); + TraceEnd(); + return (CTraceNdbSchemaOp*)pNdbSchemaOp; +} + +int CTraceNdbSchemaCon::execute() +{ + int i = NdbSchemaCon::execute(); + TraceBegin(); + TraceNdbSchemaCon(this); + TraceMethod("execute"); + TraceReturn(); + TraceInt(i); + TraceEnd(); + return i; +} + + + +// TraceNdbRecAttr + +Uint32 CTraceNdbRecAttr::u_32_value() +{ + Uint32 n = NdbRecAttr::u_32_value(); + TraceBegin(); + TraceNdbRecAttr(this); + TraceMethod("u_32_value"); + TraceReturn(); + TraceUint32(n); + TraceEnd(); + return n; +} + + + +// TraceNdbOperation + +int CTraceNdbOperation::insertTuple() +{ + int i = NdbOperation::insertTuple(); + TraceBegin(); + TraceNdbOperation(this); + TraceMethod("insertTuple"); + TraceReturn(); + TraceInt(i); + TraceEnd(); + return i; +} + +int CTraceNdbOperation::updateTuple() +{ + int i = NdbOperation::updateTuple(); + TraceBegin(); + TraceNdbOperation(this); + TraceMethod("updateTuple"); + TraceReturn(); + TraceInt(i); + TraceEnd(); + return i; +} + +int CTraceNdbOperation::interpretedUpdateTuple() +{ + int i = NdbOperation::interpretedUpdateTuple(); + TraceBegin(); + TraceNdbOperation(this); + TraceMethod("interpretedUpdateTuple"); + TraceReturn(); + TraceInt(i); + TraceEnd(); + return i; +} + +int CTraceNdbOperation::readTuple() +{ + int i = NdbOperation::readTuple(); + TraceBegin(); + TraceNdbOperation(this); + TraceMethod("readTuple"); + TraceReturn(); + TraceInt(i); + TraceEnd(); + return i; +} + + +int CTraceNdbOperation::readTupleExclusive() +{ + int i = NdbOperation::readTupleExclusive(); + TraceBegin(); + TraceNdbOperation(this); + TraceMethod("readTupleExclusive"); + TraceReturn(); + TraceInt(i); + TraceEnd(); + return i; +} + + +int CTraceNdbOperation::deleteTuple() +{ + int i = NdbOperation::deleteTuple(); + TraceBegin(); + TraceNdbOperation(this); + TraceMethod("deleteTuple"); + TraceReturn(); + TraceInt(i); + TraceEnd(); + return i; +} + +int CTraceNdbOperation::equal(const char* anAttrName, Uint32 aValue) +{ + int i = NdbOperation::equal(anAttrName, aValue); + TraceBegin(); + TraceNdbOperation(this); + TraceMethod("equal"); + TraceString(anAttrName); + TraceUint32(aValue); + TraceReturn(); + TraceInt(i); + TraceEnd(); + return i; +} + +int CTraceNdbOperation::setValue(const char* anAttrName, Uint32 aValue) +{ + int i = NdbOperation::setValue(anAttrName, aValue); + TraceBegin(); + TraceNdbOperation(this); + TraceMethod("setValue"); + TraceString(anAttrName); + TraceUint32(aValue); + TraceReturn(); + TraceInt(i); + TraceEnd(); + return i; +} + +int CTraceNdbOperation::incValue(const char* anAttrName, Uint32 aValue) +{ + int i = NdbOperation::incValue(anAttrName, aValue); + TraceBegin(); + TraceNdbOperation(this); + TraceMethod("incValue"); + TraceString(anAttrName); + TraceUint32(aValue); + TraceReturn(); + TraceInt(i); + TraceEnd(); + return i; +} + +CTraceNdbRecAttr* CTraceNdbOperation::getValue(const char* anAttrName) +{ + NdbRecAttr* pNdbRecAttr = NdbOperation::getValue(anAttrName); + TraceBegin(); + TraceNdbOperation(this); + TraceMethod("getValue"); + TraceString(anAttrName); + TraceReturn(); + TraceNdbRecAttr(pNdbRecAttr); + TraceEnd(); + return (CTraceNdbRecAttr*)pNdbRecAttr; +} + + +// TraceNdbIndexOperation + +int CTraceNdbIndexOperation::equal(const char* anAttrName, Uint32 aValue) +{ + int i = NdbIndexOperation::equal(anAttrName, aValue); + TraceBegin(); + TraceNdbIndexOperation(this); + TraceMethod("equal"); + TraceString(anAttrName); + TraceUint32(aValue); + TraceReturn(); + TraceInt(i); + TraceEnd(); + return i; +} + + +int CTraceNdbIndexOperation::incValue(const char* anAttrName, Uint32 aValue) +{ + int i = NdbIndexOperation::incValue(anAttrName, aValue); + TraceBegin(); + TraceNdbIndexOperation(this); + TraceMethod("incValue"); + TraceString(anAttrName); + TraceUint32(aValue); + TraceReturn(); + TraceInt(i); + TraceEnd(); + return i; +} + + +CTraceNdbRecAttr* CTraceNdbIndexOperation::getValue(const char* anAttrName) +{ + NdbRecAttr* pNdbRecAttr = NdbIndexOperation::getValue(anAttrName); + TraceBegin(); + TraceNdbIndexOperation(this); + TraceMethod("getValue"); + TraceString(anAttrName); + TraceReturn(); + TraceNdbRecAttr(pNdbRecAttr); + TraceEnd(); + return (CTraceNdbRecAttr*)pNdbRecAttr; +} + + +// TraceNdbConnection + +CTraceNdbOperation* CTraceNdbConnection::getNdbOperation(const char* aTableName) +{ + NdbOperation* pNdbOperation = NdbConnection::getNdbOperation(aTableName); + TraceBegin(); + TraceNdbConnection(this); + TraceMethod("getNdbOperation"); + TraceString(aTableName); + TraceReturn(); + TraceNdbOperation(pNdbOperation); + TraceEnd(); + return (CTraceNdbOperation*)pNdbOperation; +} + +CTraceNdbIndexOperation* CTraceNdbConnection::getNdbIndexOperation(const char* anIndexName, const char* aTableName) +{ + NdbIndexOperation* pNdbIndexOperation = NdbConnection::getNdbIndexOperation(anIndexName, aTableName); + TraceBegin(); + TraceNdbConnection(this); + TraceMethod("getNdbIndexOperation"); + TraceString(anIndexName); + TraceString(aTableName); + TraceReturn(); + TraceNdbIndexOperation(pNdbIndexOperation); + TraceEnd(); + return (CTraceNdbIndexOperation*)pNdbIndexOperation; +} + +int CTraceNdbConnection::execute(ExecType aTypeOfExec) +{ + int i = NdbConnection::execute(aTypeOfExec); + TraceBegin(); + TraceNdbConnection(this); + TraceMethod("execute"); + TraceExecType(aTypeOfExec); + TraceReturn(); + TraceInt(i); + TraceEnd(); + return i; +} + +const NdbError & CTraceNdbConnection::getNdbError(void) const +{ + const NdbError& err = NdbConnection::getNdbError(); + TraceBegin(); + TraceNdbConnection(this); + TraceMethod("getNdbError"); + TraceReturn(); + TraceNdbError(err); + TraceEnd(); + return err; +} + + + +// TraceNdb + +CTraceNdb::CTraceNdb(const char* aDataBase) +: Ndb(aDataBase) +{ + TraceBegin(); + TraceNdb(this); + TraceMethod("Ndb"); + TraceString(aDataBase); + TraceReturn(); + TraceVoid(); + TraceEnd(); +} + +CTraceNdbSchemaCon* CTraceNdb::startSchemaTransaction() +{ + NdbSchemaCon* pNdbSchemaCon = Ndb::startSchemaTransaction(); + TraceBegin(); + TraceNdb(this); + TraceMethod("startSchemaTransaction"); + TraceReturn(); + TraceNdbSchemaCon(pNdbSchemaCon); + TraceEnd(); + return (CTraceNdbSchemaCon*)pNdbSchemaCon; +} + +void CTraceNdb::closeSchemaTransaction(CTraceNdbSchemaCon* aSchemaCon) +{ + Ndb::closeSchemaTransaction(aSchemaCon); + TraceBegin(); + TraceNdb(this); + TraceMethod("closeSchemaTransaction"); + TraceReturn(); + TraceVoid(); + TraceEnd(); +} + +CTraceNdbConnection* CTraceNdb::startTransaction() +{ + NdbConnection* pNdbConnection = Ndb::startTransaction(); + TraceBegin(); + TraceNdb(this); + TraceMethod("startTransaction"); + TraceReturn(); + TraceNdbConnection(pNdbConnection); + TraceEnd(); + return (CTraceNdbConnection*)pNdbConnection; +} + +void CTraceNdb::closeTransaction(CTraceNdbConnection* aConnection) +{ + Ndb::closeTransaction(aConnection); + TraceBegin(); + TraceNdb(this); + TraceMethod("closeTransaction"); + TraceNdbConnection(aConnection); + TraceReturn(); + TraceVoid(); + TraceEnd(); +} + + diff --git a/ndb/test/ndbapi/VerifyNdbApi.cpp b/ndb/test/ndbapi/VerifyNdbApi.cpp new file mode 100644 index 00000000000..79645827e2c --- /dev/null +++ b/ndb/test/ndbapi/VerifyNdbApi.cpp @@ -0,0 +1,151 @@ +/* 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 */ + + +#include +#include +#include + +#include "VerifyNdbApi.hpp" + + +NdbMutex* g_pNdbMutexVerify = 0; + + +void VerifyBegin(void) +{ + if(!g_pNdbMutexVerify) + { + g_pNdbMutexVerify = NdbMutex_Create(); + } + NdbMutex_Lock(g_pNdbMutexVerify); +} + +void VerifyEnd(void) +{ + NdbMutex_Unlock(g_pNdbMutexVerify); +} + + + +void CVerifyNdbSchemaOp::VerifyIntError(const int i, const char* szMethod) +{ + VerifyBegin(); + ndbout << "NdbSchemaOp::" << szMethod << " returned " << dec << i; + ndbout << " : " << dec << getNdbError().code << " : " << getNdbError().message << endl; + VerifyEnd(); +} + + +void CVerifyNdbSchemaCon::VerifyIntError(const int i, const char* szMethod) +{ + VerifyBegin(); + ndbout << "NdbSchemaCon::" << szMethod << " returned " << dec << i; + ndbout << " : " << dec << getNdbError().code << " : " << getNdbError().message << endl; + VerifyEnd(); +} + + +void CVerifyNdbSchemaCon::VerifyPtrError(void* p, const char* szMethod) +{ + VerifyBegin(); + ndbout << "NdbSchemaCon::" << szMethod << " returned " << hex << (Uint32)p; + ndbout << " : " << dec << getNdbError().code << " : " << getNdbError().message << endl; + VerifyEnd(); +} + + +void CVerifyNdbRecAttr::VerifyValueError(const int iNull, const char* szMethod) +{ + VerifyBegin(); + ndbout << "NdbRecAttr::" << szMethod << " : isNULL() returned " << dec << iNull; + ndbout << endl; + VerifyEnd(); +} + + +void CVerifyNdbOperation::VerifyIntError(const int i, const char* szMethod) +{ + VerifyBegin(); + ndbout << "NdbOperation::" << szMethod << " returned " << dec << i; + ndbout << " : " << dec << getNdbError().code << " : " << getNdbError().message << endl; + VerifyEnd(); +} + + +void CVerifyNdbOperation::VerifyPtrError(void* p, const char* szMethod) +{ + VerifyBegin(); + ndbout << "NdbOperation::" << szMethod << " returned " << hex << (Uint32)p; + ndbout << " : " << dec << getNdbError().code << " : " << getNdbError().message << endl; + VerifyEnd(); +} + + +void CVerifyNdbIndexOperation::VerifyIntError(const int i, const char* szMethod) +{ + VerifyBegin(); + ndbout << "NdbIndexOperation::" << szMethod << " returned " << dec << i; + ndbout << " : " << dec << getNdbError().code << " : " << getNdbError().message << endl; + VerifyEnd(); +} + + +void CVerifyNdbIndexOperation::VerifyPtrError(void* p, const char* szMethod) +{ + VerifyBegin(); + ndbout << "NdbIndexOperation::" << szMethod << " returned " << hex << (Uint32)p; + ndbout << " : " << dec << getNdbError().code << " : " << getNdbError().message << endl; + VerifyEnd(); +} + + +void CVerifyNdbConnection::VerifyIntError(const int i, const char* szMethod) +{ + VerifyBegin(); + ndbout << "NdbConnection::" << szMethod << " returned " << dec << i; + ndbout << " : " << dec << getNdbError().code << " : " << getNdbError().message << endl; + VerifyEnd(); +} + + +void CVerifyNdbConnection::VerifyPtrError(void* p, const char* szMethod) +{ + VerifyBegin(); + ndbout << "NdbConnection::" << szMethod << " returned " << hex << (Uint32)p; + ndbout << " : " << dec << getNdbError().code << " : " << getNdbError().message << endl; + VerifyEnd(); +} + + +void CVerifyNdb::VerifyPtrError(void* p, const char* szMethod) +{ + VerifyBegin(); + ndbout << "Ndb::" << szMethod << " returned " << hex << (Uint32)p; + ndbout << " : " << dec << getNdbError().code << " : " << getNdbError().message << endl; + VerifyEnd(); +} + + +void CVerifyNdb::VerifyVoidError(const int iCode, const char* szMethod) +{ + VerifyBegin(); + ndbout << "Ndb::" << szMethod << " : getNdbError().code returned " << dec << iCode; + ndbout << " : " << getNdbError().message << endl; + VerifyEnd(); +} + + diff --git a/ndb/test/ndbapi/acid.cpp b/ndb/test/ndbapi/acid.cpp new file mode 100644 index 00000000000..49961531a1c --- /dev/null +++ b/ndb/test/ndbapi/acid.cpp @@ -0,0 +1,561 @@ +/* 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 */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#define TRACE +#define DEBUG +//#define RELEASE +#define NODE_REC // epaulsa: introduces pointer checks to help 'acid' keep core +// during node recovery + +#ifdef TRACE + +#define VerifyMethodInt(c, m) (ReportMethodInt(c->m, c, #c, #m, __FILE__, __LINE__)) +#define VerifyMethodPtr(v, c, m) (v=ReportMethodPtr(c->m, c, #v, #c, #m, __FILE__, __LINE__)) +#define VerifyMethodVoid(c, m) (c->m, ReportMethodVoid(c, #c, #m, __FILE__, __LINE__)) + +int ReportMethodInt(int iRes, NdbConnection* pNdbConnection, const char* szClass, const char* szMethod, const char* szFile, const int iLine) +{ + ndbout << szFile << "(" << iLine << ") : "; + ndbout << szClass << "->" << szMethod << " return " << iRes << " : "; + ndbout << pNdbConnection->getNdbError(); + NdbOperation* pNdbOperation = pNdbConnection->getNdbErrorOperation(); + if(pNdbOperation) { + ndbout << " : " << pNdbOperation->getNdbError(); + } + ndbout << " : " << pNdbConnection->getNdbErrorLine(); + ndbout << endl; + return iRes; +} + +template +int ReportMethodInt(int iRes, C* pC, const char* szClass, const char* szMethod, const char* szFile, const int iLine) +{ + ndbout << szFile << "(" << iLine << ") : "; + ndbout << szClass << "->" << szMethod << " return " << iRes << " : "; + ndbout << pC->getNdbError(); + ndbout << endl; + return iRes; +} + +template +R* ReportMethodPtr(R* pR, C* pC, const char* szVariable, const char* szClass, const char* szMethod, const char* szFile, const int iLine) +{ + ndbout << szFile << "(" << iLine << ") : "; + ndbout << szVariable << " = " << szClass << "->" << szMethod << " return " << (long)(void*)pR << " : "; + ndbout << pC->getNdbError(); + ndbout << endl; + return pR; +} + +template +void ReportMethodVoid(C* pC, const char* szClass, const char* szMethod, const char* szFile, const int iLine) +{ + ndbout << szFile << "(" << iLine << ") : "; + ndbout << szClass << "->" << szMethod << " : "; + ndbout << pC->getNdbError(); + ndbout << endl; +} +#endif /* TRACE */ + + +#ifdef DEBUG + +#define VerifyMethodInt(c, m) (ReportMethodInt(c->m, c, #c, #m, __FILE__, __LINE__)) +#define VerifyMethodPtr(v, c, m) (v=ReportMethodPtr(c->m, c, #v, #c, #m, __FILE__, __LINE__)) +#define VerifyMethodVoid(c, m) (c->m, ReportMethodVoid(c, #c, #m, __FILE__, __LINE__)) + +int ReportMethodInt(int iRes, NdbConnection* pNdbConnection, const char* szClass, const char* szMethod, const char* szFile, const int iLine) +{ + if(iRes<0) { + ndbout << szFile << "(" << iLine << ") : "; + ndbout << szClass << "->" << szMethod << " return " << iRes << " : "; + ndbout << pNdbConnection->getNdbError(); + NdbOperation* pNdbOperation = pNdbConnection->getNdbErrorOperation(); + if(pNdbOperation) { + ndbout << " : " << pNdbOperation->getNdbError(); + } + ndbout << " : " << pNdbConnection->getNdbErrorLine(); + ndbout << " : "; + ndbout << endl; + } + return iRes; +} + +template +int ReportMethodInt(int iRes, C* pC, const char* szClass, const char* szMethod, const char* szFile, const int iLine) +{ + if(iRes<0) { + ndbout << szFile << "(" << iLine << ") : "; + ndbout << szClass << "->" << szMethod << " return " << iRes << " : "; + ndbout << pC->getNdbError(); + ndbout << endl; + } + return iRes; +} + +template +R* ReportMethodPtr(R* pR, C* pC, const char* szVariable, const char* szClass, const char* szMethod, const char* szFile, const int iLine) +{ + if(!pR) { + ndbout << szFile << "(" << iLine << ") : "; + ndbout << szVariable << " = " << szClass << "->" << szMethod << " return " << " : "; + ndbout << pC->getNdbError(); + ndbout << endl; + } + return pR; +} + +template +void ReportMethodVoid(C* pC, const char* szClass, const char* szMethod, const char* szFile, const int iLine) +{ + if(pC->getNdbError().code) { + ndbout << szFile << "(" << iLine << ") : "; + ndbout << szClass << "->" << szMethod << " : "; + ndbout << pC->getNdbError(); + ndbout << endl; + } +} + + +#endif /* DEBUG */ + + +#ifdef RELEASE + +#define VerifyMethodInt(c, m) (c->m) +#define VerifyMethodPtr(v, c, m) (v=(c->m)) +#define VerifyMethodVoid(c, m) (c->m) + +int ReportMethodInt(int iRes, NdbConnection* pNdbConnection, const char* szClass, const char* szMethod, const char* szFile, const int iLine) +{ + if(iRes<0) { + ndbout << szFile << "(" << iLine << ") : "; + ndbout << szClass << "->" << szMethod << " return " << iRes << " : "; + ndbout << pNdbConnection->getNdbError(); + NdbOperation* pNdbOperation = pNdbConnection->getNdbErrorOperation(); + if(pNdbOperation) { + ndbout << " : " << pNdbOperation->getNdbError(); + } + ndbout << " : " << pNdbConnection->getNdbErrorLine(); + ndbout << endl; + } + return iRes; +} + +#endif /* RELEASE */ + +// epaulsa => +#ifndef NODE_REC +#define CHK_TR(p) +#else +#define CHK_TR(p) if(!p){ \ + ndbout <<"startTransaction failed, returning now." << endl ; \ + delete pNdb ; \ + pNdb = NULL ; \ + return 0 ; \ + } +#endif // NODE_REC +// <= epaulsa + +const char* c_szWarehouse = "WAREHOUSE"; +const char* c_szWarehouseNumber = "W_ID"; +const char* c_szWarehouseSum = "W_SUM"; +const char* c_szWarehouseCount = "W_CNT"; +const char* c_szDistrict = "DISTRICT"; +const char* c_szDistrictWarehouseNumber = "D_W_ID"; +const char* c_szDistrictNumber = "D_ID"; +const char* c_szDistrictSum = "D_SUM"; +const char* c_szDistrictCount = "D_CNT"; + +Uint32 g_nWarehouseCount = 10; +Uint32 g_nDistrictPerWarehouse = 10; +Uint32 g_nThreadCount = 1; +NdbMutex* g_pNdbMutex = 0; + +extern "C" void* NdbThreadFuncInsert(void* pArg) +{ + myRandom48Init((long int)NdbTick_CurrentMillisecond()); + unsigned nSucc = 0; + unsigned nFail = 0; + Ndb* pNdb = NULL ; + pNdb = new Ndb("TEST_DB"); + VerifyMethodInt(pNdb, init()); + VerifyMethodInt(pNdb, waitUntilReady()); + + while(NdbMutex_Trylock(g_pNdbMutex)) { + Uint32 nWarehouse = myRandom48(g_nWarehouseCount); + NdbConnection* pNdbConnection = NULL ; + VerifyMethodPtr(pNdbConnection, pNdb, startTransaction()); + CHK_TR(pNdbConnection); + NdbOperation* pNdbOperationW = NULL ; + VerifyMethodPtr(pNdbOperationW, pNdbConnection, getNdbOperation(c_szWarehouse)); + VerifyMethodInt(pNdbOperationW, insertTuple()); + VerifyMethodInt(pNdbOperationW, equal(c_szWarehouseNumber, nWarehouse)); + VerifyMethodInt(pNdbOperationW, setValue(c_szWarehouseCount, Uint32(1))); + Uint32 nWarehouseSum = 0; + for(Uint32 nDistrict=0; nDistrictexecute(Commit); + int iError = pNdbConnection->getNdbError().code; + CommitStatusType cs = pNdbConnection->commitStatus(); + + if(iExec<0 && iError!=0 && iError!=266 && iError!=630) { + ReportMethodInt(iExec, pNdbConnection, "pNdbConnection", "execute(Commit)", __FILE__, __LINE__); + } + if(iExec==0) { + ++nSucc; + } else { + ++nFail; + } + VerifyMethodVoid(pNdb, closeTransaction(pNdbConnection)); + } + ndbout << "insert: " << nSucc << " succeeded, " << nFail << " failed " << endl; + NdbMutex_Unlock(g_pNdbMutex); + delete pNdb; + pNdb = NULL ; + return NULL; +} + + +extern "C" void* NdbThreadFuncUpdate(void* pArg) +{ + myRandom48Init((long int)NdbTick_CurrentMillisecond()); + unsigned nSucc = 0; + unsigned nFail = 0; + Ndb* pNdb = NULL ; + pNdb = new Ndb("TEST_DB"); + VerifyMethodInt(pNdb, init()); + VerifyMethodInt(pNdb, waitUntilReady()); + + while(NdbMutex_Trylock(g_pNdbMutex)) { + Uint32 nWarehouse = myRandom48(g_nWarehouseCount); + NdbConnection* pNdbConnection = NULL ; + VerifyMethodPtr(pNdbConnection, pNdb, startTransaction()); + CHK_TR(pNdbConnection) ; // epaulsa + NdbOperation* pNdbOperationW = NULL ; + VerifyMethodPtr(pNdbOperationW, pNdbConnection, getNdbOperation(c_szWarehouse)); + VerifyMethodInt(pNdbOperationW, interpretedUpdateTuple()); + VerifyMethodInt(pNdbOperationW, equal(c_szWarehouseNumber, nWarehouse)); + VerifyMethodInt(pNdbOperationW, incValue(c_szWarehouseCount, Uint32(1))); + Uint32 nWarehouseSum = 0; + for(Uint32 nDistrict=0; nDistrictexecute(Commit); + int iError = pNdbConnection->getNdbError().code; + CommitStatusType cs = pNdbConnection->commitStatus(); + + if(iExec<0 && iError!=0 && iError!=266 && iError!=626) { + ReportMethodInt(iExec, pNdbConnection, "pNdbConnection", "execute(Commit)", __FILE__, __LINE__); + } + if(iExec==0) { + ++nSucc; + } else { + ++nFail; + } + VerifyMethodVoid(pNdb, closeTransaction(pNdbConnection)); + } + ndbout << "update: " << nSucc << " succeeded, " << nFail << " failed " << endl; + NdbMutex_Unlock(g_pNdbMutex); + delete pNdb; + pNdb = NULL ; + return NULL; +} + + +extern "C" void* NdbThreadFuncDelete(void* pArg) +{ + myRandom48Init((long int)NdbTick_CurrentMillisecond()); + unsigned nSucc = 0; + unsigned nFail = 0; + Ndb* pNdb = NULL ; + pNdb = new Ndb("TEST_DB"); + VerifyMethodInt(pNdb, init()); + VerifyMethodInt(pNdb, waitUntilReady()); + + while(NdbMutex_Trylock(g_pNdbMutex)) { + Uint32 nWarehouse = myRandom48(g_nWarehouseCount); + NdbConnection* pNdbConnection = NULL ; + VerifyMethodPtr(pNdbConnection, pNdb, startTransaction()); + CHK_TR(pNdbConnection) ; // epaulsa + NdbOperation* pNdbOperationW = NULL ; + VerifyMethodPtr(pNdbOperationW, pNdbConnection, getNdbOperation(c_szWarehouse)); + VerifyMethodInt(pNdbOperationW, deleteTuple()); + VerifyMethodInt(pNdbOperationW, equal(c_szWarehouseNumber, nWarehouse)); + for(Uint32 nDistrict=0; nDistrictexecute(Commit); + int iError = pNdbConnection->getNdbError().code; + CommitStatusType cs = pNdbConnection->commitStatus(); + + if(iExec<0 && iError!=0 && iError!=266 && iError!=626) { + ReportMethodInt(iExec, pNdbConnection, "pNdbConnection", "execute(Commit)", __FILE__, __LINE__); + } + if(iExec==0) { + ++nSucc; + } else { + ++nFail; + } + VerifyMethodVoid(pNdb, closeTransaction(pNdbConnection)); + } + ndbout << "delete: " << nSucc << " succeeded, " << nFail << " failed " << endl; + NdbMutex_Unlock(g_pNdbMutex); + delete pNdb; + pNdb = NULL ; + return NULL; +} + + +extern "C" void* NdbThreadFuncRead(void* pArg) +{ + myRandom48Init((long int)NdbTick_CurrentMillisecond()); + unsigned nSucc = 0; + unsigned nFail = 0; + NdbRecAttr** ppNdbRecAttrDSum = new NdbRecAttr*[g_nDistrictPerWarehouse]; + NdbRecAttr** ppNdbRecAttrDCnt = new NdbRecAttr*[g_nDistrictPerWarehouse]; + Ndb* pNdb = NULL ; + pNdb = new Ndb("TEST_DB"); + VerifyMethodInt(pNdb, init()); + VerifyMethodInt(pNdb, waitUntilReady()); + + while(NdbMutex_Trylock(g_pNdbMutex)) { + Uint32 nWarehouse = myRandom48(g_nWarehouseCount); + NdbConnection* pNdbConnection = NULL ; + VerifyMethodPtr(pNdbConnection, pNdb, startTransaction()); + CHK_TR(pNdbConnection) ; // epaulsa + NdbOperation* pNdbOperationW = NULL ; + VerifyMethodPtr(pNdbOperationW, pNdbConnection, getNdbOperation(c_szWarehouse)); + VerifyMethodInt(pNdbOperationW, readTuple()); + VerifyMethodInt(pNdbOperationW, equal(c_szWarehouseNumber, nWarehouse)); + NdbRecAttr* pNdbRecAttrWSum; + VerifyMethodPtr(pNdbRecAttrWSum, pNdbOperationW, getValue(c_szWarehouseSum, 0)); + NdbRecAttr* pNdbRecAttrWCnt; + VerifyMethodPtr(pNdbRecAttrWCnt, pNdbOperationW, getValue(c_szWarehouseCount, 0)); + for(Uint32 nDistrict=0; nDistrictexecute(Commit); + int iError = pNdbConnection->getNdbError().code; + CommitStatusType cs = pNdbConnection->commitStatus(); + if(iExec<0 && iError!=0 && iError!=266 && iError!=626) { + ReportMethodInt(iExec, pNdbConnection, "pNdbConnection", "execute(Commit)", __FILE__, __LINE__); + } + if(iExec==0) { + Uint32 nSum = 0; + Uint32 nCnt = 0; + for(Uint32 nDistrict=0; nDistrictu_32_value(); + nCnt += ppNdbRecAttrDCnt[nDistrict]->u_32_value(); + } + if(nSum!=pNdbRecAttrWSum->u_32_value() + || nCnt!=g_nDistrictPerWarehouse*pNdbRecAttrWCnt->u_32_value()) { + ndbout << "INCONSISTENT!" << endl; + ndbout << "iExec==" << iExec << endl; + ndbout << "iError==" << iError << endl; + ndbout << endl; + ndbout << c_szWarehouseSum << "==" << pNdbRecAttrWSum->u_32_value() << ", "; + ndbout << c_szWarehouseCount << "==" << pNdbRecAttrWCnt->u_32_value() << endl; + ndbout << "nSum==" << nSum << ", nCnt=" << nCnt << endl; + for(Uint32 nDistrict=0; nDistrictu_32_value() << ", "; + ndbout << c_szDistrictCount << "[" << nDistrict << "]==" << ppNdbRecAttrDCnt[nDistrict]->u_32_value() << endl; + } + VerifyMethodVoid(pNdb, closeTransaction(pNdbConnection)); + delete pNdb; pNdb = NULL ; + delete[] ppNdbRecAttrDSum; ppNdbRecAttrDSum = NULL ; + delete[] ppNdbRecAttrDCnt; ppNdbRecAttrDCnt = NULL ; + NDBT_ProgramExit(NDBT_FAILED); + } + ++nSucc; + } else { + ++nFail; + } + VerifyMethodVoid(pNdb, closeTransaction(pNdbConnection)); + } + ndbout << "read: " << nSucc << " succeeded, " << nFail << " failed " << endl; + NdbMutex_Unlock(g_pNdbMutex); + delete pNdb; pNdb = NULL ; + delete[] ppNdbRecAttrDSum; ppNdbRecAttrDSum = NULL ; + delete[] ppNdbRecAttrDCnt; ppNdbRecAttrDCnt = NULL ; + return NULL; +} + + +NDB_COMMAND(acid, "acid", "acid", "acid", 65535) +{ + long nSeconds = 60; + int rc = NDBT_OK; + + for(int i=1; i -#include -#include -#include -#include -#include -#include -#include -#include - -//#define TRACE -#define DEBUG -//#define RELEASE -#define NODE_REC // epaulsa: introduces pointer checks to help 'acid' keep core -// during node recovery - -#ifdef TRACE - -#define VerifyMethodInt(c, m) (ReportMethodInt(c->m, c, #c, #m, __FILE__, __LINE__)) -#define VerifyMethodPtr(v, c, m) (v=ReportMethodPtr(c->m, c, #v, #c, #m, __FILE__, __LINE__)) -#define VerifyMethodVoid(c, m) (c->m, ReportMethodVoid(c, #c, #m, __FILE__, __LINE__)) - -int ReportMethodInt(int iRes, NdbConnection* pNdbConnection, const char* szClass, const char* szMethod, const char* szFile, const int iLine) -{ - ndbout << szFile << "(" << iLine << ") : "; - ndbout << szClass << "->" << szMethod << " return " << iRes << " : "; - ndbout << pNdbConnection->getNdbError(); - NdbOperation* pNdbOperation = pNdbConnection->getNdbErrorOperation(); - if(pNdbOperation) { - ndbout << " : " << pNdbOperation->getNdbError(); - } - ndbout << " : " << pNdbConnection->getNdbErrorLine(); - ndbout << endl; - return iRes; -} - -template -int ReportMethodInt(int iRes, C* pC, const char* szClass, const char* szMethod, const char* szFile, const int iLine) -{ - ndbout << szFile << "(" << iLine << ") : "; - ndbout << szClass << "->" << szMethod << " return " << iRes << " : "; - ndbout << pC->getNdbError(); - ndbout << endl; - return iRes; -} - -template -R* ReportMethodPtr(R* pR, C* pC, const char* szVariable, const char* szClass, const char* szMethod, const char* szFile, const int iLine) -{ - ndbout << szFile << "(" << iLine << ") : "; - ndbout << szVariable << " = " << szClass << "->" << szMethod << " return " << (long)(void*)pR << " : "; - ndbout << pC->getNdbError(); - ndbout << endl; - return pR; -} - -template -void ReportMethodVoid(C* pC, const char* szClass, const char* szMethod, const char* szFile, const int iLine) -{ - ndbout << szFile << "(" << iLine << ") : "; - ndbout << szClass << "->" << szMethod << " : "; - ndbout << pC->getNdbError(); - ndbout << endl; -} -#endif /* TRACE */ - - -#ifdef DEBUG - -#define VerifyMethodInt(c, m) (ReportMethodInt(c->m, c, #c, #m, __FILE__, __LINE__)) -#define VerifyMethodPtr(v, c, m) (v=ReportMethodPtr(c->m, c, #v, #c, #m, __FILE__, __LINE__)) -#define VerifyMethodVoid(c, m) (c->m, ReportMethodVoid(c, #c, #m, __FILE__, __LINE__)) - -int ReportMethodInt(int iRes, NdbConnection* pNdbConnection, const char* szClass, const char* szMethod, const char* szFile, const int iLine) -{ - if(iRes<0) { - ndbout << szFile << "(" << iLine << ") : "; - ndbout << szClass << "->" << szMethod << " return " << iRes << " : "; - ndbout << pNdbConnection->getNdbError(); - NdbOperation* pNdbOperation = pNdbConnection->getNdbErrorOperation(); - if(pNdbOperation) { - ndbout << " : " << pNdbOperation->getNdbError(); - } - ndbout << " : " << pNdbConnection->getNdbErrorLine(); - ndbout << " : "; - ndbout << endl; - } - return iRes; -} - -template -int ReportMethodInt(int iRes, C* pC, const char* szClass, const char* szMethod, const char* szFile, const int iLine) -{ - if(iRes<0) { - ndbout << szFile << "(" << iLine << ") : "; - ndbout << szClass << "->" << szMethod << " return " << iRes << " : "; - ndbout << pC->getNdbError(); - ndbout << endl; - } - return iRes; -} - -template -R* ReportMethodPtr(R* pR, C* pC, const char* szVariable, const char* szClass, const char* szMethod, const char* szFile, const int iLine) -{ - if(!pR) { - ndbout << szFile << "(" << iLine << ") : "; - ndbout << szVariable << " = " << szClass << "->" << szMethod << " return " << " : "; - ndbout << pC->getNdbError(); - ndbout << endl; - } - return pR; -} - -template -void ReportMethodVoid(C* pC, const char* szClass, const char* szMethod, const char* szFile, const int iLine) -{ - if(pC->getNdbError().code) { - ndbout << szFile << "(" << iLine << ") : "; - ndbout << szClass << "->" << szMethod << " : "; - ndbout << pC->getNdbError(); - ndbout << endl; - } -} - - -#endif /* DEBUG */ - - -#ifdef RELEASE - -#define VerifyMethodInt(c, m) (c->m) -#define VerifyMethodPtr(v, c, m) (v=(c->m)) -#define VerifyMethodVoid(c, m) (c->m) - -int ReportMethodInt(int iRes, NdbConnection* pNdbConnection, const char* szClass, const char* szMethod, const char* szFile, const int iLine) -{ - if(iRes<0) { - ndbout << szFile << "(" << iLine << ") : "; - ndbout << szClass << "->" << szMethod << " return " << iRes << " : "; - ndbout << pNdbConnection->getNdbError(); - NdbOperation* pNdbOperation = pNdbConnection->getNdbErrorOperation(); - if(pNdbOperation) { - ndbout << " : " << pNdbOperation->getNdbError(); - } - ndbout << " : " << pNdbConnection->getNdbErrorLine(); - ndbout << endl; - } - return iRes; -} - -#endif /* RELEASE */ - -// epaulsa => -#ifndef NODE_REC -#define CHK_TR(p) -#else -#define CHK_TR(p) if(!p){ \ - ndbout <<"startTransaction failed, returning now." << endl ; \ - delete pNdb ; \ - pNdb = NULL ; \ - return 0 ; \ - } -#endif // NODE_REC -// <= epaulsa - -const char* c_szWarehouse = "WAREHOUSE"; -const char* c_szWarehouseNumber = "W_ID"; -const char* c_szWarehouseSum = "W_SUM"; -const char* c_szWarehouseCount = "W_CNT"; -const char* c_szDistrict = "DISTRICT"; -const char* c_szDistrictWarehouseNumber = "D_W_ID"; -const char* c_szDistrictNumber = "D_ID"; -const char* c_szDistrictSum = "D_SUM"; -const char* c_szDistrictCount = "D_CNT"; - -Uint32 g_nWarehouseCount = 10; -Uint32 g_nDistrictPerWarehouse = 10; -Uint32 g_nThreadCount = 1; -NdbMutex* g_pNdbMutex = 0; - -extern "C" void* NdbThreadFuncInsert(void* pArg) -{ - myRandom48Init((long int)NdbTick_CurrentMillisecond()); - unsigned nSucc = 0; - unsigned nFail = 0; - Ndb* pNdb = NULL ; - pNdb = new Ndb("TEST_DB"); - VerifyMethodInt(pNdb, init()); - VerifyMethodInt(pNdb, waitUntilReady()); - - while(NdbMutex_Trylock(g_pNdbMutex)) { - Uint32 nWarehouse = myRandom48(g_nWarehouseCount); - NdbConnection* pNdbConnection = NULL ; - VerifyMethodPtr(pNdbConnection, pNdb, startTransaction()); - CHK_TR(pNdbConnection); - NdbOperation* pNdbOperationW = NULL ; - VerifyMethodPtr(pNdbOperationW, pNdbConnection, getNdbOperation(c_szWarehouse)); - VerifyMethodInt(pNdbOperationW, insertTuple()); - VerifyMethodInt(pNdbOperationW, equal(c_szWarehouseNumber, nWarehouse)); - VerifyMethodInt(pNdbOperationW, setValue(c_szWarehouseCount, Uint32(1))); - Uint32 nWarehouseSum = 0; - for(Uint32 nDistrict=0; nDistrictexecute(Commit); - int iError = pNdbConnection->getNdbError().code; - CommitStatusType cs = pNdbConnection->commitStatus(); - - if(iExec<0 && iError!=0 && iError!=266 && iError!=630) { - ReportMethodInt(iExec, pNdbConnection, "pNdbConnection", "execute(Commit)", __FILE__, __LINE__); - } - if(iExec==0) { - ++nSucc; - } else { - ++nFail; - } - VerifyMethodVoid(pNdb, closeTransaction(pNdbConnection)); - } - ndbout << "insert: " << nSucc << " succeeded, " << nFail << " failed " << endl; - NdbMutex_Unlock(g_pNdbMutex); - delete pNdb; - pNdb = NULL ; - return NULL; -} - - -extern "C" void* NdbThreadFuncUpdate(void* pArg) -{ - myRandom48Init((long int)NdbTick_CurrentMillisecond()); - unsigned nSucc = 0; - unsigned nFail = 0; - Ndb* pNdb = NULL ; - pNdb = new Ndb("TEST_DB"); - VerifyMethodInt(pNdb, init()); - VerifyMethodInt(pNdb, waitUntilReady()); - - while(NdbMutex_Trylock(g_pNdbMutex)) { - Uint32 nWarehouse = myRandom48(g_nWarehouseCount); - NdbConnection* pNdbConnection = NULL ; - VerifyMethodPtr(pNdbConnection, pNdb, startTransaction()); - CHK_TR(pNdbConnection) ; // epaulsa - NdbOperation* pNdbOperationW = NULL ; - VerifyMethodPtr(pNdbOperationW, pNdbConnection, getNdbOperation(c_szWarehouse)); - VerifyMethodInt(pNdbOperationW, interpretedUpdateTuple()); - VerifyMethodInt(pNdbOperationW, equal(c_szWarehouseNumber, nWarehouse)); - VerifyMethodInt(pNdbOperationW, incValue(c_szWarehouseCount, Uint32(1))); - Uint32 nWarehouseSum = 0; - for(Uint32 nDistrict=0; nDistrictexecute(Commit); - int iError = pNdbConnection->getNdbError().code; - CommitStatusType cs = pNdbConnection->commitStatus(); - - if(iExec<0 && iError!=0 && iError!=266 && iError!=626) { - ReportMethodInt(iExec, pNdbConnection, "pNdbConnection", "execute(Commit)", __FILE__, __LINE__); - } - if(iExec==0) { - ++nSucc; - } else { - ++nFail; - } - VerifyMethodVoid(pNdb, closeTransaction(pNdbConnection)); - } - ndbout << "update: " << nSucc << " succeeded, " << nFail << " failed " << endl; - NdbMutex_Unlock(g_pNdbMutex); - delete pNdb; - pNdb = NULL ; - return NULL; -} - - -extern "C" void* NdbThreadFuncDelete(void* pArg) -{ - myRandom48Init((long int)NdbTick_CurrentMillisecond()); - unsigned nSucc = 0; - unsigned nFail = 0; - Ndb* pNdb = NULL ; - pNdb = new Ndb("TEST_DB"); - VerifyMethodInt(pNdb, init()); - VerifyMethodInt(pNdb, waitUntilReady()); - - while(NdbMutex_Trylock(g_pNdbMutex)) { - Uint32 nWarehouse = myRandom48(g_nWarehouseCount); - NdbConnection* pNdbConnection = NULL ; - VerifyMethodPtr(pNdbConnection, pNdb, startTransaction()); - CHK_TR(pNdbConnection) ; // epaulsa - NdbOperation* pNdbOperationW = NULL ; - VerifyMethodPtr(pNdbOperationW, pNdbConnection, getNdbOperation(c_szWarehouse)); - VerifyMethodInt(pNdbOperationW, deleteTuple()); - VerifyMethodInt(pNdbOperationW, equal(c_szWarehouseNumber, nWarehouse)); - for(Uint32 nDistrict=0; nDistrictexecute(Commit); - int iError = pNdbConnection->getNdbError().code; - CommitStatusType cs = pNdbConnection->commitStatus(); - - if(iExec<0 && iError!=0 && iError!=266 && iError!=626) { - ReportMethodInt(iExec, pNdbConnection, "pNdbConnection", "execute(Commit)", __FILE__, __LINE__); - } - if(iExec==0) { - ++nSucc; - } else { - ++nFail; - } - VerifyMethodVoid(pNdb, closeTransaction(pNdbConnection)); - } - ndbout << "delete: " << nSucc << " succeeded, " << nFail << " failed " << endl; - NdbMutex_Unlock(g_pNdbMutex); - delete pNdb; - pNdb = NULL ; - return NULL; -} - - -extern "C" void* NdbThreadFuncRead(void* pArg) -{ - myRandom48Init((long int)NdbTick_CurrentMillisecond()); - unsigned nSucc = 0; - unsigned nFail = 0; - NdbRecAttr** ppNdbRecAttrDSum = new NdbRecAttr*[g_nDistrictPerWarehouse]; - NdbRecAttr** ppNdbRecAttrDCnt = new NdbRecAttr*[g_nDistrictPerWarehouse]; - Ndb* pNdb = NULL ; - pNdb = new Ndb("TEST_DB"); - VerifyMethodInt(pNdb, init()); - VerifyMethodInt(pNdb, waitUntilReady()); - - while(NdbMutex_Trylock(g_pNdbMutex)) { - Uint32 nWarehouse = myRandom48(g_nWarehouseCount); - NdbConnection* pNdbConnection = NULL ; - VerifyMethodPtr(pNdbConnection, pNdb, startTransaction()); - CHK_TR(pNdbConnection) ; // epaulsa - NdbOperation* pNdbOperationW = NULL ; - VerifyMethodPtr(pNdbOperationW, pNdbConnection, getNdbOperation(c_szWarehouse)); - VerifyMethodInt(pNdbOperationW, readTuple()); - VerifyMethodInt(pNdbOperationW, equal(c_szWarehouseNumber, nWarehouse)); - NdbRecAttr* pNdbRecAttrWSum; - VerifyMethodPtr(pNdbRecAttrWSum, pNdbOperationW, getValue(c_szWarehouseSum, 0)); - NdbRecAttr* pNdbRecAttrWCnt; - VerifyMethodPtr(pNdbRecAttrWCnt, pNdbOperationW, getValue(c_szWarehouseCount, 0)); - for(Uint32 nDistrict=0; nDistrictexecute(Commit); - int iError = pNdbConnection->getNdbError().code; - CommitStatusType cs = pNdbConnection->commitStatus(); - if(iExec<0 && iError!=0 && iError!=266 && iError!=626) { - ReportMethodInt(iExec, pNdbConnection, "pNdbConnection", "execute(Commit)", __FILE__, __LINE__); - } - if(iExec==0) { - Uint32 nSum = 0; - Uint32 nCnt = 0; - for(Uint32 nDistrict=0; nDistrictu_32_value(); - nCnt += ppNdbRecAttrDCnt[nDistrict]->u_32_value(); - } - if(nSum!=pNdbRecAttrWSum->u_32_value() - || nCnt!=g_nDistrictPerWarehouse*pNdbRecAttrWCnt->u_32_value()) { - ndbout << "INCONSISTENT!" << endl; - ndbout << "iExec==" << iExec << endl; - ndbout << "iError==" << iError << endl; - ndbout << endl; - ndbout << c_szWarehouseSum << "==" << pNdbRecAttrWSum->u_32_value() << ", "; - ndbout << c_szWarehouseCount << "==" << pNdbRecAttrWCnt->u_32_value() << endl; - ndbout << "nSum==" << nSum << ", nCnt=" << nCnt << endl; - for(Uint32 nDistrict=0; nDistrictu_32_value() << ", "; - ndbout << c_szDistrictCount << "[" << nDistrict << "]==" << ppNdbRecAttrDCnt[nDistrict]->u_32_value() << endl; - } - VerifyMethodVoid(pNdb, closeTransaction(pNdbConnection)); - delete pNdb; pNdb = NULL ; - delete[] ppNdbRecAttrDSum; ppNdbRecAttrDSum = NULL ; - delete[] ppNdbRecAttrDCnt; ppNdbRecAttrDCnt = NULL ; - NDBT_ProgramExit(NDBT_FAILED); - } - ++nSucc; - } else { - ++nFail; - } - VerifyMethodVoid(pNdb, closeTransaction(pNdbConnection)); - } - ndbout << "read: " << nSucc << " succeeded, " << nFail << " failed " << endl; - NdbMutex_Unlock(g_pNdbMutex); - delete pNdb; pNdb = NULL ; - delete[] ppNdbRecAttrDSum; ppNdbRecAttrDSum = NULL ; - delete[] ppNdbRecAttrDCnt; ppNdbRecAttrDCnt = NULL ; - return NULL; -} - - -NDB_COMMAND(acid, "acid", "acid", "acid", 65535) -{ - long nSeconds = 60; - int rc = NDBT_OK; - - for(int i=1; i +#include +#include +#include +#include + +#include "TraceNdbApi.hpp" +#include "VerifyNdbApi.hpp" + + +#define Ndb CTraceNdb +#define NdbSchemaCon CTraceNdbSchemaCon +#define NdbSchemaOp CTraceNdbSchemaOp +#define NdbConnection CTraceNdbConnection +#define NdbOperation CTraceNdbOperation +#define NdbIndexOperation CTraceNdbIndexOperation +#define NdbRecAttr CTraceNdbRecAttr +#define Table CTraceTable +#define Index CTraceIndex +#define Column CTraceColumn +#define NdbDictionary CTraceNdbDictionary + +/* +#define Ndb CVerifyNdb +#define NdbSchemaCon CVerifyNdbSchemaCon +#define NdbSchemaOp CVerifyNdbSchemaOp +#define NdbConnection CVerifyNdbConnection +#define NdbOperation CVerifyNdbOperation +#define NdbIndexOperation CVerifyNdbIndexOperation +#define NdbRecAttr CVerifyNdbRecAttr +#define Table CVerifyTable +#define Index CVerifyIndex +#define Column CVerifyColumn +#define NdbDictionary CVerifyNdbDictionary +*/ + +NdbMutex* g_pNdbMutexStop = 0; +Uint32 g_nPart = 1; +Uint32 g_nTable = 1; +Uint32 g_nTuple = 1; +Uint32 g_nAttribute = 1; +char* g_szTable = 0; +char* g_szIndex = 0; +char* g_szAttribute = 0; +bool g_bVerify = false; +bool g_bUseIndex = false; + + + +#define N 624 +#define M 397 +#define MATRIX_A 0x9908b0df +#define UPPER_MASK 0x80000000 +#define LOWER_MASK 0x7fffffff + +#define TEMPERING_MASK_B 0x9d2c5680 +#define TEMPERING_MASK_C 0xefc60000 +#define TEMPERING_SHIFT_U(y) (y >> 11) +#define TEMPERING_SHIFT_S(y) (y << 7) +#define TEMPERING_SHIFT_T(y) (y << 15) +#define TEMPERING_SHIFT_L(y) (y >> 18) + + +class MT19937 +{ +public: + MT19937(void); + void sgenrand(unsigned long seed); + unsigned long genrand(void); + +private: + unsigned long mt[N]; + int mti; + unsigned long mag01[2]; +}; + + +MT19937::MT19937(void) +{ + mti = N+1; + mag01[0] = 0x0; + mag01[1] = MATRIX_A; + sgenrand(4357); +} + + +void MT19937::sgenrand(unsigned long seed) +{ + mt[0]= seed & 0xffffffff; + for (mti=1; mti= N) { + int kk; + if (mti == N+1) + { + sgenrand(4357); + } + for (kk=0;kk> 1) ^ mag01[y & 0x1]; + } + for (;kk> 1) ^ mag01[y & 0x1]; + } + y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); + mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1]; + mti = 0; + } + y = mt[mti++]; + y ^= TEMPERING_SHIFT_U(y); + y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B; + y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C; + y ^= TEMPERING_SHIFT_L(y); + return y; +} + + + + + +void CreateTables(Ndb* pNdb) +{ + for(Uint32 iTable=0; iTablegetDictionary(); + + NdbDictionary::Table table; + table.setName(g_szTable+iTable*4); + + NdbDictionary::Index index; + index.setName(g_szIndex+iTable*4); + index.setTable(table.getName()); + index.setType(NdbDictionary::Index::UniqueHashIndex); + + NdbDictionary::Column columnPK; + columnPK.setName("PK"); + columnPK.setTupleKey(true); + table.addColumn(columnPK); + index.addIndexColumn(columnPK.getName()); + + for(Uint32 iAttr=0; iAttrcreateTable(table); + pDictionary->createIndex(index); + + /* + NdbSchemaCon* pNdbSchemaCon = pNdb->startSchemaTransaction(); + NdbSchemaOp* pNdbSchemaOp = pNdbSchemaCon->getNdbSchemaOp(); + pNdbSchemaOp->createTable(g_szTable+iTable*4); + pNdbSchemaOp->createAttribute("PK", TupleKey); + for(Uint32 iAttr=0; iAttrcreateAttribute(g_szAttribute+iAttr*4, NoKey); + } + + pNdbSchemaCon->execute(); + pNdb->closeSchemaTransaction(pNdbSchemaCon); + */ + } +} + + +int InsertTransaction(Ndb* pNdb, const Uint32 iPart, const bool bIndex) +{ + int iExec = -1; + int iCode = -1; + NdbConnection* pNdbConnection = pNdb->startTransaction(); + if(pNdbConnection) + { + for(Uint32 iTable=0; iTablegetNdbIndexOperation(g_szIndex+iTable*4, g_szTable+iTable*4); + pNdbIndexOperation->insertTuple(); + Uint32 nPK = iPart*g_nTuple + iTuple; + pNdbIndexOperation->equal("PK", nPK); + for(Uint32 iAttr=0; iAttrsetValue(g_szAttribute+iAttr*4, nValue); + } + } + else + { + NdbOperation* pNdbOperation = pNdbConnection->getNdbOperation(g_szTable+iTable*4); + pNdbOperation->insertTuple(); + Uint32 nPK = iPart*g_nTuple + iTuple; + pNdbOperation->equal("PK", nPK); + for(Uint32 iAttr=0; iAttrsetValue(g_szAttribute+iAttr*4, nValue); + } + } + } + } + iExec = pNdbConnection->execute_ok(Commit); + if (iExec == -1) + { + ndbout << pNdbConnection->getNdbError() << endl; + } + pNdb->closeTransaction(pNdbConnection); + } + return 0; +} + + +int UpdateGetAndSetTransaction(Ndb* pNdb, const Uint32 iPart, const bool bIndex) +{ + int iExec = -1; + int iCode = -1; + NdbRecAttr** ppNdbRecAttr = new NdbRecAttr*[g_nTable*g_nTuple*g_nAttribute]; + NdbConnection* pNdbConnection = pNdb->startTransaction(); + if(pNdbConnection) + { + for(Uint32 iTable=0; iTablegetNdbIndexOperation(g_szIndex+iTable*4, g_szTable+iTable*4); + pNdbIndexOperation->readTupleExclusive(); + Uint32 nPK = iPart*g_nTuple + iTuple; + pNdbIndexOperation->equal("PK", nPK); + for(Uint32 iAttr=0; iAttrgetValue(g_szAttribute+iAttr*4); + } + } + else + { + NdbOperation* pNdbOperation = pNdbConnection->getNdbOperation(g_szTable+iTable*4); + pNdbOperation->readTupleExclusive(); + Uint32 nPK = iPart*g_nTuple + iTuple; + pNdbOperation->equal("PK", nPK); + for(Uint32 iAttr=0; iAttrgetValue(g_szAttribute+iAttr*4); + } + } + } + } + iExec = pNdbConnection->execute_ok(NoCommit); + if( iExec == -1) + { + ndbout << pNdbConnection->getNdbError() << endl; + } + } + iCode = pNdbConnection->getNdbError().code; + if(iExec==0) + { + for(Uint32 iTable=0; iTablegetNdbIndexOperation(g_szIndex+iTable*4, g_szTable+iTable*4); + pNdbIndexOperation->updateTuple(); + Uint32 nPK = iPart*g_nTuple + iTuple; + pNdbIndexOperation->equal("PK", nPK); + for(Uint32 iAttr=0; iAttru_32_value() + 1; + pNdbIndexOperation->setValue(g_szAttribute+iAttr*4, nValue); + } + } + else + { + NdbOperation* pNdbOperation = pNdbConnection->getNdbOperation(g_szTable+iTable*4); + pNdbOperation->updateTuple(); + Uint32 nPK = iPart*g_nTuple + iTuple; + pNdbOperation->equal("PK", nPK); + for(Uint32 iAttr=0; iAttru_32_value() + 1; + pNdbOperation->setValue(g_szAttribute+iAttr*4, nValue); + } + } + } + } + iExec = pNdbConnection->execute(Commit); + if (iExec == -1) + { + ndbout << pNdbConnection->getNdbError() << endl; + } + pNdb->closeTransaction(pNdbConnection); + } + delete[] ppNdbRecAttr; + return 0; +} + + +int UpdateInterpretedTransaction(Ndb* pNdb, const Uint32 iPart, const bool bIndex) +{ + int iExec = -1; + int iCode = -1; + NdbConnection* pNdbConnection = pNdb->startTransaction(); + if(pNdbConnection) + { + for(Uint32 iTable=0; iTablegetNdbIndexOperation(g_szIndex+iTable*4, g_szTable+iTable*4); + pNdbIndexOperation->interpretedUpdateTuple(); + Uint32 nPK = iPart*g_nTuple + iTuple; + pNdbIndexOperation->equal("PK", nPK); + for(Uint32 iAttr=0; iAttrincValue(g_szAttribute+iAttr*4, (Uint32)1); + } + } + else + { + NdbOperation* pNdbOperation = pNdbConnection->getNdbOperation(g_szTable+iTable*4); + pNdbOperation->interpretedUpdateTuple(); + Uint32 nPK = iPart*g_nTuple + iTuple; + pNdbOperation->equal("PK", nPK); + for(Uint32 iAttr=0; iAttrincValue(g_szAttribute+iAttr*4, (Uint32)1); + } + } + } + } + iExec = pNdbConnection->execute_ok(Commit); + + if (iExec == -1) + { + ndbout << pNdbConnection->getNdbError() << endl; + } + pNdb->closeTransaction(pNdbConnection); + } + return 0; +} + + +void ReportInconsistency (const Uint32 iPart, + const Uint32 iTable, + const Uint32 iTuple, + const Uint32 iAttr, + const Uint32 nValue, + const Uint32 nExpected ) +{ + ndbout << "INCONSISTENCY: "; + ndbout << "Part " << iPart; + ndbout << ", Table " << iTable; + ndbout << ", Tuple " << iTuple; + ndbout << ", Attr " << iAttr; + ndbout << ", Value " << nValue; + ndbout << ", Expected " << nExpected; + ndbout << endl; +} + + +int ReadTransaction(Ndb* pNdb, const Uint32 iPart, const bool bIndex) +{ + int iExec = -1; + int iCode = -1; + NdbRecAttr** ppNdbRecAttr = new NdbRecAttr*[g_nTable*g_nTuple*g_nAttribute]; + NdbConnection* pNdbConnection = pNdb->startTransaction(); + if(pNdbConnection) + { + for(Uint32 iTable=0; iTablegetNdbIndexOperation(g_szIndex+iTable*4, g_szTable+iTable*4); + pNdbIndexOperation->readTuple(); + Uint32 nPK = iPart*g_nTuple + iTuple; + pNdbIndexOperation->equal("PK", nPK); + for(Uint32 iAttr=0; iAttrgetValue(g_szAttribute+iAttr*4); + } + } + else + { + NdbOperation* pNdbOperation = pNdbConnection->getNdbOperation(g_szTable+iTable*4); + pNdbOperation->readTuple(); + Uint32 nPK = iPart*g_nTuple + iTuple; + pNdbOperation->equal("PK", nPK); + for(Uint32 iAttr=0; iAttrgetValue(g_szAttribute+iAttr*4); + } + } + } + } + iExec = pNdbConnection->execute_ok(Commit); + if (iExec == -1) + { + ndbout << pNdbConnection->getNdbError() << endl; + } + if(iExec==0) + { + Uint32 nValue0 = ppNdbRecAttr[0]->u_32_value(); + for(Uint32 iTable=0; iTableu_32_value(); + Uint32 nExpected = nValue0 + (iTable*g_nTuple+iTuple)*g_nAttribute+iAttr; + if(nValue!=nExpected) + { + ReportInconsistency(iPart, iTable, iTuple, iAttr, nValue, nExpected); + } + } + } + } + } + pNdb->closeTransaction(pNdbConnection); + } + return 0; +} + + +int DeleteTransaction(Ndb* pNdb, const Uint32 iPart, const bool bIndex) +{ + int iExec = -1; + int iCode = -1; + NdbConnection* pNdbConnection = pNdb->startTransaction(); + if(pNdbConnection) + { + for(Uint32 iTable=0; iTablegetNdbIndexOperation(g_szIndex+iTable*4, g_szTable+iTable*4); + pNdbIndexOperation->deleteTuple(); + Uint32 nPK = iPart*g_nTuple + iTuple; + pNdbIndexOperation->equal("PK", nPK); + } + else + { + NdbOperation* pNdbOperation = pNdbConnection->getNdbOperation(g_szTable+iTable*4); + pNdbOperation->deleteTuple(); + Uint32 nPK = iPart*g_nTuple + iTuple; + pNdbOperation->equal("PK", nPK); + } + } + } + iExec = pNdbConnection->execute_ok(Commit); + + if (iExec == -1) + { + ndbout << pNdbConnection->getNdbError() << endl; + } + pNdb->closeTransaction(pNdbConnection); + } + return 0; +} + + +extern "C" void* ThreadFunc(void*) +{ + Ndb* pNdb = new Ndb("TEST_DB"); + pNdb->init(); + pNdb->waitUntilReady(); + + MT19937 rndgen; + rndgen.sgenrand((unsigned long)pNdb); + + Uint32 nInsertError = 0; + Uint32 nInsertCommit = 0; + Uint32 nInsertRollback = 0; + Uint32 nUpdateGetAndSetError = 0; + Uint32 nUpdateGetAndSetCommit = 0; + Uint32 nUpdateGetAndSetRollback = 0; + Uint32 nReadError = 0; + Uint32 nReadCommit = 0; + Uint32 nReadRollback = 0; + Uint32 nUpdateInterpretedError = 0; + Uint32 nUpdateInterpretedCommit = 0; + Uint32 nUpdateInterpretedRollback = 0; + Uint32 nDeleteError = 0; + Uint32 nDeleteCommit = 0; + Uint32 nDeleteRollback = 0; + + if (g_bVerify) + { + for (Uint32 iPart = 0; iPart < g_nPart; iPart++) + { + switch(ReadTransaction(pNdb, iPart, false)) + { + case -1: ++nReadError; break; + case 0: ++nReadCommit; break; + case 1: ++nReadRollback; break; + } + } + } + else + while(NdbMutex_Trylock(g_pNdbMutexStop)) + { + Uint32 iPart = rndgen.genrand() % g_nPart; + Uint32 iTrans = rndgen.genrand() % 5; + bool bIndex = ((rndgen.genrand() & 1) ? true : false); + switch(iTrans) + { + case 0: + switch(InsertTransaction(pNdb, iPart, bIndex)) + { + case -1: ++nInsertError; break; + case 0: ++nInsertCommit; break; + case 1: ++nInsertRollback; break; + } + break; + + case 1: + switch(UpdateGetAndSetTransaction(pNdb, iPart, bIndex)) + { + case -1: ++nUpdateGetAndSetError; break; + case 0: ++nUpdateGetAndSetCommit; break; + case 1: ++nUpdateGetAndSetRollback; break; + } + break; + + case 2: + switch(ReadTransaction(pNdb, iPart, bIndex)) + { + case -1: ++nReadError; break; + case 0: ++nReadCommit; break; + case 1: ++nReadRollback; break; + } + break; + + case 3: + switch(UpdateInterpretedTransaction(pNdb, iPart, bIndex)) + { + case -1: ++nUpdateInterpretedError; break; + case 0: ++nUpdateInterpretedCommit; break; + case 1: ++nUpdateInterpretedRollback; break; + } + break; + + case 4: + switch(DeleteTransaction(pNdb, iPart, bIndex)) + { + case -1: ++nDeleteError; break; + case 0: ++nDeleteCommit; break; + case 1: ++nDeleteRollback; break; + } + break; + } + } + + ndbout << "I:" << nInsertError << ":" << nInsertCommit << ":" << nInsertRollback; + ndbout << " UG:" << nUpdateGetAndSetError << ":" << nUpdateGetAndSetCommit << ":" << nUpdateGetAndSetRollback; + ndbout << " R:" << nReadError << ":" << nReadCommit << ":" << nReadRollback; + ndbout << " UI:" << nUpdateInterpretedError << ":" << nUpdateInterpretedCommit << ":" << nUpdateInterpretedRollback; + ndbout << " D:" << nDeleteError << ":" << nDeleteCommit << ":" << nDeleteRollback << endl; + ndbout << endl; + + NdbMutex_Unlock(g_pNdbMutexStop); + delete pNdb; + return 0; +} + + +int main(int argc, char* argv[]) +{ + Uint32 nSeconds = 1; + Uint32 nThread = 1; + + for(int iArg=1; iArginit(); + pNdb->waitUntilReady(); + + if (!g_bVerify) CreateTables(pNdb); + g_pNdbMutexStop = NdbMutex_Create(); + NdbMutex_Lock(g_pNdbMutexStop); + + NdbThread_SetConcurrencyLevel(nThread+1); + NdbThread** ppNdbThread = new NdbThread*[nThread]; + for(Uint32 iThread=0; iThread -#include -#include - -#include "TraceNdbApi.hpp" - - -int g_nParamTrace; -NdbMutex* g_pNdbMutexTrace = 0; - - -void TraceBegin(void) -{ - if(!g_pNdbMutexTrace) - { - g_pNdbMutexTrace = NdbMutex_Create(); - } - NdbMutex_Lock(g_pNdbMutexTrace); - g_nParamTrace = 0; -} - -void TraceEnd(void) -{ - ndbout << endl; - g_nParamTrace = 0; - NdbMutex_Unlock(g_pNdbMutexTrace); -} - -void TraceMethod(const char* szMethod) -{ - ndbout << "->" << szMethod << "("; - g_nParamTrace = 0; -} - -void TraceParamComma(void) -{ - if(g_nParamTrace) - { - ndbout << ", "; - } - ++g_nParamTrace; -} - -void TraceNdb(Ndb* pNdb) -{ - TraceParamComma(); - ndbout << "((Ndb*)" << hex << (Uint32)pNdb << ")"; -} - -void TraceNdbSchemaCon(NdbSchemaCon* pNdbSchemaCon) -{ - TraceParamComma(); - ndbout << "((NdbSchemaCon*)" << hex << (Uint32)pNdbSchemaCon << ")"; -} - -void TraceNdbSchemaOp(NdbSchemaOp* pNdbSchemaOp) -{ - TraceParamComma(); - ndbout << "((NdbSchemaOp*)" << hex << (Uint32)pNdbSchemaOp << ")"; -} - -void TraceNdbConnection(const NdbConnection* pNdbConnection) -{ - TraceParamComma(); - ndbout << "((NdbConnection*)" << hex << (Uint32)pNdbConnection << ")"; -} - -void TraceNdbOperation(NdbOperation* pNdbOperation) -{ - TraceParamComma(); - ndbout << "((NdbOperation*)" << hex << (Uint32)pNdbOperation << ")"; -} - -void TraceNdbIndexOperation(NdbIndexOperation* pNdbIndexOperation) -{ - TraceParamComma(); - ndbout << "((NdbIndexOperation*)" << hex << (Uint32)pNdbIndexOperation << ")"; -} - -void TraceNdbRecAttr(NdbRecAttr* pNdbRecAttr) -{ - TraceParamComma(); - ndbout << "((NdbRecAttr*)" << hex << (Uint32)pNdbRecAttr << ")"; -} - -void TraceTable(Table* pTable) -{ - TraceParamComma(); - ndbout << "((Table*)" << hex << (Uint32)pTable << ")"; -} - -void TraceString(const char* szParam) -{ - TraceParamComma(); - ndbout << "\"" << szParam << "\""; -} - -void TraceInt(const int i) -{ - TraceParamComma(); - ndbout << "(int)" << dec << i; -} - -void TraceUint32(const Uint32 n) -{ - TraceParamComma(); - ndbout << "(Uint32)" << dec << n; -} - -void TraceKeyType(const KeyType aKeyType) -{ - TraceParamComma(); - switch(aKeyType) - { - case Undefined: ndbout << "Undefined"; break; - case NoKey: ndbout << "NoKey"; break; - case TupleKey: ndbout << "TupleKey"; break; - case TupleId: ndbout << "TupleId"; break; - default: ndbout << "(KeyType)" << aKeyType; break; - } -} - -void TraceExecType(const ExecType aExecType) -{ - switch(aExecType) - { - case NoExecTypeDef: ndbout << "NoExecTypeDef"; break; - case Prepare: ndbout << "Prepare"; break; - case NoCommit: ndbout << "NoCommit"; break; - case Commit: ndbout << "Commit"; break; - case Rollback: ndbout << "Rollback"; break; - default: ndbout << "(ExecType)" << aExecType; break; - } -} - - -void TraceNdbError(const NdbError& err) -{ - TraceParamComma(); - ndbout << "(NdbError)" << err; -} - - - -void TraceVoid(void) -{ - ndbout << "void"; -} - -void TraceReturn(void) -{ - ndbout << "); // return "; - g_nParamTrace = 0; -} - - -// TraceNdbSchemaOp - -int CTraceNdbSchemaOp::createTable(const char* aTableName) -{ - int i = NdbSchemaOp::createTable(aTableName); - TraceBegin(); - TraceNdbSchemaOp(this); - TraceMethod("createTable"); - TraceString(aTableName); - TraceReturn(); - TraceInt(i); - TraceEnd(); - return i; -} - -int CTraceNdbSchemaOp::createAttribute(const char* aAttrName, KeyType aTupleyKey) -{ - int i = NdbSchemaOp::createAttribute(aAttrName, aTupleyKey); - TraceBegin(); - TraceNdbSchemaOp(this); - TraceMethod("createAttribute"); - TraceString(aAttrName); - TraceKeyType(aTupleyKey); - TraceReturn(); - TraceInt(i); - TraceEnd(); - return i; -} - - - -// TraceNdbSchemaCon - -CTraceNdbSchemaOp* CTraceNdbSchemaCon::getNdbSchemaOp() -{ - NdbSchemaOp* pNdbSchemaOp = NdbSchemaCon::getNdbSchemaOp(); - TraceBegin(); - TraceNdbSchemaCon(this); - TraceMethod("getNdbSchemaOp"); - TraceReturn(); - TraceNdbSchemaOp(pNdbSchemaOp); - TraceEnd(); - return (CTraceNdbSchemaOp*)pNdbSchemaOp; -} - -int CTraceNdbSchemaCon::execute() -{ - int i = NdbSchemaCon::execute(); - TraceBegin(); - TraceNdbSchemaCon(this); - TraceMethod("execute"); - TraceReturn(); - TraceInt(i); - TraceEnd(); - return i; -} - - - -// TraceNdbRecAttr - -Uint32 CTraceNdbRecAttr::u_32_value() -{ - Uint32 n = NdbRecAttr::u_32_value(); - TraceBegin(); - TraceNdbRecAttr(this); - TraceMethod("u_32_value"); - TraceReturn(); - TraceUint32(n); - TraceEnd(); - return n; -} - - - -// TraceNdbOperation - -int CTraceNdbOperation::insertTuple() -{ - int i = NdbOperation::insertTuple(); - TraceBegin(); - TraceNdbOperation(this); - TraceMethod("insertTuple"); - TraceReturn(); - TraceInt(i); - TraceEnd(); - return i; -} - -int CTraceNdbOperation::updateTuple() -{ - int i = NdbOperation::updateTuple(); - TraceBegin(); - TraceNdbOperation(this); - TraceMethod("updateTuple"); - TraceReturn(); - TraceInt(i); - TraceEnd(); - return i; -} - -int CTraceNdbOperation::interpretedUpdateTuple() -{ - int i = NdbOperation::interpretedUpdateTuple(); - TraceBegin(); - TraceNdbOperation(this); - TraceMethod("interpretedUpdateTuple"); - TraceReturn(); - TraceInt(i); - TraceEnd(); - return i; -} - -int CTraceNdbOperation::readTuple() -{ - int i = NdbOperation::readTuple(); - TraceBegin(); - TraceNdbOperation(this); - TraceMethod("readTuple"); - TraceReturn(); - TraceInt(i); - TraceEnd(); - return i; -} - - -int CTraceNdbOperation::readTupleExclusive() -{ - int i = NdbOperation::readTupleExclusive(); - TraceBegin(); - TraceNdbOperation(this); - TraceMethod("readTupleExclusive"); - TraceReturn(); - TraceInt(i); - TraceEnd(); - return i; -} - - -int CTraceNdbOperation::deleteTuple() -{ - int i = NdbOperation::deleteTuple(); - TraceBegin(); - TraceNdbOperation(this); - TraceMethod("deleteTuple"); - TraceReturn(); - TraceInt(i); - TraceEnd(); - return i; -} - -int CTraceNdbOperation::equal(const char* anAttrName, Uint32 aValue) -{ - int i = NdbOperation::equal(anAttrName, aValue); - TraceBegin(); - TraceNdbOperation(this); - TraceMethod("equal"); - TraceString(anAttrName); - TraceUint32(aValue); - TraceReturn(); - TraceInt(i); - TraceEnd(); - return i; -} - -int CTraceNdbOperation::setValue(const char* anAttrName, Uint32 aValue) -{ - int i = NdbOperation::setValue(anAttrName, aValue); - TraceBegin(); - TraceNdbOperation(this); - TraceMethod("setValue"); - TraceString(anAttrName); - TraceUint32(aValue); - TraceReturn(); - TraceInt(i); - TraceEnd(); - return i; -} - -int CTraceNdbOperation::incValue(const char* anAttrName, Uint32 aValue) -{ - int i = NdbOperation::incValue(anAttrName, aValue); - TraceBegin(); - TraceNdbOperation(this); - TraceMethod("incValue"); - TraceString(anAttrName); - TraceUint32(aValue); - TraceReturn(); - TraceInt(i); - TraceEnd(); - return i; -} - -CTraceNdbRecAttr* CTraceNdbOperation::getValue(const char* anAttrName) -{ - NdbRecAttr* pNdbRecAttr = NdbOperation::getValue(anAttrName); - TraceBegin(); - TraceNdbOperation(this); - TraceMethod("getValue"); - TraceString(anAttrName); - TraceReturn(); - TraceNdbRecAttr(pNdbRecAttr); - TraceEnd(); - return (CTraceNdbRecAttr*)pNdbRecAttr; -} - - -// TraceNdbIndexOperation - -int CTraceNdbIndexOperation::equal(const char* anAttrName, Uint32 aValue) -{ - int i = NdbIndexOperation::equal(anAttrName, aValue); - TraceBegin(); - TraceNdbIndexOperation(this); - TraceMethod("equal"); - TraceString(anAttrName); - TraceUint32(aValue); - TraceReturn(); - TraceInt(i); - TraceEnd(); - return i; -} - - -int CTraceNdbIndexOperation::incValue(const char* anAttrName, Uint32 aValue) -{ - int i = NdbIndexOperation::incValue(anAttrName, aValue); - TraceBegin(); - TraceNdbIndexOperation(this); - TraceMethod("incValue"); - TraceString(anAttrName); - TraceUint32(aValue); - TraceReturn(); - TraceInt(i); - TraceEnd(); - return i; -} - - -CTraceNdbRecAttr* CTraceNdbIndexOperation::getValue(const char* anAttrName) -{ - NdbRecAttr* pNdbRecAttr = NdbIndexOperation::getValue(anAttrName); - TraceBegin(); - TraceNdbIndexOperation(this); - TraceMethod("getValue"); - TraceString(anAttrName); - TraceReturn(); - TraceNdbRecAttr(pNdbRecAttr); - TraceEnd(); - return (CTraceNdbRecAttr*)pNdbRecAttr; -} - - -// TraceNdbConnection - -CTraceNdbOperation* CTraceNdbConnection::getNdbOperation(const char* aTableName) -{ - NdbOperation* pNdbOperation = NdbConnection::getNdbOperation(aTableName); - TraceBegin(); - TraceNdbConnection(this); - TraceMethod("getNdbOperation"); - TraceString(aTableName); - TraceReturn(); - TraceNdbOperation(pNdbOperation); - TraceEnd(); - return (CTraceNdbOperation*)pNdbOperation; -} - -CTraceNdbIndexOperation* CTraceNdbConnection::getNdbIndexOperation(const char* anIndexName, const char* aTableName) -{ - NdbIndexOperation* pNdbIndexOperation = NdbConnection::getNdbIndexOperation(anIndexName, aTableName); - TraceBegin(); - TraceNdbConnection(this); - TraceMethod("getNdbIndexOperation"); - TraceString(anIndexName); - TraceString(aTableName); - TraceReturn(); - TraceNdbIndexOperation(pNdbIndexOperation); - TraceEnd(); - return (CTraceNdbIndexOperation*)pNdbIndexOperation; -} - -int CTraceNdbConnection::execute(ExecType aTypeOfExec) -{ - int i = NdbConnection::execute(aTypeOfExec); - TraceBegin(); - TraceNdbConnection(this); - TraceMethod("execute"); - TraceExecType(aTypeOfExec); - TraceReturn(); - TraceInt(i); - TraceEnd(); - return i; -} - -const NdbError & CTraceNdbConnection::getNdbError(void) const -{ - const NdbError& err = NdbConnection::getNdbError(); - TraceBegin(); - TraceNdbConnection(this); - TraceMethod("getNdbError"); - TraceReturn(); - TraceNdbError(err); - TraceEnd(); - return err; -} - - - -// TraceNdb - -CTraceNdb::CTraceNdb(const char* aDataBase) -: Ndb(aDataBase) -{ - TraceBegin(); - TraceNdb(this); - TraceMethod("Ndb"); - TraceString(aDataBase); - TraceReturn(); - TraceVoid(); - TraceEnd(); -} - -CTraceNdbSchemaCon* CTraceNdb::startSchemaTransaction() -{ - NdbSchemaCon* pNdbSchemaCon = Ndb::startSchemaTransaction(); - TraceBegin(); - TraceNdb(this); - TraceMethod("startSchemaTransaction"); - TraceReturn(); - TraceNdbSchemaCon(pNdbSchemaCon); - TraceEnd(); - return (CTraceNdbSchemaCon*)pNdbSchemaCon; -} - -void CTraceNdb::closeSchemaTransaction(CTraceNdbSchemaCon* aSchemaCon) -{ - Ndb::closeSchemaTransaction(aSchemaCon); - TraceBegin(); - TraceNdb(this); - TraceMethod("closeSchemaTransaction"); - TraceReturn(); - TraceVoid(); - TraceEnd(); -} - -CTraceNdbConnection* CTraceNdb::startTransaction() -{ - NdbConnection* pNdbConnection = Ndb::startTransaction(); - TraceBegin(); - TraceNdb(this); - TraceMethod("startTransaction"); - TraceReturn(); - TraceNdbConnection(pNdbConnection); - TraceEnd(); - return (CTraceNdbConnection*)pNdbConnection; -} - -void CTraceNdb::closeTransaction(CTraceNdbConnection* aConnection) -{ - Ndb::closeTransaction(aConnection); - TraceBegin(); - TraceNdb(this); - TraceMethod("closeTransaction"); - TraceNdbConnection(aConnection); - TraceReturn(); - TraceVoid(); - TraceEnd(); -} - - diff --git a/ndb/test/ndbapi/acid2/TraceNdbApi.hpp b/ndb/test/ndbapi/acid2/TraceNdbApi.hpp deleted file mode 100644 index 2bd4eab6b70..00000000000 --- a/ndb/test/ndbapi/acid2/TraceNdbApi.hpp +++ /dev/null @@ -1,132 +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 */ - - -#ifndef TraceNdbApi_hpp -#define TraceNdbApi_hpp - - -class CTraceNdbSchemaOp : public NdbSchemaOp -{ -public: - int createTable(const char* aTableName); - int createAttribute(const char* aAttrName, KeyType aTupleyKey); -}; - - - -class CTraceNdbSchemaCon : public NdbSchemaCon -{ -public: - CTraceNdbSchemaOp* getNdbSchemaOp(); - int execute(); -}; - - - -class CTraceNdbRecAttr : public NdbRecAttr -{ -public: - Uint32 u_32_value(); -}; - - -class CTraceNdbOperation : public NdbOperation -{ -public: - int insertTuple(); - int updateTuple(); - int interpretedUpdateTuple(); - int readTuple(); - int readTupleExclusive(); - int deleteTuple(); - int equal(const char* anAttrName, Uint32 aValue); - int setValue(const char* anAttrName, Uint32 aValue); - int incValue(const char* anAttrName, Uint32 aValue); - CTraceNdbRecAttr* getValue(const char* anAttrName); - -}; - - -class CTraceNdbIndexOperation : public NdbIndexOperation -{ -public: - int insertTuple(); - int updateTuple(); - int interpretedUpdateTuple(); - int readTuple(); - int readTupleExclusive(); - int deleteTuple(); - int equal(const char* anAttrName, Uint32 aValue); - int setValue(const char* anAttrName, Uint32 aValue); - int incValue(const char* anAttrName, Uint32 aValue); - CTraceNdbRecAttr* getValue(const char* anAttrName); -}; - - - -class CTraceNdbConnection : public NdbConnection -{ -public: - CTraceNdbOperation* getNdbOperation(const char* aTableName); - CTraceNdbIndexOperation* getNdbIndexOperation(const char* anIndexName, const char* aTableName); - - int execute(ExecType aTypeOfExec); - - int execute_ok(ExecType aTypeOfExec) - { - return execute(aTypeOfExec); - }; - - const NdbError & getNdbError(void) const; -}; - - - -class CTraceNdbDictionary : public NdbDictionary -{ -public: - class CTraceTable : public Table - { - }; - - class CTraceIndex : public Index - { - }; - - class CTraceColumn : public Column - { - }; - - int createTable(const CTraceTable &); - int createIndex(const CTraceIndex &); -}; - - - -class CTraceNdb : public Ndb -{ -public: - CTraceNdb(const char* aDataBase); - CTraceNdbSchemaCon* startSchemaTransaction(); - void closeSchemaTransaction(CTraceNdbSchemaCon* aSchemaCon); - CTraceNdbConnection* startTransaction(); - void closeTransaction(CTraceNdbConnection* aConnection); -}; - - - -#endif // TraceNdbApi_hpp diff --git a/ndb/test/ndbapi/acid2/VerifyNdbApi.cpp b/ndb/test/ndbapi/acid2/VerifyNdbApi.cpp deleted file mode 100644 index 79645827e2c..00000000000 --- a/ndb/test/ndbapi/acid2/VerifyNdbApi.cpp +++ /dev/null @@ -1,151 +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 */ - - -#include -#include -#include - -#include "VerifyNdbApi.hpp" - - -NdbMutex* g_pNdbMutexVerify = 0; - - -void VerifyBegin(void) -{ - if(!g_pNdbMutexVerify) - { - g_pNdbMutexVerify = NdbMutex_Create(); - } - NdbMutex_Lock(g_pNdbMutexVerify); -} - -void VerifyEnd(void) -{ - NdbMutex_Unlock(g_pNdbMutexVerify); -} - - - -void CVerifyNdbSchemaOp::VerifyIntError(const int i, const char* szMethod) -{ - VerifyBegin(); - ndbout << "NdbSchemaOp::" << szMethod << " returned " << dec << i; - ndbout << " : " << dec << getNdbError().code << " : " << getNdbError().message << endl; - VerifyEnd(); -} - - -void CVerifyNdbSchemaCon::VerifyIntError(const int i, const char* szMethod) -{ - VerifyBegin(); - ndbout << "NdbSchemaCon::" << szMethod << " returned " << dec << i; - ndbout << " : " << dec << getNdbError().code << " : " << getNdbError().message << endl; - VerifyEnd(); -} - - -void CVerifyNdbSchemaCon::VerifyPtrError(void* p, const char* szMethod) -{ - VerifyBegin(); - ndbout << "NdbSchemaCon::" << szMethod << " returned " << hex << (Uint32)p; - ndbout << " : " << dec << getNdbError().code << " : " << getNdbError().message << endl; - VerifyEnd(); -} - - -void CVerifyNdbRecAttr::VerifyValueError(const int iNull, const char* szMethod) -{ - VerifyBegin(); - ndbout << "NdbRecAttr::" << szMethod << " : isNULL() returned " << dec << iNull; - ndbout << endl; - VerifyEnd(); -} - - -void CVerifyNdbOperation::VerifyIntError(const int i, const char* szMethod) -{ - VerifyBegin(); - ndbout << "NdbOperation::" << szMethod << " returned " << dec << i; - ndbout << " : " << dec << getNdbError().code << " : " << getNdbError().message << endl; - VerifyEnd(); -} - - -void CVerifyNdbOperation::VerifyPtrError(void* p, const char* szMethod) -{ - VerifyBegin(); - ndbout << "NdbOperation::" << szMethod << " returned " << hex << (Uint32)p; - ndbout << " : " << dec << getNdbError().code << " : " << getNdbError().message << endl; - VerifyEnd(); -} - - -void CVerifyNdbIndexOperation::VerifyIntError(const int i, const char* szMethod) -{ - VerifyBegin(); - ndbout << "NdbIndexOperation::" << szMethod << " returned " << dec << i; - ndbout << " : " << dec << getNdbError().code << " : " << getNdbError().message << endl; - VerifyEnd(); -} - - -void CVerifyNdbIndexOperation::VerifyPtrError(void* p, const char* szMethod) -{ - VerifyBegin(); - ndbout << "NdbIndexOperation::" << szMethod << " returned " << hex << (Uint32)p; - ndbout << " : " << dec << getNdbError().code << " : " << getNdbError().message << endl; - VerifyEnd(); -} - - -void CVerifyNdbConnection::VerifyIntError(const int i, const char* szMethod) -{ - VerifyBegin(); - ndbout << "NdbConnection::" << szMethod << " returned " << dec << i; - ndbout << " : " << dec << getNdbError().code << " : " << getNdbError().message << endl; - VerifyEnd(); -} - - -void CVerifyNdbConnection::VerifyPtrError(void* p, const char* szMethod) -{ - VerifyBegin(); - ndbout << "NdbConnection::" << szMethod << " returned " << hex << (Uint32)p; - ndbout << " : " << dec << getNdbError().code << " : " << getNdbError().message << endl; - VerifyEnd(); -} - - -void CVerifyNdb::VerifyPtrError(void* p, const char* szMethod) -{ - VerifyBegin(); - ndbout << "Ndb::" << szMethod << " returned " << hex << (Uint32)p; - ndbout << " : " << dec << getNdbError().code << " : " << getNdbError().message << endl; - VerifyEnd(); -} - - -void CVerifyNdb::VerifyVoidError(const int iCode, const char* szMethod) -{ - VerifyBegin(); - ndbout << "Ndb::" << szMethod << " : getNdbError().code returned " << dec << iCode; - ndbout << " : " << getNdbError().message << endl; - VerifyEnd(); -} - - diff --git a/ndb/test/ndbapi/acid2/VerifyNdbApi.hpp b/ndb/test/ndbapi/acid2/VerifyNdbApi.hpp deleted file mode 100644 index 4a5b8cc8111..00000000000 --- a/ndb/test/ndbapi/acid2/VerifyNdbApi.hpp +++ /dev/null @@ -1,466 +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 */ - - -#ifndef VerifyNdbApi_hpp -#define VerifyNdbApi_hpp - - -class CVerifyNdbSchemaOp : public NdbSchemaOp -{ -public: - int createTable(const char* aTableName) - { - int i = NdbSchemaOp::createTable(aTableName); - VerifyInt(i, "createTable"); - return i; - }; - - int createAttribute(const char* aAttrName, KeyType aTupleyKey) - { - int i = NdbSchemaOp::createAttribute(aAttrName, aTupleyKey); - VerifyInt(i, "createAttribute"); - return i; - }; - -private: - void VerifyInt(const int i, const char* szMethod) - { - if(i) - { - VerifyIntError(i, szMethod); - } - } - - void VerifyIntError(const int i, const char* szMethod); -}; - - - -class CVerifyNdbSchemaCon : public NdbSchemaCon -{ -public: - CVerifyNdbSchemaOp* getNdbSchemaOp() - { - NdbSchemaOp* p = NdbSchemaCon::getNdbSchemaOp(); - VerifyPtr(p, "getNdbSchemaOp"); - return (CVerifyNdbSchemaOp*)p; - }; - - int execute() - { - int i = NdbSchemaCon::execute(); - VerifyInt(i, "execute"); - return i; - }; - -private: - void VerifyInt(const int i, const char* szMethod) - { - if(i) - { - VerifyIntError(i, szMethod); - } - } - - void VerifyPtr(void* p, const char* szMethod) - { - if(!p) - { - VerifyPtrError(p, szMethod); - } - } - - void VerifyIntError(const int i, const char* szMethod); - void VerifyPtrError(void* p, const char* szMethod); -}; - - - -class CVerifyNdbRecAttr : public NdbRecAttr -{ -public: - Uint32 u_32_value() - { - Uint32 n = NdbRecAttr::u_32_value(); - VerifyValue("u_32_value"); - return n; - }; - -private: - void VerifyValue(const char* szMethod) - { - int iNull = NdbRecAttr::isNULL(); - if(iNull) - { - VerifyValueError(iNull, szMethod); - } - }; - - void VerifyValueError(const int iNull, const char* szMethod); -}; - - -class CVerifyNdbOperation : public NdbOperation -{ -public: - int insertTuple() - { - int i = NdbOperation::insertTuple(); - VerifyInt(i, "insertTuple"); - return i; - }; - - int updateTuple() - { - int i = NdbOperation::updateTuple(); - VerifyInt(i, "updateTuple"); - return i; - }; - - int interpretedUpdateTuple() - { - int i = NdbOperation::interpretedUpdateTuple(); - VerifyInt(i, "interpretedUpdateTuple"); - return i; - } - - int readTuple() - { - int i = NdbOperation::readTuple(); - VerifyInt(i, "readTuple"); - return i; - } - - int readTupleExclusive() - { - int i = NdbOperation::readTupleExclusive(); - VerifyInt(i, "readTupleExclusive"); - return i; - } - - int deleteTuple() - { - int i = NdbOperation::deleteTuple(); - VerifyInt(i, "deleteTuple"); - return i; - } - - int equal(const char* anAttrName, Uint32 aValue) - { - int i = NdbOperation::equal(anAttrName, aValue); - VerifyInt(i, "equal"); - return i; - } - - int setValue(const char* anAttrName, Uint32 aValue) - { - int i = NdbOperation::setValue(anAttrName, aValue); - VerifyInt(i, "setValue"); - return i; - } - - int incValue(const char* anAttrName, Uint32 aValue) - { - int i = NdbOperation::incValue(anAttrName, aValue); - VerifyInt(i, "incValue"); - return i; - } - - CVerifyNdbRecAttr* getValue(const char* anAttrName) - { - NdbRecAttr* p = NdbOperation::getValue(anAttrName); - VerifyPtr(p, "getValue"); - return (CVerifyNdbRecAttr*)p; - } - - -private: - void VerifyInt(const int i, const char* szMethod) - { - if(i) - { - VerifyIntError(i, szMethod); - } - } - - void VerifyPtr(void* p, const char* szMethod) - { - if(!p) - { - VerifyPtrError(p, szMethod); - } - } - - void VerifyIntError(const int i, const char* szMethod); - void VerifyPtrError(void* p, const char* szMethod); -}; - - -class CVerifyNdbIndexOperation : public NdbIndexOperation -{ -public: - int insertTuple() - { - int i = NdbIndexOperation::insertTuple(); - VerifyInt(i, "insertTuple"); - return i; - }; - - int updateTuple() - { - int i = NdbIndexOperation::updateTuple(); - VerifyInt(i, "updateTuple"); - return i; - }; - - int interpretedUpdateTuple() - { - int i = NdbIndexOperation::interpretedUpdateTuple(); - VerifyInt(i, "interpretedUpdateTuple"); - return i; - } - - int readTuple() - { - int i = NdbIndexOperation::readTuple(); - VerifyInt(i, "readTuple"); - return i; - } - - int readTupleExclusive() - { - int i = NdbIndexOperation::readTupleExclusive(); - VerifyInt(i, "readTupleExclusive"); - return i; - } - - int deleteTuple() - { - int i = NdbIndexOperation::deleteTuple(); - VerifyInt(i, "deleteTuple"); - return i; - } - - int equal(const char* anAttrName, Uint32 aValue) - { - int i = NdbIndexOperation::equal(anAttrName, aValue); - VerifyInt(i, "equal"); - return i; - } - - int setValue(const char* anAttrName, Uint32 aValue) - { - int i = NdbIndexOperation::setValue(anAttrName, aValue); - VerifyInt(i, "setValue"); - return i; - } - - int incValue(const char* anAttrName, Uint32 aValue) - { - int i = NdbIndexOperation::incValue(anAttrName, aValue); - VerifyInt(i, "incValue"); - return i; - } - - CVerifyNdbRecAttr* getValue(const char* anAttrName) - { - NdbRecAttr* p = NdbIndexOperation::getValue(anAttrName); - VerifyPtr(p, "getValue"); - return (CVerifyNdbRecAttr*)p; - } - - -private: - void VerifyInt(const int i, const char* szMethod) - { - if(i) - { - VerifyIntError(i, szMethod); - } - } - - void VerifyPtr(void* p, const char* szMethod) - { - if(!p) - { - VerifyPtrError(p, szMethod); - } - } - - void VerifyIntError(const int i, const char* szMethod); - void VerifyPtrError(void* p, const char* szMethod); -}; - - -class CVerifyNdbConnection : public NdbConnection -{ -public: - CVerifyNdbOperation* getNdbOperation(const char* aTableName) - { - NdbOperation* p = NdbConnection::getNdbOperation(aTableName); - VerifyPtr(p, "getNdbOperation"); - return (CVerifyNdbOperation*)p; - } - - CVerifyNdbIndexOperation* getNdbIndexOperation(const char* anIndexName, const char* aTableName) - { - NdbIndexOperation* p = NdbConnection::getNdbIndexOperation(anIndexName, aTableName); - VerifyPtr(p, "getNdbIndexOperation"); - return (CVerifyNdbIndexOperation*)p; - } - - int execute(ExecType aTypeOfExec) - { - int i = NdbConnection::execute(aTypeOfExec); - VerifyInt(i, "execute"); - return i; - } - - int execute_ok(ExecType aTypeOfExec) - { - int iExec = NdbConnection::execute(aTypeOfExec); - NdbError err = NdbConnection::getNdbError(); - int iCode = err.code; - if(iExec - && ((aTypeOfExec==NoCommit && iCode!=0) - || (aTypeOfExec==Commit && iCode!=626 && iCode!=630))) - { - VerifyInt(iExec, "execute"); - } - return iExec; - } - - -private: - void VerifyInt(const int i, const char* szMethod) - { - if(i) - { - VerifyIntError(i, szMethod); - } - } - - void VerifyPtr(void* p, const char* szMethod) - { - if(!p) - { - VerifyPtrError(p, szMethod); - } - } - - void VerifyIntError(const int i, const char* szMethod); - void VerifyPtrError(void* p, const char* szMethod); -}; - - -//class CVerifyTable : public NdbDictionary::Table -//{ -//public: -//}; - - -class CVerifyNdbDictionary : public NdbDictionary -{ -public: - class CVerifyTable : public Table - { - public: - private: - }; - - class CVerifyIndex : public Index - { - public: - private: - }; - - class CVerifyColumn : public Column - { - public: - private: - }; - - int createTable(const CVerifyTable &); - int createIndex(const CVerifyIndex &); - - -private: -}; - - -class CVerifyNdb : public Ndb -{ -public: - CVerifyNdb(const char* aDataBase) - : Ndb(aDataBase) - { - VerifyVoid("Ndb"); - }; - - CVerifyNdbSchemaCon* startSchemaTransaction() - { - NdbSchemaCon* p = Ndb::startSchemaTransaction(); - VerifyPtr(p, "startSchemaTransaction"); - return (CVerifyNdbSchemaCon*)p; - }; - - void closeSchemaTransaction(CVerifyNdbSchemaCon* aSchemaCon) - { - Ndb::closeSchemaTransaction(aSchemaCon); - VerifyVoid("closeSchemaTransaction"); - }; - - CVerifyNdbConnection* startTransaction() - { - NdbConnection* p = Ndb::startTransaction(); - VerifyPtr(p, "startTransaction"); - return (CVerifyNdbConnection*)p; - }; - - void closeTransaction(CVerifyNdbConnection* aConnection) - { - Ndb::closeTransaction(aConnection); - VerifyVoid("closeTransaction"); - }; - - -private: - void VerifyPtr(void* p, const char* szMethod) - { - if(!p) - { - VerifyPtrError(p, szMethod); - } - } - - void VerifyVoid(const char* szMethod) - { - NdbError err = Ndb::getNdbError(); - int iCode = err.code; - if(iCode) - { - VerifyVoidError(iCode, szMethod); - } - } - - void VerifyPtrError(void* p, const char* szMethod); - void VerifyVoidError(const int iCode, const char* szMethod); -}; - - - -#endif // VerifyNdbApi_hpp diff --git a/ndb/test/ndbapi/acid2/acid2.cpp b/ndb/test/ndbapi/acid2/acid2.cpp deleted file mode 100644 index 434a0450daa..00000000000 --- a/ndb/test/ndbapi/acid2/acid2.cpp +++ /dev/null @@ -1,692 +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 */ - - -#include -#include -#include -#include -#include - -#include "TraceNdbApi.hpp" -#include "VerifyNdbApi.hpp" - - -#define Ndb CTraceNdb -#define NdbSchemaCon CTraceNdbSchemaCon -#define NdbSchemaOp CTraceNdbSchemaOp -#define NdbConnection CTraceNdbConnection -#define NdbOperation CTraceNdbOperation -#define NdbIndexOperation CTraceNdbIndexOperation -#define NdbRecAttr CTraceNdbRecAttr -#define Table CTraceTable -#define Index CTraceIndex -#define Column CTraceColumn -#define NdbDictionary CTraceNdbDictionary - -/* -#define Ndb CVerifyNdb -#define NdbSchemaCon CVerifyNdbSchemaCon -#define NdbSchemaOp CVerifyNdbSchemaOp -#define NdbConnection CVerifyNdbConnection -#define NdbOperation CVerifyNdbOperation -#define NdbIndexOperation CVerifyNdbIndexOperation -#define NdbRecAttr CVerifyNdbRecAttr -#define Table CVerifyTable -#define Index CVerifyIndex -#define Column CVerifyColumn -#define NdbDictionary CVerifyNdbDictionary -*/ - -NdbMutex* g_pNdbMutexStop = 0; -Uint32 g_nPart = 1; -Uint32 g_nTable = 1; -Uint32 g_nTuple = 1; -Uint32 g_nAttribute = 1; -char* g_szTable = 0; -char* g_szIndex = 0; -char* g_szAttribute = 0; -bool g_bVerify = false; -bool g_bUseIndex = false; - - - -#define N 624 -#define M 397 -#define MATRIX_A 0x9908b0df -#define UPPER_MASK 0x80000000 -#define LOWER_MASK 0x7fffffff - -#define TEMPERING_MASK_B 0x9d2c5680 -#define TEMPERING_MASK_C 0xefc60000 -#define TEMPERING_SHIFT_U(y) (y >> 11) -#define TEMPERING_SHIFT_S(y) (y << 7) -#define TEMPERING_SHIFT_T(y) (y << 15) -#define TEMPERING_SHIFT_L(y) (y >> 18) - - -class MT19937 -{ -public: - MT19937(void); - void sgenrand(unsigned long seed); - unsigned long genrand(void); - -private: - unsigned long mt[N]; - int mti; - unsigned long mag01[2]; -}; - - -MT19937::MT19937(void) -{ - mti = N+1; - mag01[0] = 0x0; - mag01[1] = MATRIX_A; - sgenrand(4357); -} - - -void MT19937::sgenrand(unsigned long seed) -{ - mt[0]= seed & 0xffffffff; - for (mti=1; mti= N) { - int kk; - if (mti == N+1) - { - sgenrand(4357); - } - for (kk=0;kk> 1) ^ mag01[y & 0x1]; - } - for (;kk> 1) ^ mag01[y & 0x1]; - } - y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); - mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1]; - mti = 0; - } - y = mt[mti++]; - y ^= TEMPERING_SHIFT_U(y); - y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B; - y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C; - y ^= TEMPERING_SHIFT_L(y); - return y; -} - - - - - -void CreateTables(Ndb* pNdb) -{ - for(Uint32 iTable=0; iTablegetDictionary(); - - NdbDictionary::Table table; - table.setName(g_szTable+iTable*4); - - NdbDictionary::Index index; - index.setName(g_szIndex+iTable*4); - index.setTable(table.getName()); - index.setType(NdbDictionary::Index::UniqueHashIndex); - - NdbDictionary::Column columnPK; - columnPK.setName("PK"); - columnPK.setTupleKey(true); - table.addColumn(columnPK); - index.addIndexColumn(columnPK.getName()); - - for(Uint32 iAttr=0; iAttrcreateTable(table); - pDictionary->createIndex(index); - - /* - NdbSchemaCon* pNdbSchemaCon = pNdb->startSchemaTransaction(); - NdbSchemaOp* pNdbSchemaOp = pNdbSchemaCon->getNdbSchemaOp(); - pNdbSchemaOp->createTable(g_szTable+iTable*4); - pNdbSchemaOp->createAttribute("PK", TupleKey); - for(Uint32 iAttr=0; iAttrcreateAttribute(g_szAttribute+iAttr*4, NoKey); - } - - pNdbSchemaCon->execute(); - pNdb->closeSchemaTransaction(pNdbSchemaCon); - */ - } -} - - -int InsertTransaction(Ndb* pNdb, const Uint32 iPart, const bool bIndex) -{ - int iExec = -1; - int iCode = -1; - NdbConnection* pNdbConnection = pNdb->startTransaction(); - if(pNdbConnection) - { - for(Uint32 iTable=0; iTablegetNdbIndexOperation(g_szIndex+iTable*4, g_szTable+iTable*4); - pNdbIndexOperation->insertTuple(); - Uint32 nPK = iPart*g_nTuple + iTuple; - pNdbIndexOperation->equal("PK", nPK); - for(Uint32 iAttr=0; iAttrsetValue(g_szAttribute+iAttr*4, nValue); - } - } - else - { - NdbOperation* pNdbOperation = pNdbConnection->getNdbOperation(g_szTable+iTable*4); - pNdbOperation->insertTuple(); - Uint32 nPK = iPart*g_nTuple + iTuple; - pNdbOperation->equal("PK", nPK); - for(Uint32 iAttr=0; iAttrsetValue(g_szAttribute+iAttr*4, nValue); - } - } - } - } - iExec = pNdbConnection->execute_ok(Commit); - if (iExec == -1) - { - ndbout << pNdbConnection->getNdbError() << endl; - } - pNdb->closeTransaction(pNdbConnection); - } - return 0; -} - - -int UpdateGetAndSetTransaction(Ndb* pNdb, const Uint32 iPart, const bool bIndex) -{ - int iExec = -1; - int iCode = -1; - NdbRecAttr** ppNdbRecAttr = new NdbRecAttr*[g_nTable*g_nTuple*g_nAttribute]; - NdbConnection* pNdbConnection = pNdb->startTransaction(); - if(pNdbConnection) - { - for(Uint32 iTable=0; iTablegetNdbIndexOperation(g_szIndex+iTable*4, g_szTable+iTable*4); - pNdbIndexOperation->readTupleExclusive(); - Uint32 nPK = iPart*g_nTuple + iTuple; - pNdbIndexOperation->equal("PK", nPK); - for(Uint32 iAttr=0; iAttrgetValue(g_szAttribute+iAttr*4); - } - } - else - { - NdbOperation* pNdbOperation = pNdbConnection->getNdbOperation(g_szTable+iTable*4); - pNdbOperation->readTupleExclusive(); - Uint32 nPK = iPart*g_nTuple + iTuple; - pNdbOperation->equal("PK", nPK); - for(Uint32 iAttr=0; iAttrgetValue(g_szAttribute+iAttr*4); - } - } - } - } - iExec = pNdbConnection->execute_ok(NoCommit); - if( iExec == -1) - { - ndbout << pNdbConnection->getNdbError() << endl; - } - } - iCode = pNdbConnection->getNdbError().code; - if(iExec==0) - { - for(Uint32 iTable=0; iTablegetNdbIndexOperation(g_szIndex+iTable*4, g_szTable+iTable*4); - pNdbIndexOperation->updateTuple(); - Uint32 nPK = iPart*g_nTuple + iTuple; - pNdbIndexOperation->equal("PK", nPK); - for(Uint32 iAttr=0; iAttru_32_value() + 1; - pNdbIndexOperation->setValue(g_szAttribute+iAttr*4, nValue); - } - } - else - { - NdbOperation* pNdbOperation = pNdbConnection->getNdbOperation(g_szTable+iTable*4); - pNdbOperation->updateTuple(); - Uint32 nPK = iPart*g_nTuple + iTuple; - pNdbOperation->equal("PK", nPK); - for(Uint32 iAttr=0; iAttru_32_value() + 1; - pNdbOperation->setValue(g_szAttribute+iAttr*4, nValue); - } - } - } - } - iExec = pNdbConnection->execute(Commit); - if (iExec == -1) - { - ndbout << pNdbConnection->getNdbError() << endl; - } - pNdb->closeTransaction(pNdbConnection); - } - delete[] ppNdbRecAttr; - return 0; -} - - -int UpdateInterpretedTransaction(Ndb* pNdb, const Uint32 iPart, const bool bIndex) -{ - int iExec = -1; - int iCode = -1; - NdbConnection* pNdbConnection = pNdb->startTransaction(); - if(pNdbConnection) - { - for(Uint32 iTable=0; iTablegetNdbIndexOperation(g_szIndex+iTable*4, g_szTable+iTable*4); - pNdbIndexOperation->interpretedUpdateTuple(); - Uint32 nPK = iPart*g_nTuple + iTuple; - pNdbIndexOperation->equal("PK", nPK); - for(Uint32 iAttr=0; iAttrincValue(g_szAttribute+iAttr*4, (Uint32)1); - } - } - else - { - NdbOperation* pNdbOperation = pNdbConnection->getNdbOperation(g_szTable+iTable*4); - pNdbOperation->interpretedUpdateTuple(); - Uint32 nPK = iPart*g_nTuple + iTuple; - pNdbOperation->equal("PK", nPK); - for(Uint32 iAttr=0; iAttrincValue(g_szAttribute+iAttr*4, (Uint32)1); - } - } - } - } - iExec = pNdbConnection->execute_ok(Commit); - - if (iExec == -1) - { - ndbout << pNdbConnection->getNdbError() << endl; - } - pNdb->closeTransaction(pNdbConnection); - } - return 0; -} - - -void ReportInconsistency (const Uint32 iPart, - const Uint32 iTable, - const Uint32 iTuple, - const Uint32 iAttr, - const Uint32 nValue, - const Uint32 nExpected ) -{ - ndbout << "INCONSISTENCY: "; - ndbout << "Part " << iPart; - ndbout << ", Table " << iTable; - ndbout << ", Tuple " << iTuple; - ndbout << ", Attr " << iAttr; - ndbout << ", Value " << nValue; - ndbout << ", Expected " << nExpected; - ndbout << endl; -} - - -int ReadTransaction(Ndb* pNdb, const Uint32 iPart, const bool bIndex) -{ - int iExec = -1; - int iCode = -1; - NdbRecAttr** ppNdbRecAttr = new NdbRecAttr*[g_nTable*g_nTuple*g_nAttribute]; - NdbConnection* pNdbConnection = pNdb->startTransaction(); - if(pNdbConnection) - { - for(Uint32 iTable=0; iTablegetNdbIndexOperation(g_szIndex+iTable*4, g_szTable+iTable*4); - pNdbIndexOperation->readTuple(); - Uint32 nPK = iPart*g_nTuple + iTuple; - pNdbIndexOperation->equal("PK", nPK); - for(Uint32 iAttr=0; iAttrgetValue(g_szAttribute+iAttr*4); - } - } - else - { - NdbOperation* pNdbOperation = pNdbConnection->getNdbOperation(g_szTable+iTable*4); - pNdbOperation->readTuple(); - Uint32 nPK = iPart*g_nTuple + iTuple; - pNdbOperation->equal("PK", nPK); - for(Uint32 iAttr=0; iAttrgetValue(g_szAttribute+iAttr*4); - } - } - } - } - iExec = pNdbConnection->execute_ok(Commit); - if (iExec == -1) - { - ndbout << pNdbConnection->getNdbError() << endl; - } - if(iExec==0) - { - Uint32 nValue0 = ppNdbRecAttr[0]->u_32_value(); - for(Uint32 iTable=0; iTableu_32_value(); - Uint32 nExpected = nValue0 + (iTable*g_nTuple+iTuple)*g_nAttribute+iAttr; - if(nValue!=nExpected) - { - ReportInconsistency(iPart, iTable, iTuple, iAttr, nValue, nExpected); - } - } - } - } - } - pNdb->closeTransaction(pNdbConnection); - } - return 0; -} - - -int DeleteTransaction(Ndb* pNdb, const Uint32 iPart, const bool bIndex) -{ - int iExec = -1; - int iCode = -1; - NdbConnection* pNdbConnection = pNdb->startTransaction(); - if(pNdbConnection) - { - for(Uint32 iTable=0; iTablegetNdbIndexOperation(g_szIndex+iTable*4, g_szTable+iTable*4); - pNdbIndexOperation->deleteTuple(); - Uint32 nPK = iPart*g_nTuple + iTuple; - pNdbIndexOperation->equal("PK", nPK); - } - else - { - NdbOperation* pNdbOperation = pNdbConnection->getNdbOperation(g_szTable+iTable*4); - pNdbOperation->deleteTuple(); - Uint32 nPK = iPart*g_nTuple + iTuple; - pNdbOperation->equal("PK", nPK); - } - } - } - iExec = pNdbConnection->execute_ok(Commit); - - if (iExec == -1) - { - ndbout << pNdbConnection->getNdbError() << endl; - } - pNdb->closeTransaction(pNdbConnection); - } - return 0; -} - - -extern "C" void* ThreadFunc(void*) -{ - Ndb* pNdb = new Ndb("TEST_DB"); - pNdb->init(); - pNdb->waitUntilReady(); - - MT19937 rndgen; - rndgen.sgenrand((unsigned long)pNdb); - - Uint32 nInsertError = 0; - Uint32 nInsertCommit = 0; - Uint32 nInsertRollback = 0; - Uint32 nUpdateGetAndSetError = 0; - Uint32 nUpdateGetAndSetCommit = 0; - Uint32 nUpdateGetAndSetRollback = 0; - Uint32 nReadError = 0; - Uint32 nReadCommit = 0; - Uint32 nReadRollback = 0; - Uint32 nUpdateInterpretedError = 0; - Uint32 nUpdateInterpretedCommit = 0; - Uint32 nUpdateInterpretedRollback = 0; - Uint32 nDeleteError = 0; - Uint32 nDeleteCommit = 0; - Uint32 nDeleteRollback = 0; - - if (g_bVerify) - { - for (Uint32 iPart = 0; iPart < g_nPart; iPart++) - { - switch(ReadTransaction(pNdb, iPart, false)) - { - case -1: ++nReadError; break; - case 0: ++nReadCommit; break; - case 1: ++nReadRollback; break; - } - } - } - else - while(NdbMutex_Trylock(g_pNdbMutexStop)) - { - Uint32 iPart = rndgen.genrand() % g_nPart; - Uint32 iTrans = rndgen.genrand() % 5; - bool bIndex = ((rndgen.genrand() & 1) ? true : false); - switch(iTrans) - { - case 0: - switch(InsertTransaction(pNdb, iPart, bIndex)) - { - case -1: ++nInsertError; break; - case 0: ++nInsertCommit; break; - case 1: ++nInsertRollback; break; - } - break; - - case 1: - switch(UpdateGetAndSetTransaction(pNdb, iPart, bIndex)) - { - case -1: ++nUpdateGetAndSetError; break; - case 0: ++nUpdateGetAndSetCommit; break; - case 1: ++nUpdateGetAndSetRollback; break; - } - break; - - case 2: - switch(ReadTransaction(pNdb, iPart, bIndex)) - { - case -1: ++nReadError; break; - case 0: ++nReadCommit; break; - case 1: ++nReadRollback; break; - } - break; - - case 3: - switch(UpdateInterpretedTransaction(pNdb, iPart, bIndex)) - { - case -1: ++nUpdateInterpretedError; break; - case 0: ++nUpdateInterpretedCommit; break; - case 1: ++nUpdateInterpretedRollback; break; - } - break; - - case 4: - switch(DeleteTransaction(pNdb, iPart, bIndex)) - { - case -1: ++nDeleteError; break; - case 0: ++nDeleteCommit; break; - case 1: ++nDeleteRollback; break; - } - break; - } - } - - ndbout << "I:" << nInsertError << ":" << nInsertCommit << ":" << nInsertRollback; - ndbout << " UG:" << nUpdateGetAndSetError << ":" << nUpdateGetAndSetCommit << ":" << nUpdateGetAndSetRollback; - ndbout << " R:" << nReadError << ":" << nReadCommit << ":" << nReadRollback; - ndbout << " UI:" << nUpdateInterpretedError << ":" << nUpdateInterpretedCommit << ":" << nUpdateInterpretedRollback; - ndbout << " D:" << nDeleteError << ":" << nDeleteCommit << ":" << nDeleteRollback << endl; - ndbout << endl; - - NdbMutex_Unlock(g_pNdbMutexStop); - delete pNdb; - return 0; -} - - -int main(int argc, char* argv[]) -{ - Uint32 nSeconds = 1; - Uint32 nThread = 1; - - for(int iArg=1; iArginit(); - pNdb->waitUntilReady(); - - if (!g_bVerify) CreateTables(pNdb); - g_pNdbMutexStop = NdbMutex_Create(); - NdbMutex_Lock(g_pNdbMutexStop); - - NdbThread_SetConcurrencyLevel(nThread+1); - NdbThread** ppNdbThread = new NdbThread*[nThread]; - for(Uint32 iThread=0; iThreadnStartingRecordNum; + + HRESULT hr = CoInitialize(NULL); + if(FAILED(hr)) + { + printf("Error Initializing COM Library\n"); + return (int)hr; + } + + _ConnectionPtr cn = NULL; + _CommandPtr cmdUpdate = NULL, cmdInsert = NULL, cmdDelete = NULL, cmdSelect = NULL; + _RecordsetPtr rs = NULL; + _ParameterPtr paramContextID = NULL; + _ParameterPtr paramVersion = NULL; + _ParameterPtr paramLockFlag = NULL; + _ParameterPtr ttparamLockFlag = NULL; + _ParameterPtr paramLockTime = NULL; + _ParameterPtr paramLockTimeUSec = NULL; + _ParameterPtr paramContextData = NULL; + _variant_t vtVersion; + _variant_t vtLockFlag; + _variant_t vtLockTime; + _variant_t vtLockTimeUSec; + _variant_t vtContextData; + // Initialize Values + vtVersion = CALL_CONTEXT_VERSION; + vtLockFlag = CALL_CONTEXT_LOCK_FLAG; + vtLockTime = CALL_CONTEXT_LOCK_TIME; + vtLockTimeUSec = CALL_CONTEXT_LOCK_TIME_USEC; + vtContextData = STATUS_DATA; + + LARGE_INTEGER freq; + + DWORD dwStartTime, dwEndTime; + LARGE_INTEGER liStartTime, liEndTime; + + try + { + cn.CreateInstance(__uuidof(Connection)); + cn->ConnectionString = _T("DSN=TTTelcoCS;"); + cn->Open(_T(""),_T(""),_T(""),adConnectUnspecified); + + cmdUpdate.CreateInstance(__uuidof(Command)); + cmdInsert.CreateInstance(__uuidof(Command)); + cmdDelete.CreateInstance(__uuidof(Command)); + cmdSelect.CreateInstance(__uuidof(Command)); + + TCHAR tszInsert[10000], tszUpdate[10000]; + memset(tszInsert, 0, sizeof(tszInsert)); + memset(tszUpdate, 0, sizeof(tszUpdate)); + strcpy(tszInsert, "INSERT INTO dbo.CallContext(ContextId,Version,LockFlag,LockTime,LockTimeUSec,ContextData) VALUES(?,?,?,?,?,'"); + strcat(tszInsert, STATUS_DATA); + strcat(tszInsert, "')"); + + cmdInsert->CommandText= tszInsert; + cmdInsert->ActiveConnection = cn; + cmdInsert->Prepared = TRUE; + + + strcpy(tszUpdate, "UPDATE dbo.CallContext SET ContextData = '"); + strcat(tszUpdate, STATUS_DATA); + strcat(tszUpdate, "' WHERE ContextId = ?"); + cmdUpdate->CommandText= tszUpdate; + cmdUpdate->ActiveConnection = cn; + cmdUpdate->Prepared = TRUE; + + cmdDelete->CommandText=_T("DELETE FROM dbo.CallContext WHERE ContextId = ?"); + cmdDelete->ActiveConnection = cn; + cmdDelete->Prepared = TRUE; + + cmdSelect->CommandText=_T("SELECT ContextData FROM dbo.CallContext WHERE ContextId = ?"); + cmdSelect->ActiveConnection = cn; + cmdSelect->Prepared = TRUE; + + + //Create params + paramContextID = cmdInsert->CreateParameter(_T("ContextID"),adInteger,adParamInput,sizeof(int),nStartingRecordID); + paramVersion = cmdInsert->CreateParameter(_T("Version"),adInteger,adParamInput,sizeof(int),1);//vtVersion); + paramLockFlag = cmdInsert->CreateParameter(_T("LockFlag"),adInteger,adParamInput,sizeof(int),1);//vtLockFlag); + ttparamLockFlag = cmdUpdate->CreateParameter(_T("LockFlag"),adInteger,adParamInput,sizeof(int),1);//vtLockFlag); + paramLockTime = cmdInsert->CreateParameter(_T("LockTime"),adInteger,adParamInput,sizeof(int),1);//vtLockTime); + paramLockTimeUSec = cmdInsert->CreateParameter(_T("LockTimeUSec"),adInteger,adParamInput,sizeof(int),1);//vtLockTimeUSec); + paramContextData = cmdInsert->CreateParameter(_T("ContextData"), adBSTR, adParamInput, SysStringByteLen(vtContextData.bstrVal), vtContextData); + //paramContextData->put_Value(vtContextData); + + + + //Append params + cmdInsert->Parameters->Append(paramContextID); + cmdInsert->Parameters->Append(paramVersion); + cmdInsert->Parameters->Append(paramLockFlag); + cmdInsert->Parameters->Append(paramLockTime); + cmdInsert->Parameters->Append(paramLockTimeUSec); + //cmdInsert->Parameters->Append(paramContextData); + + + cmdUpdate->Parameters->Append(paramContextID); + //cmdUpdate->Parameters->Append(paramContextID); + + cmdSelect->Parameters->Append(paramContextID); + + cmdDelete->Parameters->Append(paramContextID); + + while(WaitForSingleObject(pData->hShutdownEvent,0) != WAIT_OBJECT_0) + { + paramContextID->Value = nStartingRecordID++; + + bool bTimeLatency = (nStartingRecordID == 100) ? TRUE : FALSE; + + if (bTimeLatency) + { + BOOL bSuccess = QueryPerformanceFrequency(&freq); + if (!bSuccess) + printf("Error retrieving frequency: %d\n", GetLastError()); + + } + + + + for (int i=0; i < 20; i++) + { + switch(i) + { + case 3: + case 6: + case 9: + case 11: + case 12: + case 15: + case 18: // Query Record + if (bTimeLatency) + QueryPerformanceCounter(&liStartTime); + + cmdSelect->Execute(NULL, NULL, -1); + if (bTimeLatency) + { + QueryPerformanceCounter(&liEndTime); + printf("Read = %d msec.\n", (liEndTime.QuadPart - liStartTime.QuadPart) / (freq.QuadPart/1000)); + } + break; + case 19: // Delete Record + if (bTimeLatency) + QueryPerformanceCounter(&liStartTime); + cmdDelete->Execute(NULL,NULL,adExecuteNoRecords); + if (bTimeLatency) + { + QueryPerformanceCounter(&liEndTime); + printf("Delete = %d msec.\n", (liEndTime.QuadPart - liStartTime.QuadPart) / (freq.QuadPart/1000)); + } + break; + case 0: // Insert Record + if (bTimeLatency) + QueryPerformanceCounter(&liStartTime); + cmdInsert->Execute(NULL,NULL,adExecuteNoRecords); + if (bTimeLatency) + { + QueryPerformanceCounter(&liEndTime); + printf("Insert = %d msec.\n", (liEndTime.QuadPart - liStartTime.QuadPart) / (freq.QuadPart/1000)); + } + break; + default: // Update Record + if (bTimeLatency) + QueryPerformanceCounter(&liStartTime); + cmdUpdate->Execute(NULL,NULL,adExecuteNoRecords); + if (bTimeLatency) + { + QueryPerformanceCounter(&liEndTime); + printf("Update = %d msec.\n", (liEndTime.QuadPart - liStartTime.QuadPart) / (freq.QuadPart/1000)); + } + + break; + } + } + + nNumCallsProcessed++; + + InterlockedIncrement(pData->pnNumCallsProcessed); + } + + cn->Close(); + } + catch(_com_error &e) + { + printf("%d: \n\t%s\n\t%s\n", + e.Error(), + e.ErrorMessage(), + e.Source()); + + } + + return 0; +} + + +int _tmain(int argc, _TCHAR* argv[]) +{ + long nNumThreads=4; + long nSeed = 0; + if(lstrcmp(argv[1],_T("/?")) == 0) + { + _tprintf(_T("InsertRecs [No.Of Threads] [Record Seed No.]\n")); + return 0; + } + + if(argc > 1) + nNumThreads = _ttol(argv[1]); + else + nNumThreads = 4; + if (argc > 2) + nSeed = _ttol(argv[2]); + _tprintf(_T("Num of Threads = %d, Seed = %d"), nNumThreads, nSeed); + + long nNumCallsProcessed = 0; + + SetConsoleCtrlHandler(ConsoleCtrlHandler,true); + hShutdownEvent = CreateEvent(NULL,TRUE,FALSE,NULL); + + DWORD dwStartTime = GetTickCount(); + + DWORD dwThreadID = 0; + HANDLE hThreads[50]; + + struct _ParamStruct params[50]; + + + for(int ij=0;ij + +#include "dbGenerator.h" +#include +#include +#include + +/*************************************************************** +* L O C A L C O N S T A N T S * +***************************************************************/ + +/*************************************************************** +* L O C A L D A T A S T R U C T U R E S * +***************************************************************/ + +/*************************************************************** +* L O C A L F U N C T I O N S * +***************************************************************/ + +static void getRandomSubscriberNumber(SubscriberNumber number); +static void getRandomServerId(ServerId *serverId); +static void getRandomChangedBy(ChangedBy changedBy); +static void getRandomChangedTime(ChangedTime changedTime); + +static void clearTransaction(TransactionDefinition *trans); +static void initGeneratorStatistics(GeneratorStatistics *gen); + +static void doOneTransaction(ThreadData * td, + int parallellism, + int millisSendPoll, + int minEventSendPoll, + int forceSendPoll); +static void doTransaction_T1(Ndb * pNDB, ThreadData * td, int async); +static void doTransaction_T2(Ndb * pNDB, ThreadData * td, int async); +static void doTransaction_T3(Ndb * pNDB, ThreadData * td, int async); +static void doTransaction_T4(Ndb * pNDB, ThreadData * td, int async); +static void doTransaction_T5(Ndb * pNDB, ThreadData * td, int async); + +/*************************************************************** +* L O C A L D A T A * +***************************************************************/ + +static SequenceValues transactionDefinition[] = { + {25, 1}, + {25, 2}, + {20, 3}, + {15, 4}, + {15, 5}, + {0, 0} +}; + +static SequenceValues rollbackDefinition[] = { + {98, 0}, + {2 , 1}, + {0, 0} +}; + +static int maxsize = 0; + +/*************************************************************** +* P U B L I C D A T A * +***************************************************************/ + +/*************************************************************** +**************************************************************** +* L O C A L F U N C T I O N S C O D E S E C T I O N * +**************************************************************** +***************************************************************/ + +static void getRandomSubscriberNumber(SubscriberNumber number) +{ + uint32 tmp; + char sbuf[SUBSCRIBER_NUMBER_LENGTH + 1]; + tmp = myRandom48(NO_OF_SUBSCRIBERS); + sprintf(sbuf, "%.*d", SUBSCRIBER_NUMBER_LENGTH, tmp); + memcpy(number, sbuf, SUBSCRIBER_NUMBER_LENGTH); +} + +static void getRandomServerId(ServerId *serverId) +{ + *serverId = myRandom48(NO_OF_SERVERS); +} + +static void getRandomChangedBy(ChangedBy changedBy) +{ + memset(changedBy, myRandom48(26)+'A', CHANGED_BY_LENGTH); + changedBy[CHANGED_BY_LENGTH] = 0; +} + +static void getRandomChangedTime(ChangedTime changedTime) +{ + memset(changedTime, myRandom48(26)+'A', CHANGED_TIME_LENGTH); + changedTime[CHANGED_TIME_LENGTH] = 0; +} + +static void clearTransaction(TransactionDefinition *trans) +{ + trans->count = 0; + trans->branchExecuted = 0; + trans->rollbackExecuted = 0; + trans->latencyCounter = myRandom48(127); + trans->latency.reset(); +} + +static int listFull(SessionList *list) +{ + return(list->numberInList == SESSION_LIST_LENGTH); +} + +static int listEmpty(SessionList *list) +{ + return(list->numberInList == 0); +} + +static void insertSession(SessionList *list, + SubscriberNumber number, + ServerId serverId) +{ + SessionElement *e; + if( listFull(list) ) return; + + e = &list->list[list->writeIndex]; + + strcpy(e->subscriberNumber, number); + e->serverId = serverId; + + list->writeIndex = (list->writeIndex + 1) % SESSION_LIST_LENGTH; + list->numberInList++; + + if( list->numberInList > maxsize ) + maxsize = list->numberInList; +} + +static SessionElement *getNextSession(SessionList *list) +{ + if( listEmpty(list) ) return(0); + + return(&list->list[list->readIndex]); +} + +static void deleteSession(SessionList *list) +{ + if( listEmpty(list) ) return; + + list->readIndex = (list->readIndex + 1) % SESSION_LIST_LENGTH; + list->numberInList--; +} + +static void initGeneratorStatistics(GeneratorStatistics *gen) +{ + int i; + + if( initSequence(&gen->transactionSequence, + transactionDefinition) != 0 ) { + ndbout_c("could not set the transaction types"); + exit(0); + } + + if( initSequence(&gen->rollbackSequenceT4, + rollbackDefinition) != 0 ) { + ndbout_c("could not set the rollback sequence"); + exit(0); + } + + if( initSequence(&gen->rollbackSequenceT5, + rollbackDefinition) != 0 ) { + ndbout_c("could not set the rollback sequence"); + exit(0); + } + + for(i = 0; i < NUM_TRANSACTION_TYPES; i++ ) + clearTransaction(&gen->transactions[i]); + + gen->totalTransactions = 0; + + gen->activeSessions.numberInList = 0; + gen->activeSessions.readIndex = 0; + gen->activeSessions.writeIndex = 0; +} + + +static +void +doOneTransaction(ThreadData * td, int p, int millis, int minEvents, int force) +{ + int i; + unsigned int transactionType; + int async = 1; + if (p == 1) { + async = 0; + }//if + for(i = 0; isendPollNdb(millis, minEvents, force); + }//if +} + +static +void +doTransaction_T1(Ndb * pNDB, ThreadData * td, int async) +{ + /*----------------*/ + /* Init arguments */ + /*----------------*/ + getRandomSubscriberNumber(td->transactionData.number); + getRandomChangedBy(td->transactionData.changed_by); + snprintf(td->transactionData.changed_time, + sizeof(td->transactionData.changed_time), + "%ld - %d", td->changedTime++, myRandom48(65536*1024)); + //getRandomChangedTime(td->transactionData.changed_time); + td->transactionData.location = td->transactionData.changed_by[0]; + + /*-----------------*/ + /* Run transaction */ + /*-----------------*/ + td->runState = Running; + td->generator.transactions[0].startLatency(); + + start_T1(pNDB, td, async); +} + +static +void +doTransaction_T2(Ndb * pNDB, ThreadData * td, int async) +{ + /*----------------*/ + /* Init arguments */ + /*----------------*/ + getRandomSubscriberNumber(td->transactionData.number); + + /*-----------------*/ + /* Run transaction */ + /*-----------------*/ + td->runState = Running; + td->generator.transactions[1].startLatency(); + + start_T2(pNDB, td, async); +} + +static +void +doTransaction_T3(Ndb * pNDB, ThreadData * td, int async) +{ + SessionElement *se; + + /*----------------*/ + /* Init arguments */ + /*----------------*/ + se = getNextSession(&td->generator.activeSessions); + if( se ) { + strcpy(td->transactionData.number, se->subscriberNumber); + td->transactionData.server_id = se->serverId; + td->transactionData.sessionElement = 1; + } else { + getRandomSubscriberNumber(td->transactionData.number); + getRandomServerId(&td->transactionData.server_id); + td->transactionData.sessionElement = 0; + } + + td->transactionData.server_bit = (1 << td->transactionData.server_id); + + /*-----------------*/ + /* Run transaction */ + /*-----------------*/ + td->runState = Running; + td->generator.transactions[2].startLatency(); + start_T3(pNDB, td, async); +} + +static +void +doTransaction_T4(Ndb * pNDB, ThreadData * td, int async) +{ + /*----------------*/ + /* Init arguments */ + /*----------------*/ + getRandomSubscriberNumber(td->transactionData.number); + getRandomServerId(&td->transactionData.server_id); + + td->transactionData.server_bit = (1 << td->transactionData.server_id); + td->transactionData.do_rollback = + getNextRandom(&td->generator.rollbackSequenceT4); + +#if 0 + memset(td->transactionData.session_details, + myRandom48(26)+'A', SESSION_DETAILS_LENGTH); +#endif + td->transactionData.session_details[SESSION_DETAILS_LENGTH] = 0; + + /*-----------------*/ + /* Run transaction */ + /*-----------------*/ + td->runState = Running; + td->generator.transactions[3].startLatency(); + start_T4(pNDB, td, async); +} + +static +void +doTransaction_T5(Ndb * pNDB, ThreadData * td, int async) +{ + SessionElement * se; + se = getNextSession(&td->generator.activeSessions); + if( se ) { + strcpy(td->transactionData.number, se->subscriberNumber); + td->transactionData.server_id = se->serverId; + td->transactionData.sessionElement = 1; + } + else { + getRandomSubscriberNumber(td->transactionData.number); + getRandomServerId(&td->transactionData.server_id); + td->transactionData.sessionElement = 0; + } + + td->transactionData.server_bit = (1 << td->transactionData.server_id); + td->transactionData.do_rollback + = getNextRandom(&td->generator.rollbackSequenceT5); + + /*-----------------*/ + /* Run transaction */ + /*-----------------*/ + td->runState = Running; + td->generator.transactions[4].startLatency(); + start_T5(pNDB, td, async); +} + +void +complete_T1(ThreadData * data){ + data->generator.transactions[0].stopLatency(); + data->generator.transactions[0].count++; + + data->runState = Runnable; + data->generator.totalTransactions++; +} + +void +complete_T2(ThreadData * data){ + data->generator.transactions[1].stopLatency(); + data->generator.transactions[1].count++; + + data->runState = Runnable; + data->generator.totalTransactions++; +} + +void +complete_T3(ThreadData * data){ + + data->generator.transactions[2].stopLatency(); + data->generator.transactions[2].count++; + + if(data->transactionData.branchExecuted) + data->generator.transactions[2].branchExecuted++; + + data->runState = Runnable; + data->generator.totalTransactions++; +} + +void +complete_T4(ThreadData * data){ + + data->generator.transactions[3].stopLatency(); + data->generator.transactions[3].count++; + + if(data->transactionData.branchExecuted) + data->generator.transactions[3].branchExecuted++; + if(data->transactionData.do_rollback) + data->generator.transactions[3].rollbackExecuted++; + + if(data->transactionData.branchExecuted && + !data->transactionData.do_rollback){ + insertSession(&data->generator.activeSessions, + data->transactionData.number, + data->transactionData.server_id); + } + + data->runState = Runnable; + data->generator.totalTransactions++; + +} +void +complete_T5(ThreadData * data){ + + data->generator.transactions[4].stopLatency(); + data->generator.transactions[4].count++; + + if(data->transactionData.branchExecuted) + data->generator.transactions[4].branchExecuted++; + if(data->transactionData.do_rollback) + data->generator.transactions[4].rollbackExecuted++; + + if(data->transactionData.sessionElement && + !data->transactionData.do_rollback){ + deleteSession(&data->generator.activeSessions); + } + + data->runState = Runnable; + data->generator.totalTransactions++; +} + +/*************************************************************** +**************************************************************** +* P U B L I C F U N C T I O N S C O D E S E C T I O N * +**************************************************************** +***************************************************************/ +void +asyncGenerator(ThreadData *data, + int parallellism, + int millisSendPoll, + int minEventSendPoll, + int forceSendPoll) +{ + ThreadData * startUp; + + GeneratorStatistics *st; + double periodStop; + double benchTimeStart; + double benchTimeEnd; + int i, j, done; + + myRandom48Init(data->randomSeed); + + for(i = 0; isendPollNdb(); + } + } + ndbout_c("Benchmark period starts"); + + /*-------------------------*/ + /* normal benchmark period */ + /*-------------------------*/ + benchTimeStart = userGetTime(); + + periodStop = benchTimeStart + (double)data[0].testSeconds; + while(userGetTime() < periodStop) + doOneTransaction(data, parallellism, + millisSendPoll, minEventSendPoll, forceSendPoll); + + benchTimeEnd = userGetTime(); + + ndbout_c("Benchmark period done"); + + /** + * Wait for all transactions + */ + done = 0; + while(!done){ + done = 1; + for(i = 0; isendPollNdb(); + } + } + + /*------------------*/ + /* cool down period */ + /*------------------*/ + periodStop = userGetTime() + (double)data[0].coolDownSeconds; + while(userGetTime() < periodStop){ + doOneTransaction(startUp, parallellism, + millisSendPoll, minEventSendPoll, forceSendPoll); + } + + done = 0; + while(!done){ + done = 1; + for(i = 0; isendPollNdb(); + } + } + + + /*---------------------------------------------------------*/ + /* add the times for all transaction for inner loop timing */ + /*---------------------------------------------------------*/ + for(j = 0; jouterLoopTime = benchTimeEnd - benchTimeStart; + st->outerTps = getTps(st->totalTransactions, st->outerLoopTime); + } + /* ndbout_c("maxsize = %d\n",maxsize); */ + + free(startUp); +} + diff --git a/ndb/test/ndbapi/bank/Bank.cpp b/ndb/test/ndbapi/bank/Bank.cpp new file mode 100644 index 00000000000..14883205693 --- /dev/null +++ b/ndb/test/ndbapi/bank/Bank.cpp @@ -0,0 +1,2458 @@ +/* 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 */ + +#include "Bank.hpp" +#include +#include +#include + +Bank::Bank(): + m_ndb("BANK"), + m_maxAccount(-1), + m_initialized(false) +{ + +} + +int Bank::init(){ + if (m_initialized == true) + return NDBT_OK; + + myRandom48Init(NdbTick_CurrentMillisecond()); + + m_ndb.init(); + while (m_ndb.waitUntilReady(10) != 0) + ndbout << "Waiting for ndb to be ready" << endl; + + if (getNumAccounts() != NDBT_OK) + return NDBT_FAILED; + return NDBT_OK; +} + +int Bank::performTransactions(int maxSleepBetweenTrans, int yield){ + + if (init() != NDBT_OK) + return NDBT_FAILED; + int transactions = 0; + + while(1){ + + while(m_ndb.waitUntilReady(10) != 0) + ndbout << "Waiting for ndb to be ready" << endl; + + while(performTransaction() != NDBT_FAILED){ + transactions++; + + if (maxSleepBetweenTrans > 0){ + int val = myRandom48(maxSleepBetweenTrans); + NdbSleep_MilliSleep(val); + } + + if((transactions % 100) == 0) + g_info << transactions << endl; + + if (yield != 0 && transactions >= yield) + return NDBT_OK; + } + } + return NDBT_FAILED; + +} + +int Bank::performTransaction(){ + int result = NDBT_OK; + + if (m_maxAccount <= 0){ + g_err << "No accounts in bank" << endl; + return NDBT_FAILED; + } + + int fromAccount = myRandom48(m_maxAccount); + int toAccount = myRandom48(m_maxAccount); + + if (fromAccount == toAccount){ + // Increase toAccount with 1 + toAccount = (toAccount+1)%m_maxAccount; + } + + int maxAmount = getMaxAmount(); + + int amount = myRandom48(maxAmount); + + retry_transaction: + int res = performTransaction(fromAccount, toAccount, amount); + if (res != 0){ + switch (res){ + case NDBT_FAILED: + g_err << "performTransaction returned NDBT_FAILED" << endl + << " fromAccount = " << fromAccount << endl + << " toAccount = " << toAccount << endl + << " amount = " << amount << endl; + result = NDBT_FAILED; + break; + case NOT_ENOUGH_FUNDS: + // ndbout << "performTransaction returned NOT_ENOUGH_FUNDS" << endl; + break; + case NDBT_TEMPORARY: + g_err << "TEMPORARY_ERRROR retrying" << endl; + goto retry_transaction; + break; + default: + g_info << "performTransaction returned "<getNdbOperation("ACCOUNT"); + if (pOp == NULL) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp->readTupleExclusive(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp->equal("ACCOUNT_ID", fromAccountId); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + NdbRecAttr* balanceFromRec = pOp->getValue("BALANCE"); + if( balanceFromRec ==NULL ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + NdbRecAttr* fromAccountTypeRec = pOp->getValue("ACCOUNT_TYPE"); + if( fromAccountTypeRec == NULL ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pTrans->execute(NoCommit); + if( check == -1 ) { + const NdbError err = pTrans->getNdbError(); + m_ndb.closeTransaction(pTrans); + if (err.status == NdbError::TemporaryError){ + ERR(err); + return NDBT_TEMPORARY; + } + ERR(err); + return NDBT_FAILED; + } + + Uint32 balanceFrom = balanceFromRec->u_32_value(); + // ndbout << "balanceFrom: " << balanceFrom << endl; + + if (((Int64)balanceFrom - amount) < 0){ + m_ndb.closeTransaction(pTrans); + //ndbout << "Not enough funds" << endl; + return NOT_ENOUGH_FUNDS; + } + + Uint32 fromAccountType = fromAccountTypeRec->u_32_value(); + + /** + * Read balance on to account + */ + NdbOperation* pOp6 = pTrans->getNdbOperation("ACCOUNT"); + if (pOp6 == NULL) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp6->readTupleExclusive(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp6->equal("ACCOUNT_ID", toAccountId); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + NdbRecAttr* balanceToRec = pOp6->getValue("BALANCE"); + if( balanceToRec == NULL ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + NdbRecAttr* toAccountTypeRec = pOp6->getValue("ACCOUNT_TYPE"); + if( toAccountTypeRec == NULL ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pTrans->execute(NoCommit); + if( check == -1 ) { + const NdbError err = pTrans->getNdbError(); + m_ndb.closeTransaction(pTrans); + if (err.status == NdbError::TemporaryError){ + ERR(err); + return NDBT_TEMPORARY; + } + ERR(err); + return NDBT_FAILED; + } + + Uint32 balanceTo = balanceToRec->u_32_value(); + // ndbout << "balanceTo: " << balanceTo << endl; + Uint32 toAccountType = toAccountTypeRec->u_32_value(); + + // Ok, all clear to do the transaction + Uint64 transId; + if (getNextTransactionId(transId) != NDBT_OK){ + return NDBT_FAILED; + } + + Uint64 currTime; + if (getCurrTime(currTime) != NDBT_OK){ + return NDBT_FAILED; + } + + /** + * Update balance on from account + */ + NdbOperation* pOp2 = pTrans->getNdbOperation("ACCOUNT"); + if (pOp2 == NULL) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp2->updateTuple(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp2->equal("ACCOUNT_ID", fromAccountId); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp2->setValue("BALANCE", balanceFrom - amount); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + /** + * Update balance on to account + */ + NdbOperation* pOp3 = pTrans->getNdbOperation("ACCOUNT"); + if (pOp3 == NULL) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp3->updateTuple(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp3->equal("ACCOUNT_ID", toAccountId); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp3->setValue("BALANCE", balanceTo + amount); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + /** + * Insert withdrawal transaction + */ + NdbOperation* pOp4 = pTrans->getNdbOperation("TRANSACTION"); + if (pOp4 == NULL) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp4->insertTuple(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp4->equal("TRANSACTION_ID", transId); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp4->equal("ACCOUNT", fromAccountId); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp4->setValue("ACCOUNT_TYPE", fromAccountType); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp4->setValue("OTHER_ACCOUNT", toAccountId); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp4->setValue("TRANSACTION_TYPE", WithDrawal); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp4->setValue("TIME", currTime); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp4->setValue("AMOUNT", amount); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + /** + * Insert deposit transaction + */ + NdbOperation* pOp5 = pTrans->getNdbOperation("TRANSACTION"); + if (pOp5 == NULL) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp5->insertTuple(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp5->equal("TRANSACTION_ID", transId); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp5->equal("ACCOUNT", toAccountId); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp5->setValue("ACCOUNT_TYPE", toAccountType); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp5->setValue("OTHER_ACCOUNT", fromAccountId); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp5->setValue("TRANSACTION_TYPE", Deposit); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp5->setValue("TIME", currTime); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp5->setValue("AMOUNT", amount); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pTrans->execute(Commit); + if( check == -1 ) { + const NdbError err = pTrans->getNdbError(); + m_ndb.closeTransaction(pTrans); + if (err.status == NdbError::TemporaryError){ + ERR(err); + return NDBT_TEMPORARY; + } + ERR(err); + return NDBT_FAILED; + } + + m_ndb.closeTransaction(pTrans); + return NDBT_OK; +} + + + + +int Bank::performMakeGLs(int yield){ + int result; + if (init() != NDBT_OK) + return NDBT_FAILED; + + int counter, maxCounter; + int yieldCounter = 0; + + while (1){ + // Counters to keep tracck of how many + // GLs should be made before performing a validation + counter = 0; + maxCounter = 50 + myRandom48(100); + + while(m_ndb.waitUntilReady(10) != 0) + ndbout << "Waiting for ndb to be ready" << endl; + + /** + * Validate GLs and Transactions for previous days + * + */ + result = performValidateGLs(); + if (result != NDBT_OK){ + if (result == VERIFICATION_FAILED){ + g_err << "performValidateGLs verification failed" << endl; + return NDBT_FAILED; + } + g_info << "performValidateGLs failed" << endl; + continue; + } + + result = performValidatePurged(); + if (result != NDBT_OK){ + if (result == VERIFICATION_FAILED){ + g_err << "performValidatePurged verification failed" << endl; + return NDBT_FAILED; + } + g_info << "performValidatePurged failed" << endl; + continue; + } + + while (1){ + + yieldCounter++; + if (yield != 0 && yieldCounter >= yield) + return NDBT_OK; + + /** + * Find last GL time. + * ( GL record with highest time value) + */ + Uint64 lastGLTime; + if (findLastGL(lastGLTime) != NDBT_OK){ + g_info << "findLastGL failed" << endl; + // Break out of inner while loop + break; + } + + lastGLTime++; + + /** + * If last GL time + 1 is smaller than current time + * perform a GL for that time + */ + Uint64 currTime; + if (getCurrTime(currTime) != NDBT_OK){ + g_info << "getCurrTime failed" << endl; + // Break out of inner while loop + break; + } + if (lastGLTime < currTime){ + counter++; + if (performMakeGL(lastGLTime) != NDBT_OK){ + g_info << "performMakeGL failed" << endl; + // Break out of inner while loop + break; + } + + if (counter > maxCounter){ + // Break out of inner while loop and + // validatePreviousGLs + g_info << "counter("< maxCounter("<getNdbOperation("GL"); + if (pOp == NULL) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + check = pOp->openScanRead(64); + if( check == -1 ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + check = pOp->interpret_exit_ok(); + if( check == -1 ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + NdbRecAttr* timeRec = pOp->getValue("TIME"); + if( timeRec ==NULL ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + check = pScanTrans->executeScan(); + if( check == -1 ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + int eof; + int rows = 0; + eof = pScanTrans->nextScanResult(); + lastTime = 0; + + while(eof == 0){ + rows++; + Uint64 t = timeRec->u_32_value(); + + if (t > lastTime) + lastTime = t; + + eof = pScanTrans->nextScanResult(); + } + if (eof == -1) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + m_ndb.closeTransaction(pScanTrans); + + return NDBT_OK; +} + + +int Bank::performMakeGL(int time){ + g_info << "performMakeGL: " << time << endl; + /** + * Create one GL record for each account type. + * All in the same transaction + */ + // Start transaction + NdbConnection* pTrans = m_ndb.startTransaction(); + if (pTrans == NULL){ + ERR(m_ndb.getNdbError()); + return NDBT_FAILED; + } + for (int i = 0; i < getNumAccountTypes(); i++){ + + if (performMakeGLForAccountType(pTrans, time, i) != NDBT_OK){ + g_err << "performMakeGLForAccountType returned NDBT_FAILED"<execute(Commit) == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + m_ndb.closeTransaction(pTrans); + + return NDBT_OK; +} + +int Bank::performMakeGLForAccountType(NdbConnection* pTrans, + Uint64 glTime, + Uint32 accountTypeId){ + int check; + + Uint32 balance = 0; + Uint32 withdrawalCount = 0; + Uint32 withdrawalSum = 0; + Uint32 depositSum = 0; + Uint32 depositCount = 0; + Uint32 countTransactions = 0; + Uint32 purged = 0; + + // Insert record in GL so that we know + // that no one else is performing the same task + // Set purged = 0 to indicate that TRANSACTION + // records still exist + NdbOperation* pOp = pTrans->getNdbOperation("GL"); + if (pOp == NULL) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pOp->insertTuple(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pOp->equal("TIME", glTime); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pOp->equal("ACCOUNT_TYPE", accountTypeId); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pOp->setValue("BALANCE", balance); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pOp->setValue("DEPOSIT_COUNT", depositCount); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pOp->setValue("DEPOSIT_SUM", depositSum); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pOp->setValue("WITHDRAWAL_COUNT", withdrawalCount); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pOp->setValue("WITHDRAWAL_SUM", withdrawalSum); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pOp->setValue("PURGED", purged); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pTrans->execute(NoCommit); + if( check == -1 ) { + ERR(pOp->getNdbError()); + return NDBT_FAILED; + } + + // Read previous GL record to get old balance + NdbOperation* pOp2 = pTrans->getNdbOperation("GL"); + if (pOp2 == NULL) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pOp2->readTuple(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pOp2->equal("TIME", glTime-1); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pOp2->equal("ACCOUNT_TYPE", accountTypeId); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + NdbRecAttr* oldBalanceRec = pOp2->getValue("BALANCE"); + if( oldBalanceRec == NULL ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pTrans->execute(NoCommit); + if( check == -1 ) { + ERR(pOp2->getNdbError()); + return NDBT_FAILED; + } + + Uint32 oldBalance = oldBalanceRec->u_32_value(); + // ndbout << "oldBalance = "<getNdbError()); + return NDBT_FAILED; + } + + check = pOp3->updateTuple(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pOp3->equal("TIME", glTime); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pOp3->equal("ACCOUNT_TYPE", accountTypeId); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pOp3->setValue("BALANCE", balance); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pOp3->setValue("DEPOSIT_COUNT", depositCount); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pOp3->setValue("DEPOSIT_SUM", depositSum); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pOp3->setValue("WITHDRAWAL_COUNT", withdrawalCount); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pOp3->setValue("WITHDRAWAL_SUM", withdrawalSum); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pOp3->setValue("PURGED", purged); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + // Execute transaction + check = pTrans->execute(NoCommit); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + return NDBT_OK; +} + + + + +int Bank::sumTransactionsForGL(const Uint64 glTime, + const Uint32 accountType, + Uint32& balance, + Uint32& withdrawalCount, + Uint32& withdrawalSum, + Uint32& depositSum, + Uint32& depositCount, + Uint32& transactionsCount, + NdbConnection* pTrans){ + int check; + + // g_info << "sumTransactionsForGL: " << glTime << ", " << accountType << endl; + + NdbConnection* pScanTrans = m_ndb.startTransaction(); + if (pScanTrans == NULL) { + ERR(m_ndb.getNdbError()); + return NDBT_FAILED; + } + + NdbOperation* pOp = pScanTrans->getNdbOperation("TRANSACTION"); + if (pOp == NULL) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + check = pOp->openScanExclusive(64); + if( check == -1 ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + check = pOp->interpret_exit_ok(); + if( check == -1 ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + NdbRecAttr* accountTypeRec = pOp->getValue("ACCOUNT_TYPE"); + if( accountTypeRec ==NULL ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + NdbRecAttr* timeRec = pOp->getValue("TIME"); + if( timeRec ==NULL ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + NdbRecAttr* transTypeRec = pOp->getValue("TRANSACTION_TYPE"); + if( transTypeRec ==NULL ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + NdbRecAttr* amountRec = pOp->getValue("AMOUNT"); + if( amountRec ==NULL ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + check = pScanTrans->executeScan(); + if( check == -1 ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + int eof; + int rows = 0; + int rowsFound = 0; + eof = pScanTrans->nextScanResult(); + + while(eof == 0){ + rows++; + Uint32 a = accountTypeRec->u_32_value(); + Uint64 t = timeRec->u_64_value(); + + if (a == accountType && t == glTime){ + rowsFound++; + // One record found + int transType = transTypeRec->u_32_value(); + int amount = amountRec->u_32_value(); + if (transType == WithDrawal){ + withdrawalCount++; + withdrawalSum += amount; + balance -= amount; + } else { + assert(transType == Deposit); + depositCount++; + depositSum += amount; + balance += amount; + } + } + + eof = pScanTrans->nextScanResult(); + + if ((rows % 100) == 0){ + // "refresh" ownner transaction every 100th row + if (pTrans->refresh() == -1) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + } + + } + if (eof == -1) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + m_ndb.closeTransaction(pScanTrans); + // ndbout << rows << " TRANSACTIONS have been read" << endl; + transactionsCount = rowsFound; + + return NDBT_OK; + +} + + int Bank::performValidateGLs(Uint64 age){ + + Uint64 currTime; + if (getCurrTime(currTime) != NDBT_OK){ + return NDBT_FAILED; + } + Uint64 glTime = currTime - 1; + while((glTime > 0) && ((glTime + age) >= currTime)){ + + int result = performValidateGL(glTime); + if (result != NDBT_OK){ + g_err << "performValidateGL failed" << endl; + return result; + } + + glTime--; + } + + return NDBT_OK; + } + +int Bank::performValidateGL(Uint64 glTime){ + + ndbout << "performValidateGL: " << glTime << endl; + /** + * Rules: + * - There should be zero or NoAccountTypes GL records for each glTime + * - If purged == 0, then the TRANSACTION table should be checked + * to see that there are: + * + DEPOSIT_COUNT deposit transactions with account_type == ACCOUNT_TYPE + * and TIME == glTime. The sum of these transactions should be + * DEPOSIT_SUM + * + WITHDRAWAL_COUNT withdrawal transactions with account_type == + * ACCOUNT_TYPE and TIME == glTime. The sum of these transactions + * should be WITHDRAWAL_SUM + * + BALANCE should be equal to the sum of all transactions plus + * the balance of the previous GL record + * - If purged == 1 then there should be NO transactions with TIME == glTime + * and ACCOUNT_TYPE == account_type + * + */ + + int check; + /** + * SELECT * FROM GL WHERE account_type = @accountType and time = @time + */ + NdbConnection* pScanTrans = m_ndb.startTransaction(); + if (pScanTrans == NULL) { + ERR(m_ndb.getNdbError()); + return NDBT_FAILED; + } + + NdbOperation* pOp = pScanTrans->getNdbOperation("GL"); + if (pOp == NULL) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + check = pOp->openScanRead(64); + if( check == -1 ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + check = pOp->interpret_exit_ok(); + if( check == -1 ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + NdbRecAttr* accountTypeRec = pOp->getValue("ACCOUNT_TYPE"); + if( accountTypeRec ==NULL ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + NdbRecAttr* timeRec = pOp->getValue("TIME"); + if( timeRec ==NULL ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + NdbRecAttr* purgedRec = pOp->getValue("PURGED"); + if( purgedRec ==NULL ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + NdbRecAttr* balanceRec = pOp->getValue("BALANCE"); + if( balanceRec ==NULL ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + NdbRecAttr* depositSumRec = pOp->getValue("DEPOSIT_SUM"); + if( depositSumRec ==NULL ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + NdbRecAttr* depositCountRec = pOp->getValue("DEPOSIT_COUNT"); + if( depositCountRec ==NULL ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + NdbRecAttr* withdrawalSumRec = pOp->getValue("WITHDRAWAL_SUM"); + if( withdrawalSumRec ==NULL ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + NdbRecAttr* withdrawalCountRec = pOp->getValue("WITHDRAWAL_COUNT"); + if( withdrawalCountRec ==NULL ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + check = pScanTrans->executeScan(); + if( check == -1 ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + int eof; + int rows = 0; + int countGlRecords = 0; + int result = NDBT_OK; + eof = pScanTrans->nextScanResult(); + + while(eof == 0){ + rows++; + Uint64 t = timeRec->u_64_value(); + + if (t == glTime){ + countGlRecords++; + Uint32 a = accountTypeRec->u_32_value(); + Uint32 purged = purgedRec->u_32_value(); + Uint32 wsum = withdrawalSumRec->u_32_value(); + Uint32 wcount = withdrawalCountRec->u_32_value(); + Uint32 dsum = depositSumRec->u_32_value(); + Uint32 dcount = depositCountRec->u_32_value(); + Uint32 b = balanceRec->u_32_value(); + + Uint32 balance = 0; + Uint32 withdrawalSum = 0; + Uint32 withdrawalCount = 0; + Uint32 depositSum = 0; + Uint32 depositCount = 0; + Uint32 countTransactions = 0; + if (purged == 0){ + // If purged == 0, then the TRANSACTION table should be checked + // to see that there are: + // + DEPOSIT_COUNT deposit transactions with account_type == ACCOUNT_TYPE + // and TIME == glTime. The sum of these transactions should be + // DEPOSIT_SUM + // + WITHDRAWAL_COUNT withdrawal transactions with account_type == + // ACCOUNT_TYPE and TIME == glTime. The sum of these transactions + // should be WITHDRAWAL_SUM + // + BALANCE should be equal to the sum of all transactions plus + // the balance of the previous GL record + if (sumTransactionsForGL(t, + a, + balance, + withdrawalCount, + withdrawalSum, + depositSum, + depositCount, + countTransactions, + pScanTrans) != NDBT_OK){ + result = NDBT_FAILED; + } else { + Uint32 prevBalance = 0; + if (getBalanceForGL(t-1, a, prevBalance) != NDBT_OK){ + result = NDBT_FAILED; + } else + if (((prevBalance + balance) != b) || + (wsum != withdrawalSum) || + (wcount != withdrawalCount) || + (dsum != depositSum) || + (dcount != depositCount)){ + g_err << "performValidateGL, sums and counts failed" << endl + << "balance : " << balance+prevBalance << "!="<nextScanResult(); + } + if (eof == -1) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + m_ndb.closeTransaction(pScanTrans); + + // - There should be zero or NoAccountTypes GL records for each glTime + if ((countGlRecords != 0) && (countGlRecords != getNumAccountTypes())){ + g_err << "performValidateGL: " << endl + << "countGlRecords = " << countGlRecords << endl; + result = VERIFICATION_FAILED; + } + + return result; + + + } + +int Bank::getBalanceForGL(const Uint64 glTime, + const Uint32 accountTypeId, + Uint32 &balance){ + int check; + + NdbConnection* pTrans = m_ndb.startTransaction(); + if (pTrans == NULL) { + ERR(m_ndb.getNdbError()); + return NDBT_FAILED; + } + + NdbOperation* pOp = pTrans->getNdbOperation("GL"); + if (pOp == NULL) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pOp->readTuple(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pOp->equal("TIME", glTime); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pOp->equal("ACCOUNT_TYPE", accountTypeId); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + NdbRecAttr* balanceRec = pOp->getValue("BALANCE"); + if( balanceRec == NULL ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pTrans->execute(Commit); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + m_ndb.closeTransaction(pTrans); + + balance = balanceRec->u_32_value(); + + return NDBT_OK; +} + + + +int Bank::getOldestPurgedGL(const Uint32 accountType, + Uint64 &oldest){ + int check; + /** + * SELECT MAX(time) FROM GL WHERE account_type = @accountType and purged=1 + */ + NdbConnection* pScanTrans = m_ndb.startTransaction(); + if (pScanTrans == NULL) { + ERR(m_ndb.getNdbError()); + return NDBT_FAILED; + } + + NdbOperation* pOp = pScanTrans->getNdbOperation("GL"); + if (pOp == NULL) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + check = pOp->openScanRead(64); + if( check == -1 ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + check = pOp->interpret_exit_ok(); + if( check == -1 ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + NdbRecAttr* accountTypeRec = pOp->getValue("ACCOUNT_TYPE"); + if( accountTypeRec ==NULL ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + NdbRecAttr* timeRec = pOp->getValue("TIME"); + if( timeRec ==NULL ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + NdbRecAttr* purgedRec = pOp->getValue("PURGED"); + if( purgedRec ==NULL ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + check = pScanTrans->executeScan(); + if( check == -1 ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + int eof; + int rows = 0; + eof = pScanTrans->nextScanResult(); + oldest = 0; + + while(eof == 0){ + rows++; + Uint32 a = accountTypeRec->u_32_value(); + Uint32 p = purgedRec->u_32_value(); + + if (a == accountType && p == 1){ + // One record found + Uint64 t = timeRec->u_64_value(); + if (t > oldest) + oldest = t; + } + eof = pScanTrans->nextScanResult(); + } + if (eof == -1) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + m_ndb.closeTransaction(pScanTrans); + + return NDBT_OK; +} + +int Bank::getOldestNotPurgedGL(Uint64 &oldest, + Uint32 &accountTypeId, + bool &found){ + int check; + /** + * SELECT time, accountTypeId FROM GL + * WHERE purged=0 order by time asc + */ + NdbConnection* pScanTrans = m_ndb.startTransaction(); + if (pScanTrans == NULL) { + ERR(m_ndb.getNdbError()); + return NDBT_FAILED; + } + + NdbOperation* pOp = pScanTrans->getNdbOperation("GL"); + if (pOp == NULL) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + check = pOp->openScanRead(64); + if( check == -1 ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + check = pOp->interpret_exit_ok(); + if( check == -1 ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + NdbRecAttr* accountTypeRec = pOp->getValue("ACCOUNT_TYPE"); + if( accountTypeRec ==NULL ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + NdbRecAttr* timeRec = pOp->getValue("TIME"); + if( timeRec ==NULL ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + NdbRecAttr* purgedRec = pOp->getValue("PURGED"); + if( purgedRec ==NULL ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + check = pScanTrans->executeScan(); + if( check == -1 ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + int eof; + int rows = 0; + eof = pScanTrans->nextScanResult(); + oldest = (Uint64)-1; + found = false; + + while(eof == 0){ + rows++; + Uint32 p = purgedRec->u_32_value(); + if (p == 0){ + found = true; + // One record found + Uint32 a = accountTypeRec->u_32_value(); + Uint64 t = timeRec->u_64_value(); + if (t < oldest){ + oldest = t; + accountTypeId = a; + } + } + eof = pScanTrans->nextScanResult(); + } + if (eof == -1) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + m_ndb.closeTransaction(pScanTrans); + + return NDBT_OK; +} + + +int Bank::checkNoTransactionsOlderThan(const Uint32 accountType, + const Uint64 oldest){ + /** + * SELECT COUNT(transaction_id) FROM TRANSACTION + * WHERE account_type = @accountType and time <= @oldest + * + */ + + int check; + NdbConnection* pScanTrans = m_ndb.startTransaction(); + if (pScanTrans == NULL) { + ERR(m_ndb.getNdbError()); + return NDBT_FAILED; + } + + NdbOperation* pOp = pScanTrans->getNdbOperation("TRANSACTION"); + if (pOp == NULL) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + check = pOp->openScanRead(64); + if( check == -1 ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + check = pOp->interpret_exit_ok(); + if( check == -1 ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + NdbRecAttr* accountTypeRec = pOp->getValue("ACCOUNT_TYPE"); + if( accountTypeRec ==NULL ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + NdbRecAttr* timeRec = pOp->getValue("TIME"); + if( timeRec ==NULL ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + NdbRecAttr* transactionIdRec = pOp->getValue("TRANSACTION_ID"); + if( transactionIdRec ==NULL ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + check = pScanTrans->executeScan(); + if( check == -1 ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + int eof; + int rows = 0; + int found = 0; + eof = pScanTrans->nextScanResult(); + + while(eof == 0){ + rows++; + Uint32 a = accountTypeRec->u_32_value(); + Uint32 t = timeRec->u_32_value(); + + if (a == accountType && t <= oldest){ + // One record found + Uint64 ti = transactionIdRec->u_64_value(); + g_err << "checkNoTransactionsOlderThan found one record" << endl + << " t = " << t << endl + << " a = " << a << endl + << " ti = " << ti << endl; + found++; + } + eof = pScanTrans->nextScanResult(); + } + if (eof == -1) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + m_ndb.closeTransaction(pScanTrans); + + if (found == 0) + return NDBT_OK; + else + return VERIFICATION_FAILED; +} + + + int Bank::performValidatePurged(){ + /** + * Make sure there are no TRANSACTIONS older than the oldest + * purged GL record + * + */ + + for (int i = 0; i < getNumAccountTypes(); i++){ + ndbout << "performValidatePurged: " << i << endl; + Uint64 oldestGlTime; + if (getOldestPurgedGL(i, oldestGlTime) != NDBT_OK){ + g_err << "getOldestPurgedGL failed" << endl; + return NDBT_FAILED; + } + int result = checkNoTransactionsOlderThan(i, oldestGlTime); + if (result != NDBT_OK){ + g_err << "checkNoTransactionsOlderThan failed" << endl; + return result; + } + + } + + return NDBT_OK; + } + + int Bank::purgeOldGLTransactions(Uint64 currTime, Uint32 age){ + /** + * For each GL record that are older than age and have purged == 0 + * - delete all TRANSACTIONS belonging to the GL and set purged = 1 + * + * + */ + bool found; + int count = 0; + + while(1){ + count++; + if (count > 100) + return NDBT_OK; + + // Search for the oldest GL record with purged == 0 + Uint64 oldestGlTime; + Uint32 accountTypeId; + if (getOldestNotPurgedGL(oldestGlTime, accountTypeId, found) != NDBT_OK){ + g_err << "getOldestNotPurgedGL failed" << endl; + return NDBT_FAILED; + } + + + if (found == false){ + // ndbout << "not found" << endl; + return NDBT_OK; + } + + +// ndbout << "purgeOldGLTransactions" << endl +// << " oldestGlTime = " << oldestGlTime << endl +// << " currTime = " << currTime << endl +// << " age = " << age << endl; + // Check if this GL is old enough to be purged + if ((currTime < age) || (oldestGlTime > (currTime-age))){ + // ndbout << "is not old enough" << endl; + return NDBT_OK; + } + + if (purgeTransactions(oldestGlTime, accountTypeId) != NDBT_OK){ + g_err << "purgeTransactions failed" << endl; + return NDBT_FAILED; + } + } + g_err << "abnormal return" << endl; + return NDBT_FAILED; + } + + +int Bank::purgeTransactions(const Uint64 glTime, + const Uint32 accountTypeId) +{ + int check; + g_info << "purgeTransactions: " << glTime << ", "<getNdbOperation("GL"); + if (pOp == NULL) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pOp->updateTuple(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pOp->equal("TIME", glTime); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + check = pOp->equal("ACCOUNT_TYPE", accountTypeId); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + Uint32 purged = 1; + check = pOp->setValue("PURGED", purged); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + // Execute transaction + check = pTrans->execute(NoCommit); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + // Find all transactions and take over them for delete + + if(findTransactionsToPurge(glTime, + accountTypeId, + pTrans) != NDBT_OK){ + g_err << "findTransactionToPurge failed" << endl; + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + + + check = pTrans->execute(Commit); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + m_ndb.closeTransaction(pTrans); + return NDBT_OK; +} + + +int Bank::findTransactionsToPurge(const Uint64 glTime, + const Uint32 accountType, + NdbConnection* pTrans){ + int check; + + NdbConnection* pScanTrans = m_ndb.startTransaction(); + if (pScanTrans == NULL) { + ERR(m_ndb.getNdbError()); + return NDBT_FAILED; + } + + NdbOperation* pOp = pScanTrans->getNdbOperation("TRANSACTION"); + if (pOp == NULL) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + check = pOp->openScanExclusive(64); + if( check == -1 ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + check = pOp->interpret_exit_ok(); + if( check == -1 ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + NdbRecAttr* timeRec = pOp->getValue("TIME"); + if( timeRec ==NULL ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + NdbRecAttr* accountTypeRec = pOp->getValue("ACCOUNT_TYPE"); + if( accountTypeRec ==NULL ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + check = pScanTrans->executeScan(); + if( check == -1 ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + int eof; + int rows = 0; + int rowsFound = 0; + eof = pScanTrans->nextScanResult(); + + while(eof == 0){ + rows++; + Uint64 t = timeRec->u_64_value(); + Uint32 a = accountTypeRec->u_32_value(); + + if (a == accountType && t == glTime){ + rowsFound++; + // One record found + NdbOperation* pDelOp = pOp->takeOverForDelete(pTrans); + if (pDelOp == NULL){ + ERR(m_ndb.getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + // Execute transaction + check = pTrans->execute(NoCommit); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + } + eof = pScanTrans->nextScanResult(); + } + if (eof == -1) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + m_ndb.closeTransaction(pScanTrans); + // ndbout << rowsFound << " TRANSACTIONS have been deleted" << endl; + + return NDBT_OK; + +} + + + int Bank::performIncreaseTime(int maxSleepBetweenDays, int yield){ + if (init() != NDBT_OK) + return NDBT_FAILED; + + int yieldCounter = 0; + + while(1){ + + while(m_ndb.waitUntilReady(10) != 0) + ndbout << "Waiting for ndb to be ready" << endl; + + while(1){ + + Uint64 currTime; + if (incCurrTime(currTime) != NDBT_OK) + break; + + g_info << "Current time is " << currTime << endl; + if (maxSleepBetweenDays > 0){ + int val = myRandom48(maxSleepBetweenDays); + NdbSleep_SecSleep(val); + } + + yieldCounter++; + if (yield != 0 && yieldCounter >= yield) + return NDBT_OK; + + } + } + return NDBT_FAILED; + } + + + +int Bank::readSystemValue(SystemValueId sysValId, Uint64 & value){ + + int check; + + NdbConnection* pTrans = m_ndb.startTransaction(); + if (pTrans == NULL){ + ERR(m_ndb.getNdbError()); + return NDBT_FAILED; + } + + NdbOperation* pOp = pTrans->getNdbOperation("SYSTEM_VALUES"); + if (pOp == NULL) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp->readTuple(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp->equal("SYSTEM_VALUES_ID", sysValId); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + NdbRecAttr* valueRec = pOp->getValue("VALUE"); + if( valueRec ==NULL ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pTrans->execute(Commit); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + value = valueRec->u_64_value(); + + m_ndb.closeTransaction(pTrans); + return NDBT_OK; + +} + +int Bank::writeSystemValue(SystemValueId sysValId, Uint64 value){ + + int check; + + NdbConnection* pTrans = m_ndb.startTransaction(); + if (pTrans == NULL){ + ERR(m_ndb.getNdbError()); + return NDBT_FAILED; + } + + NdbOperation* pOp = pTrans->getNdbOperation("SYSTEM_VALUES"); + if (pOp == NULL) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp->insertTuple(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp->equal("SYSTEM_VALUES_ID", sysValId); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp->setValue("VALUE", value); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pTrans->execute(Commit); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + m_ndb.closeTransaction(pTrans); + return NDBT_OK; + +} + +int Bank::getNextTransactionId(Uint64 &value){ + return increaseSystemValue2(LastTransactionId, value); +} + +int Bank::incCurrTime(Uint64 &value){ + return increaseSystemValue(CurrentTime, value); +} + + +int Bank::increaseSystemValue(SystemValueId sysValId, Uint64 &value){ + /** + * Increase value with one and return + * updated value + * + */ + + int check; + + NdbConnection* pTrans = m_ndb.startTransaction(); + if (pTrans == NULL){ + ERR(m_ndb.getNdbError()); + return NDBT_FAILED; + } + + NdbOperation* pOp = pTrans->getNdbOperation("SYSTEM_VALUES"); + if (pOp == NULL) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp->readTupleExclusive(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp->equal("SYSTEM_VALUES_ID", sysValId); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + NdbRecAttr* valueRec = pOp->getValue("VALUE"); + if( valueRec ==NULL ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pTrans->execute(NoCommit); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + value = valueRec->u_64_value(); + value++; + + NdbOperation* pOp2 = pTrans->getNdbOperation("SYSTEM_VALUES"); + if (pOp2 == NULL) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp2->updateTuple(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp2->equal("SYSTEM_VALUES_ID", sysValId); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp2->setValue("VALUE", value); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + NdbOperation* pOp3 = pTrans->getNdbOperation("SYSTEM_VALUES"); + if (pOp3 == NULL) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp3->readTuple(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp3->equal("SYSTEM_VALUES_ID", sysValId); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + // Read new value + NdbRecAttr* valueNewRec = pOp3->getValue("VALUE"); + if( valueNewRec ==NULL ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pTrans->execute(Commit); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + // Check that value updated equals the value we read after the update + if (valueNewRec->u_64_value() != value){ + g_err << "getNextTransactionId: value was not updated" << endl; + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + m_ndb.closeTransaction(pTrans); + + + return 0; + +} + +int Bank::increaseSystemValue2(SystemValueId sysValId, Uint64 &value){ + /** + * Increase value with one and return + * updated value + * A more optimized version using interpreted update! + * + */ + + int check; + + NdbConnection* pTrans = m_ndb.startTransaction(); + if (pTrans == NULL){ + ERR(m_ndb.getNdbError()); + return NDBT_FAILED; + } + + NdbOperation* pOp = pTrans->getNdbOperation("SYSTEM_VALUES"); + if (pOp == NULL) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp->interpretedUpdateTuple(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp->equal("SYSTEM_VALUES_ID", sysValId ); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + Uint32 valToIncWith = 1; + check = pOp->incValue("VALUE", valToIncWith); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + NdbRecAttr* valueRec = pOp->getValue("VALUE"); + if( valueRec == NULL ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pTrans->execute(Commit); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + value = valueRec->u_64_value(); + + m_ndb.closeTransaction(pTrans); + + return 0; + +} + + + +int Bank::getCurrTime(Uint64 &time){ + return readSystemValue(CurrentTime, time); +} + + +int Bank::performSumAccounts(int maxSleepBetweenSums, int yield){ + if (init() != NDBT_OK) + return NDBT_FAILED; + + int yieldCounter = 0; + + while (1){ + + while (m_ndb.waitUntilReady(10) != 0) + ndbout << "Waiting for ndb to be ready" << endl; + + Uint32 sumAccounts = 0; + Uint32 numAccounts = 0; + if (getSumAccounts(sumAccounts, numAccounts) != NDBT_OK){ + g_err << "getSumAccounts FAILED" << endl; + } else { + + g_info << "num="<getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + check = pOp->openScanExclusive(64); + if( check == -1 ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + check = pOp->interpret_exit_ok(); + if( check == -1 ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + NdbRecAttr* balanceRec = pOp->getValue("BALANCE"); + if( balanceRec ==NULL ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + check = pScanTrans->executeScan(); + if( check == -1 ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + NdbConnection* pTrans = m_ndb.startTransaction(); + if (pTrans == NULL) { + ERR(m_ndb.getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + int eof; + eof = pScanTrans->nextScanResult(); + + while(eof == 0){ + Uint32 b = balanceRec->u_32_value(); + + sumAccounts += b; + numAccounts++; + + // ndbout << numAccounts << ": balance =" << b + // << ", sum="<< sumAccounts << endl; + + // Take over the operation so that the lock is kept in db + NdbOperation* pLockOp = pOp->takeOverForUpdate(pTrans); + if (pLockOp == NULL){ + ERR(m_ndb.getNdbError()); + m_ndb.closeTransaction(pScanTrans); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + Uint32 illegalBalance = 99; + check = pLockOp->setValue("BALANCE", illegalBalance); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + // Execute transaction + check = pTrans->execute(NoCommit); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + eof = pScanTrans->nextScanResult(); + } + if (eof == -1) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + // TODO Forget about rolling back, just close pTrans!! + + // Rollback transaction + check = pTrans->execute(Rollback); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + m_ndb.closeTransaction(pScanTrans); + m_ndb.closeTransaction(pTrans); + + + return NDBT_OK; + +} diff --git a/ndb/test/ndbapi/bank/BankLoad.cpp b/ndb/test/ndbapi/bank/BankLoad.cpp new file mode 100644 index 00000000000..76261b664a6 --- /dev/null +++ b/ndb/test/ndbapi/bank/BankLoad.cpp @@ -0,0 +1,582 @@ +/* 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 */ + +#include "Bank.hpp" +#include + +/** + * Default account types + * + */ +struct AccountTypesStruct { + int id; + const char* descr; +}; +const AccountTypesStruct accountTypes[] = { + { 0, "KASSA"}, + { 1, "BANKOMAT"}, + { 2, "POSTGIRO"}, + { 3, "LÖNEKONTO"}, + { 4, "SPARKONTO"} +}; + +const int +accountTypesSize = sizeof(accountTypes)/sizeof(AccountTypesStruct); + + +const char* tableNames[] = { + "GL", + "ACCOUNT", + "SYSTEM_VALUES", + "TRANSACTION", + "ACCOUNT_TYPE" +}; + +const int +tableNamesSize = sizeof(tableNames)/sizeof(const char*); + + +int Bank::getNumAccountTypes(){ + return accountTypesSize; +} + +int Bank::createAndLoadBank(bool ovrWrt){ + + m_ndb.init(); + if (m_ndb.waitUntilReady() != 0) + return NDBT_FAILED; + + const NdbDictionary::Table* pSysValTab = + m_ndb.getDictionary()->getTable("SYSTEM_VALUES"); + if (pSysValTab != NULL){ + // The table exists + if (ovrWrt == false){ + ndbout << "Bank already exist and overwrite == false" << endl; + return NDBT_FAILED; + } + } + + if (createTables() != NDBT_OK) + return NDBT_FAILED; + + if (clearTables() != NDBT_OK) + return NDBT_FAILED; + + if (loadAccountType() != NDBT_OK) + return NDBT_FAILED; + + if (loadAccount(10) != NDBT_OK) + return NDBT_FAILED; + + if (loadSystemValues() != NDBT_OK) + return NDBT_FAILED; + + if (loadGl() != NDBT_OK) + return NDBT_FAILED; + + return NDBT_OK; + +} + +int Bank::dropBank(){ + + m_ndb.init(); + if (m_ndb.waitUntilReady() != 0) + return NDBT_FAILED; + + if (dropTables() != NDBT_OK) + return NDBT_FAILED; + + return NDBT_OK; + +} + +int Bank::createTables(){ + for (int i = 0; i < tableNamesSize; i++){ + if (createTable(tableNames[i]) != NDBT_OK) + return NDBT_FAILED; + } + return NDBT_OK; +} + + +int Bank::dropTables(){ + for (int i = 0; i < tableNamesSize; i++){ + if (dropTable(tableNames[i]) != NDBT_OK) + return NDBT_FAILED; + } + return NDBT_OK; +} + +int Bank::clearTables(){ + for (int i = 0; i < tableNamesSize; i++){ + if (clearTable(tableNames[i]) != NDBT_OK) + return NDBT_FAILED; + } + return NDBT_OK; +} + +int Bank::clearTable(const char* tabName){ + UtilTransactions util(&m_ndb, tabName); + if(util.clearTable(&m_ndb, 64) != 0) + return NDBT_FAILED; + return NDBT_OK; +} + +int Bank::createTable(const char* tabName){ + ndbout << "createTable " << tabName << endl; + + const NdbDictionary::Table* pTab = NDBT_Tables::getTable(tabName); + if (pTab == NULL) + return NDBT_FAILED; + + const NdbDictionary::Table* org = + m_ndb.getDictionary()->getTable(tabName); + + if (org != 0 && pTab->equal(* org)){ + return NDBT_OK; + } + + if (org != 0){ + ndbout << "Different table with same name exists" << endl; + return NDBT_FAILED; + } + + if(m_ndb.getDictionary()->createTable(* pTab) == -1){ + ndbout << "Failed to create table: " << + m_ndb.getNdbError() << endl; + return NDBT_FAILED; + } + + return NDBT_OK; +} + +int Bank::dropTable(const char* tabName){ + const NdbDictionary::Table* org = + m_ndb.getDictionary()->getTable(tabName); + + if (org == NULL) + return NDBT_OK; + + ndbout << "dropTable " <dropTable(tabName) != 0){ + return NDBT_FAILED; + } + + return NDBT_OK; +} + + + + + + + + +/** + * Load SYSTEM_VALUES table + * This table keeps track of system wide settings + * For example: + * - next transaction id + * + */ +int Bank::loadSystemValues (){ +int result; + +/** + * Insert start value for next transaction id + * + */ +result = writeSystemValue(LastTransactionId, 0); + +/** + * Insert start value for current time + * + */ +result = writeSystemValue(CurrentTime, 1); + +return result; + +} + + +/** + * Load GL table + * + * Insert GL records for time = 0 with balance 0 + */ +int Bank::loadGl(){ + g_info << "loadGl" << endl; + int check; + + NdbConnection* pTrans = m_ndb.startTransaction(); + if (pTrans == NULL){ + ERR(m_ndb.getNdbError()); + return NDBT_FAILED; + } + + for (int i = 0; i < getNumAccountTypes(); i++){ + + NdbOperation* pOp = pTrans->getNdbOperation("GL"); + if (pOp == NULL) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp->insertTuple(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + Uint64 time = 0; + check = pOp->equal("TIME", time); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp->equal("ACCOUNT_TYPE", i); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + Uint32 balance = 0; + if (getBalanceForAccountType(i, balance) != NDBT_OK){ + return NDBT_FAILED; + } + + check = pOp->setValue("BALANCE", balance); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + Uint32 depositCount = 0; + check = pOp->setValue("DEPOSIT_COUNT", depositCount); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + Uint32 depositSum = 0; + check = pOp->setValue("DEPOSIT_SUM", depositSum); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + Uint32 withdrawalCount = 0; + check = pOp->setValue("WITHDRAWAL_COUNT", withdrawalCount); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + Uint32 withdrawalSum = 0; + check = pOp->setValue("WITHDRAWAL_SUM", withdrawalSum); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + Uint32 purged = 1; + check = pOp->setValue("PURGED", purged); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + } + check = pTrans->execute(Commit); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + m_ndb.closeTransaction(pTrans); + return NDBT_OK; +}; + + +int Bank::getBalanceForAccountType(const Uint32 accountType, + Uint32& balance){ + int check; + g_info << "getBalanceForAccountType: accountType="<getNdbOperation("ACCOUNT"); + if (pOp == NULL) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + check = pOp->openScanRead(64); + if( check == -1 ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + check = pOp->interpret_exit_ok(); + if( check == -1 ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + NdbRecAttr* accountTypeRec = pOp->getValue("ACCOUNT_TYPE"); + if( accountTypeRec ==NULL ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + NdbRecAttr* balanceRec = pOp->getValue("BALANCE"); + if( balanceRec ==NULL ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + check = pScanTrans->executeScan(); + if( check == -1 ) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + int eof; + int rows = 0; + eof = pScanTrans->nextScanResult(); + + while(eof == 0){ + rows++; + Uint32 a = accountTypeRec->u_32_value(); + Uint32 b = balanceRec->u_32_value(); + + if (a == accountType){ + // One record found + balance += b; + } + + eof = pScanTrans->nextScanResult(); + } + if (eof == -1) { + ERR(pScanTrans->getNdbError()); + m_ndb.closeTransaction(pScanTrans); + return NDBT_FAILED; + } + + m_ndb.closeTransaction(pScanTrans); + // ndbout << rows << " rows have been read" << endl; + + return NDBT_OK; + +} + +/** + * Load ACCOUNT_TYPE table + * + * + */ +int Bank::loadAccountType(){ + g_info << "loadAccountType" << endl; + int check; + + NdbConnection* pTrans = m_ndb.startTransaction(); + if (pTrans == NULL){ + ERR(m_ndb.getNdbError()); + return NDBT_FAILED; + } + + for (int i = 0; i < getNumAccountTypes(); i++){ + + NdbOperation* pOp = pTrans->getNdbOperation("ACCOUNT_TYPE"); + if (pOp == NULL) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp->insertTuple(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp->equal("ACCOUNT_TYPE_ID", accountTypes[i].id); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp->setValue("DESCRIPTION", accountTypes[i].descr); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + } + check = pTrans->execute(Commit); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + m_ndb.closeTransaction(pTrans); + return NDBT_OK; +}; + +/** + * Load ACCOUNT table + * + * + * + */ +int Bank::loadAccount (int numAccounts){ + g_info << "loadAccount" << endl; + int check; + + NdbConnection* pTrans = m_ndb.startTransaction(); + if (pTrans == NULL){ + ERR(m_ndb.getNdbError()); + return NDBT_FAILED; + } + + for (int i = 0; i < numAccounts; i++){ + + NdbOperation* pOp = pTrans->getNdbOperation("ACCOUNT"); + if (pOp == NULL) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp->insertTuple(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pOp->equal("ACCOUNT_ID", i); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + int owner; + if (i == 0) + owner = 0; + else + owner = i + 3000; + check = pOp->setValue("OWNER", owner); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + // Load balance so that the bank's account = 0 has 10 millions + // and all other accounts have 10000 + // This set the total balance for the entire bank to + // 10000000 + (10000 * numAccounts-1) + // Since no money should dissapear from to the bank nor + // any money should be added this is a rule that can be checked when + // validating the db + int balance; + if (i == 0){ + balance = 10000000; + } else { + balance = 10000; + } + check = pOp->setValue("BALANCE", balance); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + // TODO - This is how to set a value in a 16, 1 attribute, not so nice? + // NOTE - its not even possible to set the value 0 in this column + // since that is equal to NULL when casting to char* + // check = pOp->setValue("ACCOUNT_TYPE", (const char*)(Uint16)(i/accountTypesSize), 2); + // NOTE attribute now changed to be a 32 bit + + + int accountType; + if (i == 0) + accountType = 0; // KASSA + else + accountType = ((i%accountTypesSize) == 0 ? 1 : (i%getNumAccountTypes())); + check = pOp->setValue("ACCOUNT_TYPE", accountType); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + } + check = pTrans->execute(Commit); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + m_ndb.closeTransaction(pTrans); + return NDBT_FAILED; + } + + m_ndb.closeTransaction(pTrans); + return NDBT_OK; +} + + +int Bank::getNumAccounts(){ + const NdbDictionary::Table* accountTab = + m_ndb.getDictionary()->getTable("ACCOUNT"); + if (accountTab == NULL){ + g_err << "Table ACCOUNT does not exist" << endl; + return NDBT_FAILED; + } + UtilTransactions util(*accountTab); + if(util.selectCount(&m_ndb, 64, &m_maxAccount) != 0) + return NDBT_FAILED; + return NDBT_OK; +} + +int Bank::getMaxAmount(){ + return 10000; +} diff --git a/ndb/test/ndbapi/bank/Makefile b/ndb/test/ndbapi/bank/Makefile deleted file mode 100644 index f710f9e6612..00000000000 --- a/ndb/test/ndbapi/bank/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -include .defs.mk - -DIRS = src bankCreator \ - bankSumAccounts \ - bankTransactionMaker \ - bankValidateAllGLs \ - bankMakeGL \ - bankTimer \ - testBank - - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/bank/Makefile.am b/ndb/test/ndbapi/bank/Makefile.am new file mode 100644 index 00000000000..03f8f1d1c0b --- /dev/null +++ b/ndb/test/ndbapi/bank/Makefile.am @@ -0,0 +1,22 @@ + +bin_PROGRAMS = testBank bankSumAccounts bankValidateAllGLs bankMakeGL bankTransactionMaker bankCreator bankTimer + +noinst_LIBRARIES = libbank.a + +libbank_a_SOURCES = Bank.cpp BankLoad.cpp + +testBank_SOURCES = testBank.cpp +bankSumAccounts_SOURCES = bankSumAccounts.cpp +bankValidateAllGLs_SOURCES = bankValidateAllGLs.cpp +bankMakeGL_SOURCES = bankMakeGL.cpp +bankTransactionMaker_SOURCES = bankTransactionMaker.cpp +bankCreator_SOURCES = bankCreator.cpp +bankTimer_SOURCES = bankTimer.cpp + +LDADD_LOC = $(noinst_LIBRARIES) + +include $(top_srcdir)/ndb/config/common.mk.am +include $(top_srcdir)/ndb/config/type_ndbapitest.mk.am + +# Don't update the files from bitkeeper +%::SCCS/s.% diff --git a/ndb/test/ndbapi/bank/Makefile_old b/ndb/test/ndbapi/bank/Makefile_old new file mode 100644 index 00000000000..f710f9e6612 --- /dev/null +++ b/ndb/test/ndbapi/bank/Makefile_old @@ -0,0 +1,12 @@ +include .defs.mk + +DIRS = src bankCreator \ + bankSumAccounts \ + bankTransactionMaker \ + bankValidateAllGLs \ + bankMakeGL \ + bankTimer \ + testBank + + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/bank/bankCreator.cpp b/ndb/test/ndbapi/bank/bankCreator.cpp new file mode 100644 index 00000000000..5331ec6ba69 --- /dev/null +++ b/ndb/test/ndbapi/bank/bankCreator.cpp @@ -0,0 +1,54 @@ +/* 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 */ + + +#include +#include + +#include +#include +#include +#include +#include +#include "Bank.hpp" + + +int main(int argc, const char** argv){ + int _help = 0; + + struct getargs args[] = { + { "usage", '?', arg_flag, &_help, "Print help", "" } + }; + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + char desc[] = + "This program will create and load the tables for bank\n"; + + if(getarg(args, num_args, argc, argv, &optind) || _help) { + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + + Bank bank; + int overWriteExisting = true; + if (bank.createAndLoadBank(overWriteExisting) != NDBT_OK) + return NDBT_ProgramExit(NDBT_FAILED); + return NDBT_ProgramExit(NDBT_OK); + +} + + + diff --git a/ndb/test/ndbapi/bank/bankCreator/Makefile b/ndb/test/ndbapi/bank/bankCreator/Makefile deleted file mode 100644 index d40103a8347..00000000000 --- a/ndb/test/ndbapi/bank/bankCreator/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -include .defs.mk - -TYPE = ndbapitest -BIN_TARGET = bankCreator -SOURCES = bankCreator.cpp -BIN_TARGET_LIBS += bank - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/bank/bankCreator/bankCreator.cpp b/ndb/test/ndbapi/bank/bankCreator/bankCreator.cpp deleted file mode 100644 index d84818baf24..00000000000 --- a/ndb/test/ndbapi/bank/bankCreator/bankCreator.cpp +++ /dev/null @@ -1,54 +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 */ - - -#include -#include - -#include -#include -#include -#include -#include -#include "../Bank.hpp" - - -int main(int argc, const char** argv){ - int _help = 0; - - struct getargs args[] = { - { "usage", '?', arg_flag, &_help, "Print help", "" } - }; - int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; - char desc[] = - "This program will create and load the tables for bank\n"; - - if(getarg(args, num_args, argc, argv, &optind) || _help) { - arg_printusage(args, num_args, argv[0], desc); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - - Bank bank; - int overWriteExisting = true; - if (bank.createAndLoadBank(overWriteExisting) != NDBT_OK) - return NDBT_ProgramExit(NDBT_FAILED); - return NDBT_ProgramExit(NDBT_OK); - -} - - - diff --git a/ndb/test/ndbapi/bank/bankMakeGL.cpp b/ndb/test/ndbapi/bank/bankMakeGL.cpp new file mode 100644 index 00000000000..54bc559fbf9 --- /dev/null +++ b/ndb/test/ndbapi/bank/bankMakeGL.cpp @@ -0,0 +1,55 @@ +/* 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 */ + + +#include +#include + +#include +#include +#include +#include +#include +#include "Bank.hpp" + + +int main(int argc, const char** argv){ + int _help = 0; + + struct getargs args[] = { + { "usage", '?', arg_flag, &_help, "Print help", "" } + }; + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + char desc[] = + "This program will make GL records in the bank\n"; + + if(getarg(args, num_args, argc, argv, &optind) || _help) { + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + + Bank bank; + + if (bank.performMakeGLs() != 0) + return NDBT_ProgramExit(NDBT_FAILED); + + return NDBT_ProgramExit(NDBT_OK); + +} + + + diff --git a/ndb/test/ndbapi/bank/bankMakeGL/Makefile b/ndb/test/ndbapi/bank/bankMakeGL/Makefile deleted file mode 100644 index 16a092e885c..00000000000 --- a/ndb/test/ndbapi/bank/bankMakeGL/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -include .defs.mk - -TYPE = ndbapitest -BIN_TARGET = bankMakeGL -SOURCES = bankMakeGL.cpp -BIN_TARGET_LIBS += bank - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/bank/bankMakeGL/bankMakeGL.cpp b/ndb/test/ndbapi/bank/bankMakeGL/bankMakeGL.cpp deleted file mode 100644 index 55e9081a598..00000000000 --- a/ndb/test/ndbapi/bank/bankMakeGL/bankMakeGL.cpp +++ /dev/null @@ -1,55 +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 */ - - -#include -#include - -#include -#include -#include -#include -#include -#include "../Bank.hpp" - - -int main(int argc, const char** argv){ - int _help = 0; - - struct getargs args[] = { - { "usage", '?', arg_flag, &_help, "Print help", "" } - }; - int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; - char desc[] = - "This program will make GL records in the bank\n"; - - if(getarg(args, num_args, argc, argv, &optind) || _help) { - arg_printusage(args, num_args, argv[0], desc); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - - Bank bank; - - if (bank.performMakeGLs() != 0) - return NDBT_ProgramExit(NDBT_FAILED); - - return NDBT_ProgramExit(NDBT_OK); - -} - - - diff --git a/ndb/test/ndbapi/bank/bankSumAccounts.cpp b/ndb/test/ndbapi/bank/bankSumAccounts.cpp new file mode 100644 index 00000000000..c0a903f9034 --- /dev/null +++ b/ndb/test/ndbapi/bank/bankSumAccounts.cpp @@ -0,0 +1,55 @@ +/* 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 */ + + +#include +#include + +#include +#include +#include +#include +#include +#include "Bank.hpp" + + +int main(int argc, const char** argv){ + int _help = 0; + + struct getargs args[] = { + { "usage", '?', arg_flag, &_help, "Print help", "" } + }; + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + char desc[] = + "This program will check the sum of all ACCOUNTS in the bank\n"; + + if(getarg(args, num_args, argc, argv, &optind) || _help) { + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + + Bank bank; + + if (bank.performSumAccounts() != 0) + return NDBT_ProgramExit(NDBT_FAILED); + + return NDBT_ProgramExit(NDBT_OK); + +} + + + diff --git a/ndb/test/ndbapi/bank/bankSumAccounts/Makefile b/ndb/test/ndbapi/bank/bankSumAccounts/Makefile deleted file mode 100644 index 34f1cc21bc6..00000000000 --- a/ndb/test/ndbapi/bank/bankSumAccounts/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -include .defs.mk - -TYPE = ndbapitest -BIN_TARGET = bankSumAccounts -SOURCES = bankSumAccounts.cpp -BIN_TARGET_LIBS += bank - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/bank/bankSumAccounts/bankSumAccounts.cpp b/ndb/test/ndbapi/bank/bankSumAccounts/bankSumAccounts.cpp deleted file mode 100644 index ab3e862e8d2..00000000000 --- a/ndb/test/ndbapi/bank/bankSumAccounts/bankSumAccounts.cpp +++ /dev/null @@ -1,55 +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 */ - - -#include -#include - -#include -#include -#include -#include -#include -#include "../Bank.hpp" - - -int main(int argc, const char** argv){ - int _help = 0; - - struct getargs args[] = { - { "usage", '?', arg_flag, &_help, "Print help", "" } - }; - int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; - char desc[] = - "This program will check the sum of all ACCOUNTS in the bank\n"; - - if(getarg(args, num_args, argc, argv, &optind) || _help) { - arg_printusage(args, num_args, argv[0], desc); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - - Bank bank; - - if (bank.performSumAccounts() != 0) - return NDBT_ProgramExit(NDBT_FAILED); - - return NDBT_ProgramExit(NDBT_OK); - -} - - - diff --git a/ndb/test/ndbapi/bank/bankTimer.cpp b/ndb/test/ndbapi/bank/bankTimer.cpp new file mode 100644 index 00000000000..ba3165fccb4 --- /dev/null +++ b/ndb/test/ndbapi/bank/bankTimer.cpp @@ -0,0 +1,58 @@ +/* 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 */ + + +#include + +#include + +#include +#include +#include +#include +#include +#include "Bank.hpp" + + +int main(int argc, const char** argv){ + int _help = 0; + int _wait = 30; + + struct getargs args[] = { + { "wait", 'w', arg_integer, &_wait, "Max time to wait between days", "secs" }, + { "usage", '?', arg_flag, &_help, "Print help", "" } + }; + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + char desc[] = + "This program will increase time in the bank\n"; + + if(getarg(args, num_args, argc, argv, &optind) || _help) { + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + + Bank bank; + + if (bank.performIncreaseTime(_wait) != 0) + return NDBT_ProgramExit(NDBT_FAILED); + + return NDBT_ProgramExit(NDBT_OK); + +} + + + diff --git a/ndb/test/ndbapi/bank/bankTimer/Makefile b/ndb/test/ndbapi/bank/bankTimer/Makefile deleted file mode 100644 index a2fcf703723..00000000000 --- a/ndb/test/ndbapi/bank/bankTimer/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -include .defs.mk - -TYPE = ndbapitest -BIN_TARGET = bankTimer -SOURCES = bankTimer.cpp -BIN_TARGET_LIBS += bank - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/bank/bankTimer/bankTimer.cpp b/ndb/test/ndbapi/bank/bankTimer/bankTimer.cpp deleted file mode 100644 index ba8de9e4af1..00000000000 --- a/ndb/test/ndbapi/bank/bankTimer/bankTimer.cpp +++ /dev/null @@ -1,58 +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 */ - - -#include - -#include - -#include -#include -#include -#include -#include -#include "../Bank.hpp" - - -int main(int argc, const char** argv){ - int _help = 0; - int _wait = 30; - - struct getargs args[] = { - { "wait", 'w', arg_integer, &_wait, "Max time to wait between days", "secs" }, - { "usage", '?', arg_flag, &_help, "Print help", "" } - }; - int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; - char desc[] = - "This program will increase time in the bank\n"; - - if(getarg(args, num_args, argc, argv, &optind) || _help) { - arg_printusage(args, num_args, argv[0], desc); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - - Bank bank; - - if (bank.performIncreaseTime(_wait) != 0) - return NDBT_ProgramExit(NDBT_FAILED); - - return NDBT_ProgramExit(NDBT_OK); - -} - - - diff --git a/ndb/test/ndbapi/bank/bankTransactionMaker.cpp b/ndb/test/ndbapi/bank/bankTransactionMaker.cpp new file mode 100644 index 00000000000..fe9b53e0c8d --- /dev/null +++ b/ndb/test/ndbapi/bank/bankTransactionMaker.cpp @@ -0,0 +1,58 @@ +/* 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 */ + + +#include + +#include + +#include +#include +#include +#include +#include +#include "Bank.hpp" + + +int main(int argc, const char** argv){ + int _help = 0; + int _wait = 20; + + struct getargs args[] = { + { "wait", 'w', arg_integer, &_wait, "Time to wait between transactions", "ms" }, + { "usage", '?', arg_flag, &_help, "Print help", "" } + }; + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + char desc[] = + "This program will perform transactions in the bank\n"; + + if(getarg(args, num_args, argc, argv, &optind) || _help) { + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + + Bank bank; + + if (bank.performTransactions(_wait) != 0) + return NDBT_ProgramExit(NDBT_FAILED); + + return NDBT_ProgramExit(NDBT_OK); + +} + + + diff --git a/ndb/test/ndbapi/bank/bankTransactionMaker/Makefile b/ndb/test/ndbapi/bank/bankTransactionMaker/Makefile deleted file mode 100644 index 2e482898476..00000000000 --- a/ndb/test/ndbapi/bank/bankTransactionMaker/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -include .defs.mk - -TYPE = ndbapitest -BIN_TARGET = bankTransactionMaker -SOURCES = bankTransactionMaker.cpp -BIN_TARGET_LIBS += bank - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/bank/bankTransactionMaker/bankTransactionMaker.cpp b/ndb/test/ndbapi/bank/bankTransactionMaker/bankTransactionMaker.cpp deleted file mode 100644 index 0c7d5d72473..00000000000 --- a/ndb/test/ndbapi/bank/bankTransactionMaker/bankTransactionMaker.cpp +++ /dev/null @@ -1,58 +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 */ - - -#include - -#include - -#include -#include -#include -#include -#include -#include "../Bank.hpp" - - -int main(int argc, const char** argv){ - int _help = 0; - int _wait = 20; - - struct getargs args[] = { - { "wait", 'w', arg_integer, &_wait, "Time to wait between transactions", "ms" }, - { "usage", '?', arg_flag, &_help, "Print help", "" } - }; - int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; - char desc[] = - "This program will perform transactions in the bank\n"; - - if(getarg(args, num_args, argc, argv, &optind) || _help) { - arg_printusage(args, num_args, argv[0], desc); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - - Bank bank; - - if (bank.performTransactions(_wait) != 0) - return NDBT_ProgramExit(NDBT_FAILED); - - return NDBT_ProgramExit(NDBT_OK); - -} - - - diff --git a/ndb/test/ndbapi/bank/bankValidateAllGLs.cpp b/ndb/test/ndbapi/bank/bankValidateAllGLs.cpp new file mode 100644 index 00000000000..f9d974bb5f7 --- /dev/null +++ b/ndb/test/ndbapi/bank/bankValidateAllGLs.cpp @@ -0,0 +1,56 @@ +/* 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 */ + + +#include + +#include + +#include +#include +#include +#include +#include +#include "Bank.hpp" + + +int main(int argc, const char** argv){ + int _help = 0; + + struct getargs args[] = { + { "usage", '?', arg_flag, &_help, "Print help", "" } + }; + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + char desc[] = + "This program will validate all GLs in the bank\n"; + + if(getarg(args, num_args, argc, argv, &optind) || _help) { + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + + Bank bank; + + if (bank.performValidateAllGLs() != 0) + return NDBT_ProgramExit(NDBT_FAILED); + + return NDBT_ProgramExit(NDBT_OK); + +} + + + diff --git a/ndb/test/ndbapi/bank/bankValidateAllGLs/Makefile b/ndb/test/ndbapi/bank/bankValidateAllGLs/Makefile deleted file mode 100644 index 660b73fb830..00000000000 --- a/ndb/test/ndbapi/bank/bankValidateAllGLs/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -include .defs.mk - -TYPE = ndbapitest -BIN_TARGET = bankValidateAllGLs -SOURCES = bankValidateAllGLs.cpp -BIN_TARGET_LIBS += bank - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/bank/bankValidateAllGLs/bankValidateAllGLs.cpp b/ndb/test/ndbapi/bank/bankValidateAllGLs/bankValidateAllGLs.cpp deleted file mode 100644 index 13136755de8..00000000000 --- a/ndb/test/ndbapi/bank/bankValidateAllGLs/bankValidateAllGLs.cpp +++ /dev/null @@ -1,56 +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 */ - - -#include - -#include - -#include -#include -#include -#include -#include -#include "../Bank.hpp" - - -int main(int argc, const char** argv){ - int _help = 0; - - struct getargs args[] = { - { "usage", '?', arg_flag, &_help, "Print help", "" } - }; - int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; - char desc[] = - "This program will validate all GLs in the bank\n"; - - if(getarg(args, num_args, argc, argv, &optind) || _help) { - arg_printusage(args, num_args, argv[0], desc); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - - Bank bank; - - if (bank.performValidateAllGLs() != 0) - return NDBT_ProgramExit(NDBT_FAILED); - - return NDBT_ProgramExit(NDBT_OK); - -} - - - diff --git a/ndb/test/ndbapi/bank/old_dirs/bankCreator/Makefile b/ndb/test/ndbapi/bank/old_dirs/bankCreator/Makefile new file mode 100644 index 00000000000..d40103a8347 --- /dev/null +++ b/ndb/test/ndbapi/bank/old_dirs/bankCreator/Makefile @@ -0,0 +1,8 @@ +include .defs.mk + +TYPE = ndbapitest +BIN_TARGET = bankCreator +SOURCES = bankCreator.cpp +BIN_TARGET_LIBS += bank + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/bank/old_dirs/bankMakeGL/Makefile b/ndb/test/ndbapi/bank/old_dirs/bankMakeGL/Makefile new file mode 100644 index 00000000000..16a092e885c --- /dev/null +++ b/ndb/test/ndbapi/bank/old_dirs/bankMakeGL/Makefile @@ -0,0 +1,8 @@ +include .defs.mk + +TYPE = ndbapitest +BIN_TARGET = bankMakeGL +SOURCES = bankMakeGL.cpp +BIN_TARGET_LIBS += bank + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/bank/old_dirs/bankSumAccounts/Makefile b/ndb/test/ndbapi/bank/old_dirs/bankSumAccounts/Makefile new file mode 100644 index 00000000000..34f1cc21bc6 --- /dev/null +++ b/ndb/test/ndbapi/bank/old_dirs/bankSumAccounts/Makefile @@ -0,0 +1,8 @@ +include .defs.mk + +TYPE = ndbapitest +BIN_TARGET = bankSumAccounts +SOURCES = bankSumAccounts.cpp +BIN_TARGET_LIBS += bank + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/bank/old_dirs/bankTimer/Makefile b/ndb/test/ndbapi/bank/old_dirs/bankTimer/Makefile new file mode 100644 index 00000000000..a2fcf703723 --- /dev/null +++ b/ndb/test/ndbapi/bank/old_dirs/bankTimer/Makefile @@ -0,0 +1,8 @@ +include .defs.mk + +TYPE = ndbapitest +BIN_TARGET = bankTimer +SOURCES = bankTimer.cpp +BIN_TARGET_LIBS += bank + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/bank/old_dirs/bankTransactionMaker/Makefile b/ndb/test/ndbapi/bank/old_dirs/bankTransactionMaker/Makefile new file mode 100644 index 00000000000..2e482898476 --- /dev/null +++ b/ndb/test/ndbapi/bank/old_dirs/bankTransactionMaker/Makefile @@ -0,0 +1,8 @@ +include .defs.mk + +TYPE = ndbapitest +BIN_TARGET = bankTransactionMaker +SOURCES = bankTransactionMaker.cpp +BIN_TARGET_LIBS += bank + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/bank/old_dirs/bankValidateAllGLs/Makefile b/ndb/test/ndbapi/bank/old_dirs/bankValidateAllGLs/Makefile new file mode 100644 index 00000000000..660b73fb830 --- /dev/null +++ b/ndb/test/ndbapi/bank/old_dirs/bankValidateAllGLs/Makefile @@ -0,0 +1,8 @@ +include .defs.mk + +TYPE = ndbapitest +BIN_TARGET = bankValidateAllGLs +SOURCES = bankValidateAllGLs.cpp +BIN_TARGET_LIBS += bank + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/bank/old_dirs/src/Makefile b/ndb/test/ndbapi/bank/old_dirs/src/Makefile new file mode 100644 index 00000000000..e0ab8e0e536 --- /dev/null +++ b/ndb/test/ndbapi/bank/old_dirs/src/Makefile @@ -0,0 +1,7 @@ +include .defs.mk + +TYPE = ndbapitest +ARCHIVE_TARGET = bank +SOURCES = Bank.cpp BankLoad.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/bank/old_dirs/testBank/Makefile b/ndb/test/ndbapi/bank/old_dirs/testBank/Makefile new file mode 100644 index 00000000000..382aaadad7c --- /dev/null +++ b/ndb/test/ndbapi/bank/old_dirs/testBank/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE = ndbapitest + +BIN_TARGET = testBank +BIN_TARGET_LIBS += bank +SOURCES = testBank.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/bank/src/Bank.cpp b/ndb/test/ndbapi/bank/src/Bank.cpp deleted file mode 100644 index 11ebf087fd4..00000000000 --- a/ndb/test/ndbapi/bank/src/Bank.cpp +++ /dev/null @@ -1,2458 +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 */ - -#include "../Bank.hpp" -#include -#include -#include - -Bank::Bank(): - m_ndb("BANK"), - m_maxAccount(-1), - m_initialized(false) -{ - -} - -int Bank::init(){ - if (m_initialized == true) - return NDBT_OK; - - myRandom48Init(NdbTick_CurrentMillisecond()); - - m_ndb.init(); - while (m_ndb.waitUntilReady(10) != 0) - ndbout << "Waiting for ndb to be ready" << endl; - - if (getNumAccounts() != NDBT_OK) - return NDBT_FAILED; - return NDBT_OK; -} - -int Bank::performTransactions(int maxSleepBetweenTrans, int yield){ - - if (init() != NDBT_OK) - return NDBT_FAILED; - int transactions = 0; - - while(1){ - - while(m_ndb.waitUntilReady(10) != 0) - ndbout << "Waiting for ndb to be ready" << endl; - - while(performTransaction() != NDBT_FAILED){ - transactions++; - - if (maxSleepBetweenTrans > 0){ - int val = myRandom48(maxSleepBetweenTrans); - NdbSleep_MilliSleep(val); - } - - if((transactions % 100) == 0) - g_info << transactions << endl; - - if (yield != 0 && transactions >= yield) - return NDBT_OK; - } - } - return NDBT_FAILED; - -} - -int Bank::performTransaction(){ - int result = NDBT_OK; - - if (m_maxAccount <= 0){ - g_err << "No accounts in bank" << endl; - return NDBT_FAILED; - } - - int fromAccount = myRandom48(m_maxAccount); - int toAccount = myRandom48(m_maxAccount); - - if (fromAccount == toAccount){ - // Increase toAccount with 1 - toAccount = (toAccount+1)%m_maxAccount; - } - - int maxAmount = getMaxAmount(); - - int amount = myRandom48(maxAmount); - - retry_transaction: - int res = performTransaction(fromAccount, toAccount, amount); - if (res != 0){ - switch (res){ - case NDBT_FAILED: - g_err << "performTransaction returned NDBT_FAILED" << endl - << " fromAccount = " << fromAccount << endl - << " toAccount = " << toAccount << endl - << " amount = " << amount << endl; - result = NDBT_FAILED; - break; - case NOT_ENOUGH_FUNDS: - // ndbout << "performTransaction returned NOT_ENOUGH_FUNDS" << endl; - break; - case NDBT_TEMPORARY: - g_err << "TEMPORARY_ERRROR retrying" << endl; - goto retry_transaction; - break; - default: - g_info << "performTransaction returned "<getNdbOperation("ACCOUNT"); - if (pOp == NULL) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp->readTupleExclusive(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp->equal("ACCOUNT_ID", fromAccountId); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - NdbRecAttr* balanceFromRec = pOp->getValue("BALANCE"); - if( balanceFromRec ==NULL ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - NdbRecAttr* fromAccountTypeRec = pOp->getValue("ACCOUNT_TYPE"); - if( fromAccountTypeRec == NULL ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pTrans->execute(NoCommit); - if( check == -1 ) { - const NdbError err = pTrans->getNdbError(); - m_ndb.closeTransaction(pTrans); - if (err.status == NdbError::TemporaryError){ - ERR(err); - return NDBT_TEMPORARY; - } - ERR(err); - return NDBT_FAILED; - } - - Uint32 balanceFrom = balanceFromRec->u_32_value(); - // ndbout << "balanceFrom: " << balanceFrom << endl; - - if (((Int64)balanceFrom - amount) < 0){ - m_ndb.closeTransaction(pTrans); - //ndbout << "Not enough funds" << endl; - return NOT_ENOUGH_FUNDS; - } - - Uint32 fromAccountType = fromAccountTypeRec->u_32_value(); - - /** - * Read balance on to account - */ - NdbOperation* pOp6 = pTrans->getNdbOperation("ACCOUNT"); - if (pOp6 == NULL) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp6->readTupleExclusive(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp6->equal("ACCOUNT_ID", toAccountId); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - NdbRecAttr* balanceToRec = pOp6->getValue("BALANCE"); - if( balanceToRec == NULL ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - NdbRecAttr* toAccountTypeRec = pOp6->getValue("ACCOUNT_TYPE"); - if( toAccountTypeRec == NULL ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pTrans->execute(NoCommit); - if( check == -1 ) { - const NdbError err = pTrans->getNdbError(); - m_ndb.closeTransaction(pTrans); - if (err.status == NdbError::TemporaryError){ - ERR(err); - return NDBT_TEMPORARY; - } - ERR(err); - return NDBT_FAILED; - } - - Uint32 balanceTo = balanceToRec->u_32_value(); - // ndbout << "balanceTo: " << balanceTo << endl; - Uint32 toAccountType = toAccountTypeRec->u_32_value(); - - // Ok, all clear to do the transaction - Uint64 transId; - if (getNextTransactionId(transId) != NDBT_OK){ - return NDBT_FAILED; - } - - Uint64 currTime; - if (getCurrTime(currTime) != NDBT_OK){ - return NDBT_FAILED; - } - - /** - * Update balance on from account - */ - NdbOperation* pOp2 = pTrans->getNdbOperation("ACCOUNT"); - if (pOp2 == NULL) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp2->updateTuple(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp2->equal("ACCOUNT_ID", fromAccountId); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp2->setValue("BALANCE", balanceFrom - amount); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - /** - * Update balance on to account - */ - NdbOperation* pOp3 = pTrans->getNdbOperation("ACCOUNT"); - if (pOp3 == NULL) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp3->updateTuple(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp3->equal("ACCOUNT_ID", toAccountId); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp3->setValue("BALANCE", balanceTo + amount); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - /** - * Insert withdrawal transaction - */ - NdbOperation* pOp4 = pTrans->getNdbOperation("TRANSACTION"); - if (pOp4 == NULL) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp4->insertTuple(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp4->equal("TRANSACTION_ID", transId); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp4->equal("ACCOUNT", fromAccountId); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp4->setValue("ACCOUNT_TYPE", fromAccountType); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp4->setValue("OTHER_ACCOUNT", toAccountId); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp4->setValue("TRANSACTION_TYPE", WithDrawal); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp4->setValue("TIME", currTime); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp4->setValue("AMOUNT", amount); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - /** - * Insert deposit transaction - */ - NdbOperation* pOp5 = pTrans->getNdbOperation("TRANSACTION"); - if (pOp5 == NULL) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp5->insertTuple(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp5->equal("TRANSACTION_ID", transId); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp5->equal("ACCOUNT", toAccountId); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp5->setValue("ACCOUNT_TYPE", toAccountType); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp5->setValue("OTHER_ACCOUNT", fromAccountId); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp5->setValue("TRANSACTION_TYPE", Deposit); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp5->setValue("TIME", currTime); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp5->setValue("AMOUNT", amount); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pTrans->execute(Commit); - if( check == -1 ) { - const NdbError err = pTrans->getNdbError(); - m_ndb.closeTransaction(pTrans); - if (err.status == NdbError::TemporaryError){ - ERR(err); - return NDBT_TEMPORARY; - } - ERR(err); - return NDBT_FAILED; - } - - m_ndb.closeTransaction(pTrans); - return NDBT_OK; -} - - - - -int Bank::performMakeGLs(int yield){ - int result; - if (init() != NDBT_OK) - return NDBT_FAILED; - - int counter, maxCounter; - int yieldCounter = 0; - - while (1){ - // Counters to keep tracck of how many - // GLs should be made before performing a validation - counter = 0; - maxCounter = 50 + myRandom48(100); - - while(m_ndb.waitUntilReady(10) != 0) - ndbout << "Waiting for ndb to be ready" << endl; - - /** - * Validate GLs and Transactions for previous days - * - */ - result = performValidateGLs(); - if (result != NDBT_OK){ - if (result == VERIFICATION_FAILED){ - g_err << "performValidateGLs verification failed" << endl; - return NDBT_FAILED; - } - g_info << "performValidateGLs failed" << endl; - continue; - } - - result = performValidatePurged(); - if (result != NDBT_OK){ - if (result == VERIFICATION_FAILED){ - g_err << "performValidatePurged verification failed" << endl; - return NDBT_FAILED; - } - g_info << "performValidatePurged failed" << endl; - continue; - } - - while (1){ - - yieldCounter++; - if (yield != 0 && yieldCounter >= yield) - return NDBT_OK; - - /** - * Find last GL time. - * ( GL record with highest time value) - */ - Uint64 lastGLTime; - if (findLastGL(lastGLTime) != NDBT_OK){ - g_info << "findLastGL failed" << endl; - // Break out of inner while loop - break; - } - - lastGLTime++; - - /** - * If last GL time + 1 is smaller than current time - * perform a GL for that time - */ - Uint64 currTime; - if (getCurrTime(currTime) != NDBT_OK){ - g_info << "getCurrTime failed" << endl; - // Break out of inner while loop - break; - } - if (lastGLTime < currTime){ - counter++; - if (performMakeGL(lastGLTime) != NDBT_OK){ - g_info << "performMakeGL failed" << endl; - // Break out of inner while loop - break; - } - - if (counter > maxCounter){ - // Break out of inner while loop and - // validatePreviousGLs - g_info << "counter("< maxCounter("<getNdbOperation("GL"); - if (pOp == NULL) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - check = pOp->openScanRead(64); - if( check == -1 ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - check = pOp->interpret_exit_ok(); - if( check == -1 ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - NdbRecAttr* timeRec = pOp->getValue("TIME"); - if( timeRec ==NULL ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - check = pScanTrans->executeScan(); - if( check == -1 ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - int eof; - int rows = 0; - eof = pScanTrans->nextScanResult(); - lastTime = 0; - - while(eof == 0){ - rows++; - Uint64 t = timeRec->u_32_value(); - - if (t > lastTime) - lastTime = t; - - eof = pScanTrans->nextScanResult(); - } - if (eof == -1) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - m_ndb.closeTransaction(pScanTrans); - - return NDBT_OK; -} - - -int Bank::performMakeGL(int time){ - g_info << "performMakeGL: " << time << endl; - /** - * Create one GL record for each account type. - * All in the same transaction - */ - // Start transaction - NdbConnection* pTrans = m_ndb.startTransaction(); - if (pTrans == NULL){ - ERR(m_ndb.getNdbError()); - return NDBT_FAILED; - } - for (int i = 0; i < getNumAccountTypes(); i++){ - - if (performMakeGLForAccountType(pTrans, time, i) != NDBT_OK){ - g_err << "performMakeGLForAccountType returned NDBT_FAILED"<execute(Commit) == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - m_ndb.closeTransaction(pTrans); - - return NDBT_OK; -} - -int Bank::performMakeGLForAccountType(NdbConnection* pTrans, - Uint64 glTime, - Uint32 accountTypeId){ - int check; - - Uint32 balance = 0; - Uint32 withdrawalCount = 0; - Uint32 withdrawalSum = 0; - Uint32 depositSum = 0; - Uint32 depositCount = 0; - Uint32 countTransactions = 0; - Uint32 purged = 0; - - // Insert record in GL so that we know - // that no one else is performing the same task - // Set purged = 0 to indicate that TRANSACTION - // records still exist - NdbOperation* pOp = pTrans->getNdbOperation("GL"); - if (pOp == NULL) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pOp->insertTuple(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pOp->equal("TIME", glTime); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pOp->equal("ACCOUNT_TYPE", accountTypeId); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pOp->setValue("BALANCE", balance); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pOp->setValue("DEPOSIT_COUNT", depositCount); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pOp->setValue("DEPOSIT_SUM", depositSum); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pOp->setValue("WITHDRAWAL_COUNT", withdrawalCount); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pOp->setValue("WITHDRAWAL_SUM", withdrawalSum); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pOp->setValue("PURGED", purged); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pTrans->execute(NoCommit); - if( check == -1 ) { - ERR(pOp->getNdbError()); - return NDBT_FAILED; - } - - // Read previous GL record to get old balance - NdbOperation* pOp2 = pTrans->getNdbOperation("GL"); - if (pOp2 == NULL) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pOp2->readTuple(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pOp2->equal("TIME", glTime-1); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pOp2->equal("ACCOUNT_TYPE", accountTypeId); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - NdbRecAttr* oldBalanceRec = pOp2->getValue("BALANCE"); - if( oldBalanceRec == NULL ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pTrans->execute(NoCommit); - if( check == -1 ) { - ERR(pOp2->getNdbError()); - return NDBT_FAILED; - } - - Uint32 oldBalance = oldBalanceRec->u_32_value(); - // ndbout << "oldBalance = "<getNdbError()); - return NDBT_FAILED; - } - - check = pOp3->updateTuple(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pOp3->equal("TIME", glTime); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pOp3->equal("ACCOUNT_TYPE", accountTypeId); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pOp3->setValue("BALANCE", balance); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pOp3->setValue("DEPOSIT_COUNT", depositCount); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pOp3->setValue("DEPOSIT_SUM", depositSum); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pOp3->setValue("WITHDRAWAL_COUNT", withdrawalCount); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pOp3->setValue("WITHDRAWAL_SUM", withdrawalSum); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pOp3->setValue("PURGED", purged); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - // Execute transaction - check = pTrans->execute(NoCommit); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - return NDBT_OK; -} - - - - -int Bank::sumTransactionsForGL(const Uint64 glTime, - const Uint32 accountType, - Uint32& balance, - Uint32& withdrawalCount, - Uint32& withdrawalSum, - Uint32& depositSum, - Uint32& depositCount, - Uint32& transactionsCount, - NdbConnection* pTrans){ - int check; - - // g_info << "sumTransactionsForGL: " << glTime << ", " << accountType << endl; - - NdbConnection* pScanTrans = m_ndb.startTransaction(); - if (pScanTrans == NULL) { - ERR(m_ndb.getNdbError()); - return NDBT_FAILED; - } - - NdbOperation* pOp = pScanTrans->getNdbOperation("TRANSACTION"); - if (pOp == NULL) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - check = pOp->openScanExclusive(64); - if( check == -1 ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - check = pOp->interpret_exit_ok(); - if( check == -1 ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - NdbRecAttr* accountTypeRec = pOp->getValue("ACCOUNT_TYPE"); - if( accountTypeRec ==NULL ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - NdbRecAttr* timeRec = pOp->getValue("TIME"); - if( timeRec ==NULL ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - NdbRecAttr* transTypeRec = pOp->getValue("TRANSACTION_TYPE"); - if( transTypeRec ==NULL ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - NdbRecAttr* amountRec = pOp->getValue("AMOUNT"); - if( amountRec ==NULL ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - check = pScanTrans->executeScan(); - if( check == -1 ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - int eof; - int rows = 0; - int rowsFound = 0; - eof = pScanTrans->nextScanResult(); - - while(eof == 0){ - rows++; - Uint32 a = accountTypeRec->u_32_value(); - Uint64 t = timeRec->u_64_value(); - - if (a == accountType && t == glTime){ - rowsFound++; - // One record found - int transType = transTypeRec->u_32_value(); - int amount = amountRec->u_32_value(); - if (transType == WithDrawal){ - withdrawalCount++; - withdrawalSum += amount; - balance -= amount; - } else { - assert(transType == Deposit); - depositCount++; - depositSum += amount; - balance += amount; - } - } - - eof = pScanTrans->nextScanResult(); - - if ((rows % 100) == 0){ - // "refresh" ownner transaction every 100th row - if (pTrans->refresh() == -1) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - } - - } - if (eof == -1) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - m_ndb.closeTransaction(pScanTrans); - // ndbout << rows << " TRANSACTIONS have been read" << endl; - transactionsCount = rowsFound; - - return NDBT_OK; - -} - - int Bank::performValidateGLs(Uint64 age){ - - Uint64 currTime; - if (getCurrTime(currTime) != NDBT_OK){ - return NDBT_FAILED; - } - Uint64 glTime = currTime - 1; - while((glTime > 0) && ((glTime + age) >= currTime)){ - - int result = performValidateGL(glTime); - if (result != NDBT_OK){ - g_err << "performValidateGL failed" << endl; - return result; - } - - glTime--; - } - - return NDBT_OK; - } - -int Bank::performValidateGL(Uint64 glTime){ - - ndbout << "performValidateGL: " << glTime << endl; - /** - * Rules: - * - There should be zero or NoAccountTypes GL records for each glTime - * - If purged == 0, then the TRANSACTION table should be checked - * to see that there are: - * + DEPOSIT_COUNT deposit transactions with account_type == ACCOUNT_TYPE - * and TIME == glTime. The sum of these transactions should be - * DEPOSIT_SUM - * + WITHDRAWAL_COUNT withdrawal transactions with account_type == - * ACCOUNT_TYPE and TIME == glTime. The sum of these transactions - * should be WITHDRAWAL_SUM - * + BALANCE should be equal to the sum of all transactions plus - * the balance of the previous GL record - * - If purged == 1 then there should be NO transactions with TIME == glTime - * and ACCOUNT_TYPE == account_type - * - */ - - int check; - /** - * SELECT * FROM GL WHERE account_type = @accountType and time = @time - */ - NdbConnection* pScanTrans = m_ndb.startTransaction(); - if (pScanTrans == NULL) { - ERR(m_ndb.getNdbError()); - return NDBT_FAILED; - } - - NdbOperation* pOp = pScanTrans->getNdbOperation("GL"); - if (pOp == NULL) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - check = pOp->openScanRead(64); - if( check == -1 ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - check = pOp->interpret_exit_ok(); - if( check == -1 ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - NdbRecAttr* accountTypeRec = pOp->getValue("ACCOUNT_TYPE"); - if( accountTypeRec ==NULL ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - NdbRecAttr* timeRec = pOp->getValue("TIME"); - if( timeRec ==NULL ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - NdbRecAttr* purgedRec = pOp->getValue("PURGED"); - if( purgedRec ==NULL ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - NdbRecAttr* balanceRec = pOp->getValue("BALANCE"); - if( balanceRec ==NULL ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - NdbRecAttr* depositSumRec = pOp->getValue("DEPOSIT_SUM"); - if( depositSumRec ==NULL ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - NdbRecAttr* depositCountRec = pOp->getValue("DEPOSIT_COUNT"); - if( depositCountRec ==NULL ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - NdbRecAttr* withdrawalSumRec = pOp->getValue("WITHDRAWAL_SUM"); - if( withdrawalSumRec ==NULL ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - NdbRecAttr* withdrawalCountRec = pOp->getValue("WITHDRAWAL_COUNT"); - if( withdrawalCountRec ==NULL ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - check = pScanTrans->executeScan(); - if( check == -1 ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - int eof; - int rows = 0; - int countGlRecords = 0; - int result = NDBT_OK; - eof = pScanTrans->nextScanResult(); - - while(eof == 0){ - rows++; - Uint64 t = timeRec->u_64_value(); - - if (t == glTime){ - countGlRecords++; - Uint32 a = accountTypeRec->u_32_value(); - Uint32 purged = purgedRec->u_32_value(); - Uint32 wsum = withdrawalSumRec->u_32_value(); - Uint32 wcount = withdrawalCountRec->u_32_value(); - Uint32 dsum = depositSumRec->u_32_value(); - Uint32 dcount = depositCountRec->u_32_value(); - Uint32 b = balanceRec->u_32_value(); - - Uint32 balance = 0; - Uint32 withdrawalSum = 0; - Uint32 withdrawalCount = 0; - Uint32 depositSum = 0; - Uint32 depositCount = 0; - Uint32 countTransactions = 0; - if (purged == 0){ - // If purged == 0, then the TRANSACTION table should be checked - // to see that there are: - // + DEPOSIT_COUNT deposit transactions with account_type == ACCOUNT_TYPE - // and TIME == glTime. The sum of these transactions should be - // DEPOSIT_SUM - // + WITHDRAWAL_COUNT withdrawal transactions with account_type == - // ACCOUNT_TYPE and TIME == glTime. The sum of these transactions - // should be WITHDRAWAL_SUM - // + BALANCE should be equal to the sum of all transactions plus - // the balance of the previous GL record - if (sumTransactionsForGL(t, - a, - balance, - withdrawalCount, - withdrawalSum, - depositSum, - depositCount, - countTransactions, - pScanTrans) != NDBT_OK){ - result = NDBT_FAILED; - } else { - Uint32 prevBalance = 0; - if (getBalanceForGL(t-1, a, prevBalance) != NDBT_OK){ - result = NDBT_FAILED; - } else - if (((prevBalance + balance) != b) || - (wsum != withdrawalSum) || - (wcount != withdrawalCount) || - (dsum != depositSum) || - (dcount != depositCount)){ - g_err << "performValidateGL, sums and counts failed" << endl - << "balance : " << balance+prevBalance << "!="<nextScanResult(); - } - if (eof == -1) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - m_ndb.closeTransaction(pScanTrans); - - // - There should be zero or NoAccountTypes GL records for each glTime - if ((countGlRecords != 0) && (countGlRecords != getNumAccountTypes())){ - g_err << "performValidateGL: " << endl - << "countGlRecords = " << countGlRecords << endl; - result = VERIFICATION_FAILED; - } - - return result; - - - } - -int Bank::getBalanceForGL(const Uint64 glTime, - const Uint32 accountTypeId, - Uint32 &balance){ - int check; - - NdbConnection* pTrans = m_ndb.startTransaction(); - if (pTrans == NULL) { - ERR(m_ndb.getNdbError()); - return NDBT_FAILED; - } - - NdbOperation* pOp = pTrans->getNdbOperation("GL"); - if (pOp == NULL) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pOp->readTuple(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pOp->equal("TIME", glTime); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pOp->equal("ACCOUNT_TYPE", accountTypeId); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - NdbRecAttr* balanceRec = pOp->getValue("BALANCE"); - if( balanceRec == NULL ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pTrans->execute(Commit); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - m_ndb.closeTransaction(pTrans); - - balance = balanceRec->u_32_value(); - - return NDBT_OK; -} - - - -int Bank::getOldestPurgedGL(const Uint32 accountType, - Uint64 &oldest){ - int check; - /** - * SELECT MAX(time) FROM GL WHERE account_type = @accountType and purged=1 - */ - NdbConnection* pScanTrans = m_ndb.startTransaction(); - if (pScanTrans == NULL) { - ERR(m_ndb.getNdbError()); - return NDBT_FAILED; - } - - NdbOperation* pOp = pScanTrans->getNdbOperation("GL"); - if (pOp == NULL) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - check = pOp->openScanRead(64); - if( check == -1 ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - check = pOp->interpret_exit_ok(); - if( check == -1 ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - NdbRecAttr* accountTypeRec = pOp->getValue("ACCOUNT_TYPE"); - if( accountTypeRec ==NULL ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - NdbRecAttr* timeRec = pOp->getValue("TIME"); - if( timeRec ==NULL ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - NdbRecAttr* purgedRec = pOp->getValue("PURGED"); - if( purgedRec ==NULL ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - check = pScanTrans->executeScan(); - if( check == -1 ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - int eof; - int rows = 0; - eof = pScanTrans->nextScanResult(); - oldest = 0; - - while(eof == 0){ - rows++; - Uint32 a = accountTypeRec->u_32_value(); - Uint32 p = purgedRec->u_32_value(); - - if (a == accountType && p == 1){ - // One record found - Uint64 t = timeRec->u_64_value(); - if (t > oldest) - oldest = t; - } - eof = pScanTrans->nextScanResult(); - } - if (eof == -1) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - m_ndb.closeTransaction(pScanTrans); - - return NDBT_OK; -} - -int Bank::getOldestNotPurgedGL(Uint64 &oldest, - Uint32 &accountTypeId, - bool &found){ - int check; - /** - * SELECT time, accountTypeId FROM GL - * WHERE purged=0 order by time asc - */ - NdbConnection* pScanTrans = m_ndb.startTransaction(); - if (pScanTrans == NULL) { - ERR(m_ndb.getNdbError()); - return NDBT_FAILED; - } - - NdbOperation* pOp = pScanTrans->getNdbOperation("GL"); - if (pOp == NULL) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - check = pOp->openScanRead(64); - if( check == -1 ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - check = pOp->interpret_exit_ok(); - if( check == -1 ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - NdbRecAttr* accountTypeRec = pOp->getValue("ACCOUNT_TYPE"); - if( accountTypeRec ==NULL ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - NdbRecAttr* timeRec = pOp->getValue("TIME"); - if( timeRec ==NULL ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - NdbRecAttr* purgedRec = pOp->getValue("PURGED"); - if( purgedRec ==NULL ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - check = pScanTrans->executeScan(); - if( check == -1 ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - int eof; - int rows = 0; - eof = pScanTrans->nextScanResult(); - oldest = (Uint64)-1; - found = false; - - while(eof == 0){ - rows++; - Uint32 p = purgedRec->u_32_value(); - if (p == 0){ - found = true; - // One record found - Uint32 a = accountTypeRec->u_32_value(); - Uint64 t = timeRec->u_64_value(); - if (t < oldest){ - oldest = t; - accountTypeId = a; - } - } - eof = pScanTrans->nextScanResult(); - } - if (eof == -1) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - m_ndb.closeTransaction(pScanTrans); - - return NDBT_OK; -} - - -int Bank::checkNoTransactionsOlderThan(const Uint32 accountType, - const Uint64 oldest){ - /** - * SELECT COUNT(transaction_id) FROM TRANSACTION - * WHERE account_type = @accountType and time <= @oldest - * - */ - - int check; - NdbConnection* pScanTrans = m_ndb.startTransaction(); - if (pScanTrans == NULL) { - ERR(m_ndb.getNdbError()); - return NDBT_FAILED; - } - - NdbOperation* pOp = pScanTrans->getNdbOperation("TRANSACTION"); - if (pOp == NULL) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - check = pOp->openScanRead(64); - if( check == -1 ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - check = pOp->interpret_exit_ok(); - if( check == -1 ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - NdbRecAttr* accountTypeRec = pOp->getValue("ACCOUNT_TYPE"); - if( accountTypeRec ==NULL ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - NdbRecAttr* timeRec = pOp->getValue("TIME"); - if( timeRec ==NULL ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - NdbRecAttr* transactionIdRec = pOp->getValue("TRANSACTION_ID"); - if( transactionIdRec ==NULL ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - check = pScanTrans->executeScan(); - if( check == -1 ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - int eof; - int rows = 0; - int found = 0; - eof = pScanTrans->nextScanResult(); - - while(eof == 0){ - rows++; - Uint32 a = accountTypeRec->u_32_value(); - Uint32 t = timeRec->u_32_value(); - - if (a == accountType && t <= oldest){ - // One record found - Uint64 ti = transactionIdRec->u_64_value(); - g_err << "checkNoTransactionsOlderThan found one record" << endl - << " t = " << t << endl - << " a = " << a << endl - << " ti = " << ti << endl; - found++; - } - eof = pScanTrans->nextScanResult(); - } - if (eof == -1) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - m_ndb.closeTransaction(pScanTrans); - - if (found == 0) - return NDBT_OK; - else - return VERIFICATION_FAILED; -} - - - int Bank::performValidatePurged(){ - /** - * Make sure there are no TRANSACTIONS older than the oldest - * purged GL record - * - */ - - for (int i = 0; i < getNumAccountTypes(); i++){ - ndbout << "performValidatePurged: " << i << endl; - Uint64 oldestGlTime; - if (getOldestPurgedGL(i, oldestGlTime) != NDBT_OK){ - g_err << "getOldestPurgedGL failed" << endl; - return NDBT_FAILED; - } - int result = checkNoTransactionsOlderThan(i, oldestGlTime); - if (result != NDBT_OK){ - g_err << "checkNoTransactionsOlderThan failed" << endl; - return result; - } - - } - - return NDBT_OK; - } - - int Bank::purgeOldGLTransactions(Uint64 currTime, Uint32 age){ - /** - * For each GL record that are older than age and have purged == 0 - * - delete all TRANSACTIONS belonging to the GL and set purged = 1 - * - * - */ - bool found; - int count = 0; - - while(1){ - count++; - if (count > 100) - return NDBT_OK; - - // Search for the oldest GL record with purged == 0 - Uint64 oldestGlTime; - Uint32 accountTypeId; - if (getOldestNotPurgedGL(oldestGlTime, accountTypeId, found) != NDBT_OK){ - g_err << "getOldestNotPurgedGL failed" << endl; - return NDBT_FAILED; - } - - - if (found == false){ - // ndbout << "not found" << endl; - return NDBT_OK; - } - - -// ndbout << "purgeOldGLTransactions" << endl -// << " oldestGlTime = " << oldestGlTime << endl -// << " currTime = " << currTime << endl -// << " age = " << age << endl; - // Check if this GL is old enough to be purged - if ((currTime < age) || (oldestGlTime > (currTime-age))){ - // ndbout << "is not old enough" << endl; - return NDBT_OK; - } - - if (purgeTransactions(oldestGlTime, accountTypeId) != NDBT_OK){ - g_err << "purgeTransactions failed" << endl; - return NDBT_FAILED; - } - } - g_err << "abnormal return" << endl; - return NDBT_FAILED; - } - - -int Bank::purgeTransactions(const Uint64 glTime, - const Uint32 accountTypeId) -{ - int check; - g_info << "purgeTransactions: " << glTime << ", "<getNdbOperation("GL"); - if (pOp == NULL) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pOp->updateTuple(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pOp->equal("TIME", glTime); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - check = pOp->equal("ACCOUNT_TYPE", accountTypeId); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - Uint32 purged = 1; - check = pOp->setValue("PURGED", purged); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - // Execute transaction - check = pTrans->execute(NoCommit); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - // Find all transactions and take over them for delete - - if(findTransactionsToPurge(glTime, - accountTypeId, - pTrans) != NDBT_OK){ - g_err << "findTransactionToPurge failed" << endl; - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - - - check = pTrans->execute(Commit); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - m_ndb.closeTransaction(pTrans); - return NDBT_OK; -} - - -int Bank::findTransactionsToPurge(const Uint64 glTime, - const Uint32 accountType, - NdbConnection* pTrans){ - int check; - - NdbConnection* pScanTrans = m_ndb.startTransaction(); - if (pScanTrans == NULL) { - ERR(m_ndb.getNdbError()); - return NDBT_FAILED; - } - - NdbOperation* pOp = pScanTrans->getNdbOperation("TRANSACTION"); - if (pOp == NULL) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - check = pOp->openScanExclusive(64); - if( check == -1 ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - check = pOp->interpret_exit_ok(); - if( check == -1 ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - NdbRecAttr* timeRec = pOp->getValue("TIME"); - if( timeRec ==NULL ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - NdbRecAttr* accountTypeRec = pOp->getValue("ACCOUNT_TYPE"); - if( accountTypeRec ==NULL ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - check = pScanTrans->executeScan(); - if( check == -1 ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - int eof; - int rows = 0; - int rowsFound = 0; - eof = pScanTrans->nextScanResult(); - - while(eof == 0){ - rows++; - Uint64 t = timeRec->u_64_value(); - Uint32 a = accountTypeRec->u_32_value(); - - if (a == accountType && t == glTime){ - rowsFound++; - // One record found - NdbOperation* pDelOp = pOp->takeOverForDelete(pTrans); - if (pDelOp == NULL){ - ERR(m_ndb.getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - // Execute transaction - check = pTrans->execute(NoCommit); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - } - eof = pScanTrans->nextScanResult(); - } - if (eof == -1) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - m_ndb.closeTransaction(pScanTrans); - // ndbout << rowsFound << " TRANSACTIONS have been deleted" << endl; - - return NDBT_OK; - -} - - - int Bank::performIncreaseTime(int maxSleepBetweenDays, int yield){ - if (init() != NDBT_OK) - return NDBT_FAILED; - - int yieldCounter = 0; - - while(1){ - - while(m_ndb.waitUntilReady(10) != 0) - ndbout << "Waiting for ndb to be ready" << endl; - - while(1){ - - Uint64 currTime; - if (incCurrTime(currTime) != NDBT_OK) - break; - - g_info << "Current time is " << currTime << endl; - if (maxSleepBetweenDays > 0){ - int val = myRandom48(maxSleepBetweenDays); - NdbSleep_SecSleep(val); - } - - yieldCounter++; - if (yield != 0 && yieldCounter >= yield) - return NDBT_OK; - - } - } - return NDBT_FAILED; - } - - - -int Bank::readSystemValue(SystemValueId sysValId, Uint64 & value){ - - int check; - - NdbConnection* pTrans = m_ndb.startTransaction(); - if (pTrans == NULL){ - ERR(m_ndb.getNdbError()); - return NDBT_FAILED; - } - - NdbOperation* pOp = pTrans->getNdbOperation("SYSTEM_VALUES"); - if (pOp == NULL) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp->readTuple(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp->equal("SYSTEM_VALUES_ID", sysValId); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - NdbRecAttr* valueRec = pOp->getValue("VALUE"); - if( valueRec ==NULL ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pTrans->execute(Commit); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - value = valueRec->u_64_value(); - - m_ndb.closeTransaction(pTrans); - return NDBT_OK; - -} - -int Bank::writeSystemValue(SystemValueId sysValId, Uint64 value){ - - int check; - - NdbConnection* pTrans = m_ndb.startTransaction(); - if (pTrans == NULL){ - ERR(m_ndb.getNdbError()); - return NDBT_FAILED; - } - - NdbOperation* pOp = pTrans->getNdbOperation("SYSTEM_VALUES"); - if (pOp == NULL) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp->insertTuple(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp->equal("SYSTEM_VALUES_ID", sysValId); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp->setValue("VALUE", value); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pTrans->execute(Commit); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - m_ndb.closeTransaction(pTrans); - return NDBT_OK; - -} - -int Bank::getNextTransactionId(Uint64 &value){ - return increaseSystemValue2(LastTransactionId, value); -} - -int Bank::incCurrTime(Uint64 &value){ - return increaseSystemValue(CurrentTime, value); -} - - -int Bank::increaseSystemValue(SystemValueId sysValId, Uint64 &value){ - /** - * Increase value with one and return - * updated value - * - */ - - int check; - - NdbConnection* pTrans = m_ndb.startTransaction(); - if (pTrans == NULL){ - ERR(m_ndb.getNdbError()); - return NDBT_FAILED; - } - - NdbOperation* pOp = pTrans->getNdbOperation("SYSTEM_VALUES"); - if (pOp == NULL) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp->readTupleExclusive(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp->equal("SYSTEM_VALUES_ID", sysValId); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - NdbRecAttr* valueRec = pOp->getValue("VALUE"); - if( valueRec ==NULL ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pTrans->execute(NoCommit); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - value = valueRec->u_64_value(); - value++; - - NdbOperation* pOp2 = pTrans->getNdbOperation("SYSTEM_VALUES"); - if (pOp2 == NULL) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp2->updateTuple(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp2->equal("SYSTEM_VALUES_ID", sysValId); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp2->setValue("VALUE", value); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - NdbOperation* pOp3 = pTrans->getNdbOperation("SYSTEM_VALUES"); - if (pOp3 == NULL) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp3->readTuple(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp3->equal("SYSTEM_VALUES_ID", sysValId); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - // Read new value - NdbRecAttr* valueNewRec = pOp3->getValue("VALUE"); - if( valueNewRec ==NULL ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pTrans->execute(Commit); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - // Check that value updated equals the value we read after the update - if (valueNewRec->u_64_value() != value){ - g_err << "getNextTransactionId: value was not updated" << endl; - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - m_ndb.closeTransaction(pTrans); - - - return 0; - -} - -int Bank::increaseSystemValue2(SystemValueId sysValId, Uint64 &value){ - /** - * Increase value with one and return - * updated value - * A more optimized version using interpreted update! - * - */ - - int check; - - NdbConnection* pTrans = m_ndb.startTransaction(); - if (pTrans == NULL){ - ERR(m_ndb.getNdbError()); - return NDBT_FAILED; - } - - NdbOperation* pOp = pTrans->getNdbOperation("SYSTEM_VALUES"); - if (pOp == NULL) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp->interpretedUpdateTuple(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp->equal("SYSTEM_VALUES_ID", sysValId ); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - Uint32 valToIncWith = 1; - check = pOp->incValue("VALUE", valToIncWith); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - NdbRecAttr* valueRec = pOp->getValue("VALUE"); - if( valueRec == NULL ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pTrans->execute(Commit); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - value = valueRec->u_64_value(); - - m_ndb.closeTransaction(pTrans); - - return 0; - -} - - - -int Bank::getCurrTime(Uint64 &time){ - return readSystemValue(CurrentTime, time); -} - - -int Bank::performSumAccounts(int maxSleepBetweenSums, int yield){ - if (init() != NDBT_OK) - return NDBT_FAILED; - - int yieldCounter = 0; - - while (1){ - - while (m_ndb.waitUntilReady(10) != 0) - ndbout << "Waiting for ndb to be ready" << endl; - - Uint32 sumAccounts = 0; - Uint32 numAccounts = 0; - if (getSumAccounts(sumAccounts, numAccounts) != NDBT_OK){ - g_err << "getSumAccounts FAILED" << endl; - } else { - - g_info << "num="<getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - check = pOp->openScanExclusive(64); - if( check == -1 ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - check = pOp->interpret_exit_ok(); - if( check == -1 ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - NdbRecAttr* balanceRec = pOp->getValue("BALANCE"); - if( balanceRec ==NULL ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - check = pScanTrans->executeScan(); - if( check == -1 ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - NdbConnection* pTrans = m_ndb.startTransaction(); - if (pTrans == NULL) { - ERR(m_ndb.getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - int eof; - eof = pScanTrans->nextScanResult(); - - while(eof == 0){ - Uint32 b = balanceRec->u_32_value(); - - sumAccounts += b; - numAccounts++; - - // ndbout << numAccounts << ": balance =" << b - // << ", sum="<< sumAccounts << endl; - - // Take over the operation so that the lock is kept in db - NdbOperation* pLockOp = pOp->takeOverForUpdate(pTrans); - if (pLockOp == NULL){ - ERR(m_ndb.getNdbError()); - m_ndb.closeTransaction(pScanTrans); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - Uint32 illegalBalance = 99; - check = pLockOp->setValue("BALANCE", illegalBalance); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - // Execute transaction - check = pTrans->execute(NoCommit); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - eof = pScanTrans->nextScanResult(); - } - if (eof == -1) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - // TODO Forget about rolling back, just close pTrans!! - - // Rollback transaction - check = pTrans->execute(Rollback); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - m_ndb.closeTransaction(pScanTrans); - m_ndb.closeTransaction(pTrans); - - - return NDBT_OK; - -} diff --git a/ndb/test/ndbapi/bank/src/BankLoad.cpp b/ndb/test/ndbapi/bank/src/BankLoad.cpp deleted file mode 100644 index 985a49d5f64..00000000000 --- a/ndb/test/ndbapi/bank/src/BankLoad.cpp +++ /dev/null @@ -1,582 +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 */ - -#include "../Bank.hpp" -#include - -/** - * Default account types - * - */ -struct AccountTypesStruct { - int id; - const char* descr; -}; -const AccountTypesStruct accountTypes[] = { - { 0, "KASSA"}, - { 1, "BANKOMAT"}, - { 2, "POSTGIRO"}, - { 3, "LÖNEKONTO"}, - { 4, "SPARKONTO"} -}; - -const int -accountTypesSize = sizeof(accountTypes)/sizeof(AccountTypesStruct); - - -const char* tableNames[] = { - "GL", - "ACCOUNT", - "SYSTEM_VALUES", - "TRANSACTION", - "ACCOUNT_TYPE" -}; - -const int -tableNamesSize = sizeof(tableNames)/sizeof(const char*); - - -int Bank::getNumAccountTypes(){ - return accountTypesSize; -} - -int Bank::createAndLoadBank(bool ovrWrt){ - - m_ndb.init(); - if (m_ndb.waitUntilReady() != 0) - return NDBT_FAILED; - - const NdbDictionary::Table* pSysValTab = - m_ndb.getDictionary()->getTable("SYSTEM_VALUES"); - if (pSysValTab != NULL){ - // The table exists - if (ovrWrt == false){ - ndbout << "Bank already exist and overwrite == false" << endl; - return NDBT_FAILED; - } - } - - if (createTables() != NDBT_OK) - return NDBT_FAILED; - - if (clearTables() != NDBT_OK) - return NDBT_FAILED; - - if (loadAccountType() != NDBT_OK) - return NDBT_FAILED; - - if (loadAccount(10) != NDBT_OK) - return NDBT_FAILED; - - if (loadSystemValues() != NDBT_OK) - return NDBT_FAILED; - - if (loadGl() != NDBT_OK) - return NDBT_FAILED; - - return NDBT_OK; - -} - -int Bank::dropBank(){ - - m_ndb.init(); - if (m_ndb.waitUntilReady() != 0) - return NDBT_FAILED; - - if (dropTables() != NDBT_OK) - return NDBT_FAILED; - - return NDBT_OK; - -} - -int Bank::createTables(){ - for (int i = 0; i < tableNamesSize; i++){ - if (createTable(tableNames[i]) != NDBT_OK) - return NDBT_FAILED; - } - return NDBT_OK; -} - - -int Bank::dropTables(){ - for (int i = 0; i < tableNamesSize; i++){ - if (dropTable(tableNames[i]) != NDBT_OK) - return NDBT_FAILED; - } - return NDBT_OK; -} - -int Bank::clearTables(){ - for (int i = 0; i < tableNamesSize; i++){ - if (clearTable(tableNames[i]) != NDBT_OK) - return NDBT_FAILED; - } - return NDBT_OK; -} - -int Bank::clearTable(const char* tabName){ - UtilTransactions util(&m_ndb, tabName); - if(util.clearTable(&m_ndb, 64) != 0) - return NDBT_FAILED; - return NDBT_OK; -} - -int Bank::createTable(const char* tabName){ - ndbout << "createTable " << tabName << endl; - - const NdbDictionary::Table* pTab = NDBT_Tables::getTable(tabName); - if (pTab == NULL) - return NDBT_FAILED; - - const NdbDictionary::Table* org = - m_ndb.getDictionary()->getTable(tabName); - - if (org != 0 && pTab->equal(* org)){ - return NDBT_OK; - } - - if (org != 0){ - ndbout << "Different table with same name exists" << endl; - return NDBT_FAILED; - } - - if(m_ndb.getDictionary()->createTable(* pTab) == -1){ - ndbout << "Failed to create table: " << - m_ndb.getNdbError() << endl; - return NDBT_FAILED; - } - - return NDBT_OK; -} - -int Bank::dropTable(const char* tabName){ - const NdbDictionary::Table* org = - m_ndb.getDictionary()->getTable(tabName); - - if (org == NULL) - return NDBT_OK; - - ndbout << "dropTable " <dropTable(tabName) != 0){ - return NDBT_FAILED; - } - - return NDBT_OK; -} - - - - - - - - -/** - * Load SYSTEM_VALUES table - * This table keeps track of system wide settings - * For example: - * - next transaction id - * - */ -int Bank::loadSystemValues (){ -int result; - -/** - * Insert start value for next transaction id - * - */ -result = writeSystemValue(LastTransactionId, 0); - -/** - * Insert start value for current time - * - */ -result = writeSystemValue(CurrentTime, 1); - -return result; - -} - - -/** - * Load GL table - * - * Insert GL records for time = 0 with balance 0 - */ -int Bank::loadGl(){ - g_info << "loadGl" << endl; - int check; - - NdbConnection* pTrans = m_ndb.startTransaction(); - if (pTrans == NULL){ - ERR(m_ndb.getNdbError()); - return NDBT_FAILED; - } - - for (int i = 0; i < getNumAccountTypes(); i++){ - - NdbOperation* pOp = pTrans->getNdbOperation("GL"); - if (pOp == NULL) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp->insertTuple(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - Uint64 time = 0; - check = pOp->equal("TIME", time); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp->equal("ACCOUNT_TYPE", i); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - Uint32 balance = 0; - if (getBalanceForAccountType(i, balance) != NDBT_OK){ - return NDBT_FAILED; - } - - check = pOp->setValue("BALANCE", balance); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - Uint32 depositCount = 0; - check = pOp->setValue("DEPOSIT_COUNT", depositCount); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - Uint32 depositSum = 0; - check = pOp->setValue("DEPOSIT_SUM", depositSum); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - Uint32 withdrawalCount = 0; - check = pOp->setValue("WITHDRAWAL_COUNT", withdrawalCount); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - Uint32 withdrawalSum = 0; - check = pOp->setValue("WITHDRAWAL_SUM", withdrawalSum); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - Uint32 purged = 1; - check = pOp->setValue("PURGED", purged); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - } - check = pTrans->execute(Commit); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - m_ndb.closeTransaction(pTrans); - return NDBT_OK; -}; - - -int Bank::getBalanceForAccountType(const Uint32 accountType, - Uint32& balance){ - int check; - g_info << "getBalanceForAccountType: accountType="<getNdbOperation("ACCOUNT"); - if (pOp == NULL) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - check = pOp->openScanRead(64); - if( check == -1 ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - check = pOp->interpret_exit_ok(); - if( check == -1 ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - NdbRecAttr* accountTypeRec = pOp->getValue("ACCOUNT_TYPE"); - if( accountTypeRec ==NULL ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - NdbRecAttr* balanceRec = pOp->getValue("BALANCE"); - if( balanceRec ==NULL ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - check = pScanTrans->executeScan(); - if( check == -1 ) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - int eof; - int rows = 0; - eof = pScanTrans->nextScanResult(); - - while(eof == 0){ - rows++; - Uint32 a = accountTypeRec->u_32_value(); - Uint32 b = balanceRec->u_32_value(); - - if (a == accountType){ - // One record found - balance += b; - } - - eof = pScanTrans->nextScanResult(); - } - if (eof == -1) { - ERR(pScanTrans->getNdbError()); - m_ndb.closeTransaction(pScanTrans); - return NDBT_FAILED; - } - - m_ndb.closeTransaction(pScanTrans); - // ndbout << rows << " rows have been read" << endl; - - return NDBT_OK; - -} - -/** - * Load ACCOUNT_TYPE table - * - * - */ -int Bank::loadAccountType(){ - g_info << "loadAccountType" << endl; - int check; - - NdbConnection* pTrans = m_ndb.startTransaction(); - if (pTrans == NULL){ - ERR(m_ndb.getNdbError()); - return NDBT_FAILED; - } - - for (int i = 0; i < getNumAccountTypes(); i++){ - - NdbOperation* pOp = pTrans->getNdbOperation("ACCOUNT_TYPE"); - if (pOp == NULL) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp->insertTuple(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp->equal("ACCOUNT_TYPE_ID", accountTypes[i].id); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp->setValue("DESCRIPTION", accountTypes[i].descr); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - } - check = pTrans->execute(Commit); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - m_ndb.closeTransaction(pTrans); - return NDBT_OK; -}; - -/** - * Load ACCOUNT table - * - * - * - */ -int Bank::loadAccount (int numAccounts){ - g_info << "loadAccount" << endl; - int check; - - NdbConnection* pTrans = m_ndb.startTransaction(); - if (pTrans == NULL){ - ERR(m_ndb.getNdbError()); - return NDBT_FAILED; - } - - for (int i = 0; i < numAccounts; i++){ - - NdbOperation* pOp = pTrans->getNdbOperation("ACCOUNT"); - if (pOp == NULL) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp->insertTuple(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp->equal("ACCOUNT_ID", i); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - int owner; - if (i == 0) - owner = 0; - else - owner = i + 3000; - check = pOp->setValue("OWNER", owner); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - // Load balance so that the bank's account = 0 has 10 millions - // and all other accounts have 10000 - // This set the total balance for the entire bank to - // 10000000 + (10000 * numAccounts-1) - // Since no money should dissapear from to the bank nor - // any money should be added this is a rule that can be checked when - // validating the db - int balance; - if (i == 0){ - balance = 10000000; - } else { - balance = 10000; - } - check = pOp->setValue("BALANCE", balance); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - // TODO - This is how to set a value in a 16, 1 attribute, not so nice? - // NOTE - its not even possible to set the value 0 in this column - // since that is equal to NULL when casting to char* - // check = pOp->setValue("ACCOUNT_TYPE", (const char*)(Uint16)(i/accountTypesSize), 2); - // NOTE attribute now changed to be a 32 bit - - - int accountType; - if (i == 0) - accountType = 0; // KASSA - else - accountType = ((i%accountTypesSize) == 0 ? 1 : (i%getNumAccountTypes())); - check = pOp->setValue("ACCOUNT_TYPE", accountType); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - } - check = pTrans->execute(Commit); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - m_ndb.closeTransaction(pTrans); - return NDBT_FAILED; - } - - m_ndb.closeTransaction(pTrans); - return NDBT_OK; -} - - -int Bank::getNumAccounts(){ - const NdbDictionary::Table* accountTab = - m_ndb.getDictionary()->getTable("ACCOUNT"); - if (accountTab == NULL){ - g_err << "Table ACCOUNT does not exist" << endl; - return NDBT_FAILED; - } - UtilTransactions util(*accountTab); - if(util.selectCount(&m_ndb, 64, &m_maxAccount) != 0) - return NDBT_FAILED; - return NDBT_OK; -} - -int Bank::getMaxAmount(){ - return 10000; -} diff --git a/ndb/test/ndbapi/bank/src/Makefile b/ndb/test/ndbapi/bank/src/Makefile deleted file mode 100644 index e0ab8e0e536..00000000000 --- a/ndb/test/ndbapi/bank/src/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -include .defs.mk - -TYPE = ndbapitest -ARCHIVE_TARGET = bank -SOURCES = Bank.cpp BankLoad.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/bank/testBank.cpp b/ndb/test/ndbapi/bank/testBank.cpp new file mode 100644 index 00000000000..77ac1172d7c --- /dev/null +++ b/ndb/test/ndbapi/bank/testBank.cpp @@ -0,0 +1,150 @@ +/* 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 */ + +#include +#include +#include +#include +#include +#include + + +#define CHECK(b) if (!(b)) { \ + g_err << "ERR: "<< step->getName() \ + << " failed on line " << __LINE__ << endl; \ + result = NDBT_FAILED; \ + continue; } + + +#include "Bank.hpp" + +int runCreateBank(NDBT_Context* ctx, NDBT_Step* step){ + Bank bank; + int overWriteExisting = true; + if (bank.createAndLoadBank(overWriteExisting) != NDBT_OK) + return NDBT_FAILED; + return NDBT_OK; +} + +int runBankTimer(NDBT_Context* ctx, NDBT_Step* step){ + Bank bank; + int wait = 30; // Max seconds between each "day" + int yield = 1; // Loops before bank returns + + while (ctx->isTestStopped() == false) { + bank.performIncreaseTime(wait, yield); + } + return NDBT_OK; +} + +int runBankTransactions(NDBT_Context* ctx, NDBT_Step* step){ + Bank bank; + int wait = 10; // Max ms between each transaction + int yield = 100; // Loops before bank returns + + while (ctx->isTestStopped() == false) { + bank.performTransactions(wait, yield); + } + return NDBT_OK; +} + +int runBankGL(NDBT_Context* ctx, NDBT_Step* step){ + Bank bank; + int yield = 20; // Loops before bank returns + int result = NDBT_OK; + + while (ctx->isTestStopped() == false) { + if (bank.performMakeGLs(yield) != NDBT_OK){ + ndbout << "bank.performMakeGLs FAILED" << endl; + result = NDBT_FAILED; + } + } + return NDBT_OK; +} + +int runBankSum(NDBT_Context* ctx, NDBT_Step* step){ + Bank bank; + int wait = 2000; // Max ms between each sum of accounts + int yield = 1; // Loops before bank returns + int result = NDBT_OK; + + while (ctx->isTestStopped() == false) { + if (bank.performSumAccounts(wait, yield) != NDBT_OK){ + ndbout << "bank.performSumAccounts FAILED" << endl; + result = NDBT_FAILED; + } + } + return result ; +} + +int runDropBank(NDBT_Context* ctx, NDBT_Step* step){ + Bank bank; + if (bank.dropBank() != NDBT_OK) + return NDBT_FAILED; + return NDBT_OK; +} + +int runBankController(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + int l = 0; + int result = NDBT_OK; + + while (l < loops && result != NDBT_FAILED){ + + if (pNdb->waitUntilReady() != 0){ + result = NDBT_FAILED; + continue; + } + + // Sleep for a while + NdbSleep_SecSleep(records); + + l++; + } + + if (pNdb->waitUntilReady() != 0){ + result = NDBT_FAILED; + } + + ctx->stopTest(); + + return result; +} + +NDBT_TESTSUITE(testBank); +TESTCASE("Bank", + "Run the bank\n"){ + INITIALIZER(runCreateBank); + STEP(runBankTimer); + STEP(runBankTransactions); + STEP(runBankGL); + // TODO STEP(runBankSum); + STEP(runBankController); + FINALIZER(runDropBank); + +} +NDBT_TESTSUITE_END(testBank); + +int main(int argc, const char** argv){ + // Tables should not be auto created + testBank.setCreateTable(false); + + return testBank.execute(argc, argv); +} + + diff --git a/ndb/test/ndbapi/bank/testBank/Makefile b/ndb/test/ndbapi/bank/testBank/Makefile deleted file mode 100644 index 382aaadad7c..00000000000 --- a/ndb/test/ndbapi/bank/testBank/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include .defs.mk - -TYPE = ndbapitest - -BIN_TARGET = testBank -BIN_TARGET_LIBS += bank -SOURCES = testBank.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/bank/testBank/testBank.cpp b/ndb/test/ndbapi/bank/testBank/testBank.cpp deleted file mode 100644 index 094ecaa499c..00000000000 --- a/ndb/test/ndbapi/bank/testBank/testBank.cpp +++ /dev/null @@ -1,150 +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 */ - -#include -#include -#include -#include -#include -#include - - -#define CHECK(b) if (!(b)) { \ - g_err << "ERR: "<< step->getName() \ - << " failed on line " << __LINE__ << endl; \ - result = NDBT_FAILED; \ - continue; } - - -#include "../Bank.hpp" - -int runCreateBank(NDBT_Context* ctx, NDBT_Step* step){ - Bank bank; - int overWriteExisting = true; - if (bank.createAndLoadBank(overWriteExisting) != NDBT_OK) - return NDBT_FAILED; - return NDBT_OK; -} - -int runBankTimer(NDBT_Context* ctx, NDBT_Step* step){ - Bank bank; - int wait = 30; // Max seconds between each "day" - int yield = 1; // Loops before bank returns - - while (ctx->isTestStopped() == false) { - bank.performIncreaseTime(wait, yield); - } - return NDBT_OK; -} - -int runBankTransactions(NDBT_Context* ctx, NDBT_Step* step){ - Bank bank; - int wait = 10; // Max ms between each transaction - int yield = 100; // Loops before bank returns - - while (ctx->isTestStopped() == false) { - bank.performTransactions(wait, yield); - } - return NDBT_OK; -} - -int runBankGL(NDBT_Context* ctx, NDBT_Step* step){ - Bank bank; - int yield = 20; // Loops before bank returns - int result = NDBT_OK; - - while (ctx->isTestStopped() == false) { - if (bank.performMakeGLs(yield) != NDBT_OK){ - ndbout << "bank.performMakeGLs FAILED" << endl; - result = NDBT_FAILED; - } - } - return NDBT_OK; -} - -int runBankSum(NDBT_Context* ctx, NDBT_Step* step){ - Bank bank; - int wait = 2000; // Max ms between each sum of accounts - int yield = 1; // Loops before bank returns - int result = NDBT_OK; - - while (ctx->isTestStopped() == false) { - if (bank.performSumAccounts(wait, yield) != NDBT_OK){ - ndbout << "bank.performSumAccounts FAILED" << endl; - result = NDBT_FAILED; - } - } - return result ; -} - -int runDropBank(NDBT_Context* ctx, NDBT_Step* step){ - Bank bank; - if (bank.dropBank() != NDBT_OK) - return NDBT_FAILED; - return NDBT_OK; -} - -int runBankController(NDBT_Context* ctx, NDBT_Step* step){ - Ndb* pNdb = GETNDB(step); - int loops = ctx->getNumLoops(); - int records = ctx->getNumRecords(); - int l = 0; - int result = NDBT_OK; - - while (l < loops && result != NDBT_FAILED){ - - if (pNdb->waitUntilReady() != 0){ - result = NDBT_FAILED; - continue; - } - - // Sleep for a while - NdbSleep_SecSleep(records); - - l++; - } - - if (pNdb->waitUntilReady() != 0){ - result = NDBT_FAILED; - } - - ctx->stopTest(); - - return result; -} - -NDBT_TESTSUITE(testBank); -TESTCASE("Bank", - "Run the bank\n"){ - INITIALIZER(runCreateBank); - STEP(runBankTimer); - STEP(runBankTransactions); - STEP(runBankGL); - // TODO STEP(runBankSum); - STEP(runBankController); - FINALIZER(runDropBank); - -} -NDBT_TESTSUITE_END(testBank); - -int main(int argc, const char** argv){ - // Tables should not be auto created - testBank.setCreateTable(false); - - return testBank.execute(argc, argv); -} - - diff --git a/ndb/test/ndbapi/basicAsynch/Makefile b/ndb/test/ndbapi/basicAsynch/Makefile deleted file mode 100755 index 802c5e5a2bd..00000000000 --- a/ndb/test/ndbapi/basicAsynch/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := testBasicAsynch - -SOURCES := testBasicAsynch.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/basicAsynch/testBasicAsynch.cpp b/ndb/test/ndbapi/basicAsynch/testBasicAsynch.cpp deleted file mode 100755 index a97920e53da..00000000000 --- a/ndb/test/ndbapi/basicAsynch/testBasicAsynch.cpp +++ /dev/null @@ -1,186 +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 */ - -#include "NDBT_Test.hpp" -#include "NDBT_ReturnCodes.h" -#include "HugoTransactions.hpp" -#include "HugoAsynchTransactions.hpp" -#include "UtilTransactions.hpp" - -#define GETNDB(ps) ((NDBT_NdbApiStep*)ps)->getNdb() - -int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ - - int records = ctx->getNumRecords(); - int batchSize = ctx->getProperty("BatchSize", 1); - int transactions = (records / 100) + 1; - int operations = (records / transactions) + 1; - - HugoAsynchTransactions hugoTrans(*ctx->getTab()); - if (hugoTrans.loadTableAsynch(GETNDB(step), records, batchSize, - transactions, operations) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runInsert(NDBT_Context* ctx, NDBT_Step* step){ - - int records = ctx->getNumRecords(); - int batchSize = ctx->getProperty("BatchSize", 1); - int transactions = (records / 100) + 1; - int operations = (records / transactions) + 1; - - HugoAsynchTransactions hugoTrans(*ctx->getTab()); - // Insert records, dont allow any - // errors(except temporary) while inserting - if (hugoTrans.loadTableAsynch(GETNDB(step), records, batchSize, - transactions, operations) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runVerifyInsert(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - int batchSize = ctx->getProperty("BatchSize", 1); - int transactions = (records / 100) + 1; - int operations = (records / transactions) + 1; - - HugoAsynchTransactions hugoTrans(*ctx->getTab()); - if (hugoTrans.pkDelRecordsAsynch(GETNDB(step), records, batchSize, - transactions, operations) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - int batchSize = ctx->getProperty("BatchSize", 1); - int transactions = (records / 100) + 1; - int operations = (records / transactions) + 1; - - HugoAsynchTransactions hugoTrans(*ctx->getTab()); - if (hugoTrans.pkDelRecordsAsynch(GETNDB(step), records, batchSize, - transactions, operations) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runPkDelete(NDBT_Context* ctx, NDBT_Step* step){ - - int loops = ctx->getNumLoops(); - int records = ctx->getNumRecords(); - int batchSize = ctx->getProperty("BatchSize", 1); - int transactions = (records / 100) + 1; - int operations = (records / transactions) + 1; - - int i = 0; - HugoAsynchTransactions hugoTrans(*ctx->getTab()); - while (igetNumLoops(); - int records = ctx->getNumRecords(); - int batchSize = ctx->getProperty("BatchSize", 1); - int transactions = (records / 100) + 1; - int operations = (records / transactions) + 1; - - int i = 0; - HugoAsynchTransactions hugoTrans(*ctx->getTab()); - while (igetNumLoops(); - int records = ctx->getNumRecords(); - int batchSize = ctx->getProperty("BatchSize", 1); - int transactions = (records / 100) + 1; - int operations = (records / transactions) + 1; - - int i = 0; - HugoAsynchTransactions hugoTrans(*ctx->getTab()); - while (i + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_TIMERS 4 +#define MAXSTRLEN 16 +#define MAXATTR 64 +#define MAXTABLES 64 +#define MAXTHREADS 256 +#define MAXATTRSIZE 8000 +#define START_TIMER NdbTimer timer; timer.doStart(); +#define STOP_TIMER timer.doStop(); +#define START_TIMER_TOP NdbTimer timer_top; timer_top.doStart(); +#define STOP_TIMER_TOP timer_top.doStop(); + +void* ThreadExec(void*); +struct ThreadNdb +{ + int NoOfOps; + int ThreadNo; + Ndb* NdbRef; +}; + +static NdbThread* threadLife[MAXTHREADS]; +static unsigned int tNoOfThreads; +static unsigned int tNoOfOpsPerExecute; +static unsigned int tNoOfRecords; +static unsigned int tNoOfOperations; +static int ThreadReady[MAXTHREADS]; +static int ThreadStart[MAXTHREADS]; + +NDB_COMMAND(benchronja, "benchronja", "benchronja", "benchronja", 65535){ + + ThreadNdb tabThread[MAXTHREADS]; + int i = 0 ; + int cont = 0 ; + Ndb* pMyNdb = NULL ; //( "TEST_DB" ); + int tmp = 0 ; + int nTest = 0 ; + char inp[100] ; + + tNoOfThreads = 1; // Default Value + tNoOfOpsPerExecute = 1; // Default Value + tNoOfOperations = 100000; // Default Value + tNoOfRecords = 500 ; // Default Value 1) + { + if (strcmp(argv[i], "-t") == 0){ + tNoOfThreads = atoi(argv[i+1]); + if ((tNoOfThreads < 1) || (tNoOfThreads > MAXTHREADS)) goto error_input; + }else if (strcmp(argv[i], "-o") == 0){ + tNoOfOperations = atoi(argv[i+1]); + if (tNoOfOperations < 1) goto error_input; + }else if (strcmp(argv[i], "-r") == 0){ + tNoOfRecords = atoi(argv[i+1]); + if ((tNoOfRecords < 1) || (tNoOfRecords > 1000000000)) goto error_input; + }else if (strcmp(argv[i], "-p") == 0){ + nTest = atoi(argv[i+1]) ; + if (0 > nTest || 18 < nTest) goto error_input ; + }else if (strcmp(argv[i], "-c") == 0){ + tNoOfOpsPerExecute = atoi(argv[i+1]); + if ((tNoOfOpsPerExecute < 1) || (tNoOfOpsPerExecute > 1024)) goto error_input; + }else{ + goto error_input; + } + argc -= 2; + i = i + 2; + } + + ndbout << "Initialisation started. " << endl; + pMyNdb = new Ndb("TEST_DB") ; + pMyNdb->init(); + ndbout << "Initialisation completed. " << endl; + + ndbout << endl << "Execute Ronja Benchmark" << endl; + ndbout << " NdbAPI node with id = " << pMyNdb->getNodeId() << endl; + ndbout << " " << tNoOfThreads << " thread(s) " << endl; + ndbout << " " << tNoOfOperations << " transaction(s) per thread and round " << endl; + + if (pMyNdb->waitUntilReady(120) != 0) { + ndbout << "Benchmark failed - NDB is not ready" << endl; + delete pMyNdb ; + return NDBT_ProgramExit(NDBT_FAILED); + }//if + + NdbThread_SetConcurrencyLevel(2 + tNoOfThreads); + + for (i = 0; i < tNoOfThreads ; i++) { + ThreadReady[i] = 0; + ThreadStart[i] = 0; + }//for + + for (i = 0; i < tNoOfThreads ; i++) { + tabThread[i].ThreadNo = i; + tabThread[i].NdbRef = NULL; + tabThread[i].NoOfOps = tNoOfOperations; + threadLife[i] = NdbThread_Create(ThreadExec, + (void**)&tabThread[i], + 32768, + "RonjaThread", + NDB_THREAD_PRIO_LOW); + }//for + + cont = 1; + while (cont) { + NdbSleep_MilliSleep(10); + cont = 0; + for (i = 0; i < tNoOfThreads ; i++) + if (!ThreadReady[i]) cont = 1; + }//while + + ndbout << "All threads started" << endl; + + if(!nTest){ + + for (;;){ + + inp[0] = 0; + ndbout << endl << "What to do next:" << endl; + ndbout << "1 \t=> Perform lookups in short table" << endl; + ndbout << "2 \t=> Perform lookups in long table" << endl; + ndbout << "3 \t=> Perform updates in short table" << endl; + ndbout << "4 \t=> Perform updates in long table" << endl; + ndbout << "5 \t=> Perform 50% lookups/50% updates in short table" << endl; + ndbout << "6 \t=> Perform 50% lookups/50% updates in long table" << endl; + ndbout << "7 \t=> Perform 80% lookups/20% updates in short table" << endl; + ndbout << "8 \t=> Perform 80% lookups/20% updates in long table" << endl; + ndbout << "9 \t=> Perform 25% lookups short/25% lookups long/25% updates short/25% updates long" << endl; + ndbout << "10\t=> Test bug with replicated interpreted updates, short table" << endl; + ndbout << "11\t=> Test interpreter functions, short table" << endl; + ndbout << "12\t=> Test bug with replicated interpreted updates, long table" << endl; + ndbout << "13\t=> Test interpreter functions, long table" << endl; + ndbout << "14\t=> Perform lookups in short table, no guess of TC" << endl; + ndbout << "15\t=> Perform lookups in long table, no guess of TC" << endl; + ndbout << "16\t=> Perform updates in short table, no guess of TC" << endl; + ndbout << "17\t=> Perform updates in long table, no guess of TC" << endl; + ndbout << "18\t=> Multi record updates of transactions" << endl; + ndbout << "All other responses will exit" << endl; + ndbout << "_____________________________" << endl << endl ; + + int inp_i = 0; + do { + inp[inp_i] = (char) fgetc(stdin); + if (inp[inp_i] == '\n' || inp[inp_i] == EOF) { + inp[inp_i] ='\0'; + break; + } + inp_i++; + + } while (inp[inp_i - 1] != '\n' && inp[inp_i - 1] != EOF); + + tmp = atoi(inp); + + if ((tmp > 18) || (tmp <= 0)) break; + + ndbout << "Starting test " << tmp << "..." << endl; + + for (i = 0; i < tNoOfThreads ; i++){ ThreadStart[i] = tmp; } + + cont = 1; + while (cont) { + NdbSleep_MilliSleep(10); + cont = 0; + for (i = 0; i < tNoOfThreads ; i++){ + if (!ThreadReady[i]) cont = 1; + } + }//while + }//for(;;) + + }else{ + + if(19 == nTest){ + ndbout << "Executing all 18 available tests..." << endl << endl; + for (int count = 1; count < nTest; count++){ + ndbout << "Test " << count << endl ; + ndbout << "------" << endl << endl ; + for (i = 0; i < tNoOfThreads ; i++) { ThreadStart[i] = count ; } + cont = 1; + while (cont) { + NdbSleep_MilliSleep(10); + cont = 0; + for (i = 0; i < tNoOfThreads ; i++){ + if (!ThreadReady[i]) cont = 1; + } + } + }//for + }else{ + ndbout << endl << "Executing test " << nTest << endl << endl; + for (i = 0; i < tNoOfThreads ; i++) { ThreadStart[i] = nTest ; } + cont = 1; + while (cont) { + NdbSleep_MilliSleep(10); + cont = 0; + for (i = 0; i < tNoOfThreads ; i++){ + if (!ThreadReady[i]) cont = 1; + } + } + }//if(18 == nTest) + } //if(!nTest) + + ndbout << "--------------------------------------------------" << endl; + + for (i = 0; i < tNoOfThreads ; i++) ThreadReady[i] = 0; + // Signaling threads to stop + for (i = 0; i < tNoOfThreads ; i++) ThreadStart[i] = 999; + + // Wait for threads to stop + cont = 1; + do { + NdbSleep_MilliSleep(1); + cont = 0; + for (i = 0; i < tNoOfThreads ; i++){ + if (ThreadReady[i] == 0) cont = 1; + } + } while (cont == 1); + + delete pMyNdb ; + ndbout << endl << "Ronja Benchmark completed" << endl; + return NDBT_ProgramExit(NDBT_OK) ; + +error_input: + ndbout << endl << " Ivalid parameter(s)" << endl; + ndbout << " Usage: benchronja [-t threads][-r rec] [-o ops] [-c ops_per_exec] [-p test], where:" << endl; + ndbout << " threads - the number of threads to start; default: 1" << endl; + ndbout << " rec - the number of records in the tables; default: 500" << endl; + ndbout << " ops - the number of operations per transaction; default: 100000" << endl; + ndbout << " ops_per_exec - the number of operations per execution; default: 1" << endl ; + ndbout << " test - the number of test to execute; 19 executes all available tests; default: 0"<< endl ; + ndbout << " which enters a loop expecting manual input of test number to execute." << endl << endl ; + delete pMyNdb ; + return NDBT_ProgramExit(NDBT_WRONGARGS) ; + + } +//////////////////////////////////////// + +void commitTrans(Ndb* aNdb, NdbConnection* aCon) +{ + int ret = aCon->execute(Commit); + assert (ret != -1); + aNdb->closeTransaction(aCon); +} + +void rollbackTrans(Ndb* aNdb, NdbConnection* aCon) +{ + int ret = aCon->execute(Rollback); + assert (ret != -1); + aNdb->closeTransaction(aCon); +} + +void updateNoCommit(NdbConnection* aCon, Uint32* flip, unsigned int key) +{ + NdbOperation* theOperation; + + *flip = *flip + 1; + theOperation = aCon->getNdbOperation("SHORT_REC"); + theOperation->updateTuple(); + theOperation->equal((Uint32)0, key); + theOperation->setValue((Uint32)1, (char*)flip); + int ret = aCon->execute(NoCommit); + assert (ret != -1); +} + +void updateNoCommitFail(NdbConnection* aCon, unsigned int key) +{ + NdbOperation* theOperation; + + Uint32 flip = 0; + theOperation = aCon->getNdbOperation("SHORT_REC"); + theOperation->updateTuple(); + theOperation->equal((Uint32)0, key); + theOperation->setValue((Uint32)1, (char*)flip); + int ret = aCon->execute(NoCommit); + assert (ret == -1); +} + +void deleteNoCommit(NdbConnection* aCon, Uint32* flip, unsigned int key) +{ + NdbOperation* theOperation; + + *flip = 0; + theOperation = aCon->getNdbOperation("SHORT_REC"); + theOperation->deleteTuple(); + theOperation->equal((Uint32)0, key); + int ret = aCon->execute(NoCommit); + assert (ret != -1); +} + +void insertNoCommit(NdbConnection* aCon, Uint32* flip, unsigned int key) +{ + NdbOperation* theOperation; + Uint32 placeholder[100]; + + *flip = *flip + 1; + theOperation = aCon->getNdbOperation("SHORT_REC"); + theOperation->insertTuple(); + theOperation->equal((Uint32)0, key); + theOperation->setValue((Uint32)1, (char*)flip); + theOperation->setValue((Uint32)2, (char*)&placeholder[0]); + theOperation->setValue((Uint32)3, (char*)&placeholder[0]); + int ret = aCon->execute(NoCommit); + assert (ret != -1); +} + +void writeNoCommit(NdbConnection* aCon, Uint32* flip, unsigned int key) +{ + NdbOperation* theOperation; + Uint32 placeholder[100]; + + *flip = *flip + 1; + theOperation = aCon->getNdbOperation("SHORT_REC"); + theOperation->writeTuple(); + theOperation->equal((Uint32)0, key); + theOperation->setValue((Uint32)1, (char*)flip); + theOperation->setValue((Uint32)2, (char*)&placeholder[0]); + theOperation->setValue((Uint32)3, (char*)&placeholder[0]); + int ret = aCon->execute(NoCommit); + assert (ret != -1); +} + +void readNoCommit(NdbConnection* aCon, Uint32* flip, Uint32 key, int expected_ret) +{ + NdbOperation* theOperation; + Uint32 readFlip; + + theOperation = aCon->getNdbOperation("SHORT_REC"); + theOperation->readTuple(); + theOperation->equal((Uint32)0, key); + theOperation->getValue((Uint32)1, (char*)&readFlip); + int ret = aCon->execute(NoCommit); + assert (ret == expected_ret); + if (ret == 0) + assert (*flip == readFlip); +} + +void readDirtyNoCommit(NdbConnection* aCon, Uint32* flip, Uint32 key, int expected_ret) +{ + NdbOperation* theOperation; + Uint32 readFlip; + + theOperation = aCon->getNdbOperation("SHORT_REC"); + theOperation->committedRead(); + theOperation->equal((Uint32)0, key); + theOperation->getValue((Uint32)1, (char*)&readFlip); + int ret = aCon->execute(NoCommit); + assert (ret == expected_ret); + if (ret == 0) + assert (*flip == readFlip); +} + +void readVerify(Ndb* aNdb, Uint32* flip, Uint32 key, int expected_ret) +{ + NdbConnection* theTransaction; + theTransaction = aNdb->startTransaction(); + readNoCommit(theTransaction, flip, key, expected_ret); + commitTrans(aNdb, theTransaction); +} + +void readDirty(Ndb* aNdb, Uint32* flip, Uint32 key, int expected_ret) +{ + NdbOperation* theOperation; + NdbConnection* theTransaction; + Uint32 readFlip; + + theTransaction = aNdb->startTransaction(); + theOperation = theTransaction->getNdbOperation("SHORT_REC"); + theOperation->committedRead(); + theOperation->equal((Uint32)0, key); + theOperation->getValue((Uint32)1, (char*)&readFlip); + int ret = theTransaction->execute(Commit); + assert (ret == expected_ret); + if (ret == 0) + assert (*flip == readFlip); + aNdb->closeTransaction(theTransaction); +} + +int multiRecordTest(Ndb* aNdb, unsigned int key) +{ + NdbConnection* theTransaction; + Uint32 flip = 0; + Uint32 save_flip; + ndbout << "0" << endl; + + theTransaction = aNdb->startTransaction(); + + updateNoCommit(theTransaction, &flip, key); + + readNoCommit(theTransaction, &flip, key, 0); + + updateNoCommit(theTransaction, &flip, key); + + readNoCommit(theTransaction, &flip, key, 0); + + commitTrans(aNdb, theTransaction); + + ndbout << "1 " << endl; + + readVerify(aNdb, &flip, key, 0); + readDirty(aNdb, &flip, key, 0); + save_flip = flip; + ndbout << "1.1 " << endl; + + theTransaction = aNdb->startTransaction(); + + deleteNoCommit(theTransaction, &flip, key); + + readNoCommit(theTransaction, &flip, key, -1); + readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!! + readDirtyNoCommit(theTransaction, &flip, key, -1); + ndbout << "1.2 " << endl; + + insertNoCommit(theTransaction, &flip, key); + + readNoCommit(theTransaction, &flip, key, 0); + readDirtyNoCommit(theTransaction, &flip, key, 0); + readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!! + ndbout << "1.3 " << endl; + + updateNoCommit(theTransaction, &flip, key); + + readNoCommit(theTransaction, &flip, key, 0); + readDirtyNoCommit(theTransaction, &flip, key, 0); + readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!! + ndbout << "1.4 " << endl; + + commitTrans(aNdb, theTransaction); + + ndbout << "2 " << endl; + + readDirty(aNdb, &flip, key, 0); // COMMITTED READ!!! + readVerify(aNdb, &flip, key, 0); + + save_flip = flip; + theTransaction = aNdb->startTransaction(); + + deleteNoCommit(theTransaction, &flip, key); + + readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!! + readDirtyNoCommit(theTransaction, &flip, key, -1); // COMMITTED READ!!! + readNoCommit(theTransaction, &flip, key, -1); + + insertNoCommit(theTransaction, &flip, key); + + readNoCommit(theTransaction, &flip, key, 0); + + updateNoCommit(theTransaction, &flip, key); + + readNoCommit(theTransaction, &flip, key, 0); + readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!! + readDirtyNoCommit(theTransaction, &flip, key, 0); // COMMITTED READ!!! + + deleteNoCommit(theTransaction, &flip, key); + + readNoCommit(theTransaction, &flip, key, -1); + readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!! + readDirtyNoCommit(theTransaction, &flip, key, -1); + + rollbackTrans(aNdb, theTransaction); + + ndbout << "3 " << endl; + + flip = save_flip; + readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!! + readVerify(aNdb, &flip, key, 0); + + theTransaction = aNdb->startTransaction(); + + updateNoCommit(theTransaction, &flip, key); + + readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!! + readDirtyNoCommit(theTransaction, &flip, key, 0); + readNoCommit(theTransaction, &flip, key, 0); + + deleteNoCommit(theTransaction, &flip, key); + + readNoCommit(theTransaction, &flip, key, -1); + readDirtyNoCommit(theTransaction, &flip, key, -1); + readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!! + + insertNoCommit(theTransaction, &flip, key); + + readNoCommit(theTransaction, &flip, key, 0); + readDirtyNoCommit(theTransaction, &flip, key, 0); + readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!! + + updateNoCommit(theTransaction, &flip, key); + + readNoCommit(theTransaction, &flip, key, 0); + readDirtyNoCommit(theTransaction, &flip, key, 0); + readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!! + + deleteNoCommit(theTransaction, &flip, key); + + readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!! + readNoCommit(theTransaction, &flip, key, -1); + readDirtyNoCommit(theTransaction, &flip, key, -1); + + commitTrans(aNdb, theTransaction); + + ndbout << "4 " << endl; + + readVerify(aNdb, &flip, key, -1); + + theTransaction = aNdb->startTransaction(); + + insertNoCommit(theTransaction, &flip, key); + + readDirty(aNdb, &save_flip, key, -1); // COMMITTED READ!!! + readNoCommit(theTransaction, &flip, key, 0); + readDirtyNoCommit(theTransaction, &flip, key, 0); + + deleteNoCommit(theTransaction, &flip, key); + + readDirty(aNdb, &save_flip, key, -1); // COMMITTED READ!!! + readNoCommit(theTransaction, &flip, key, -1); + readDirtyNoCommit(theTransaction, &flip, key, -1); + + insertNoCommit(theTransaction, &flip, key); + + readDirty(aNdb, &save_flip, key, -1); // COMMITTED READ!!! + readNoCommit(theTransaction, &flip, key, 0); + readDirtyNoCommit(theTransaction, &flip, key, 0); + + updateNoCommit(theTransaction, &flip, key); + + readDirty(aNdb, &save_flip, key, -1); // COMMITTED READ!!! + readNoCommit(theTransaction, &flip, key, 0); + readDirtyNoCommit(theTransaction, &flip, key, 0); + + deleteNoCommit(theTransaction, &flip, key); + + readDirty(aNdb, &save_flip, key, -1); // COMMITTED READ!!! + readNoCommit(theTransaction, &flip, key, -1); + readDirtyNoCommit(theTransaction, &flip, key, -1); + + commitTrans(aNdb, theTransaction); + + ndbout << "5 " << endl; + + readDirty(aNdb, &flip, key, -1); // COMMITTED READ!!! + readVerify(aNdb, &flip, key, -1); + + theTransaction = aNdb->startTransaction(); + + insertNoCommit(theTransaction, &flip, key); + + readDirty(aNdb, &flip, key, -1); // COMMITTED READ!!! + readDirtyNoCommit(theTransaction, &flip, key, 0); // COMMITTED READ!!! + + commitTrans(aNdb, theTransaction); + readDirty(aNdb, &flip, key, 0); // COMMITTED READ!!! + + ndbout << "6 " << endl; + + theTransaction = aNdb->startTransaction(); + + deleteNoCommit(theTransaction, &flip, key); + updateNoCommitFail(theTransaction, key); + rollbackTrans(aNdb, theTransaction); + return 0; +} + +int lookup(Ndb* aNdb, unsigned int key, unsigned int long_short, int guess){ + + int placeholder[500]; + unsigned int flip, count; + int ret_value, i; + NdbConnection* theTransaction; + NdbOperation* theOperation; + if ( !aNdb ) return -1 ; + + if (guess != 0) + theTransaction = aNdb->startTransaction((Uint32)0, (const char*)&key, (Uint32)4); + else + theTransaction = aNdb->startTransaction(); + + for (i = 0; i < tNoOfOpsPerExecute; i++) { + if (long_short == 0) + theOperation = theTransaction->getNdbOperation("SHORT_REC"); + else + theOperation = theTransaction->getNdbOperation("LONG_REC"); + if (theOperation == NULL) { + ndbout << "Table missing" << endl; + aNdb->closeTransaction(theTransaction) ; + return -1; + }//if + theOperation->simpleRead(); + theOperation->equal((Uint32)0, key); + theOperation->getValue((Uint32)1, (char*)&flip); + theOperation->getValue((Uint32)2, (char*)&count); + if (theOperation->getValue((Uint32)3, (char*)&placeholder[0]) == NULL) { + ndbout << "Error in definition phase = " << theTransaction->getNdbError() << endl; + aNdb->closeTransaction(theTransaction); + return -1; + }//if + }//for + ret_value = theTransaction->execute(Commit); + if (ret_value == -1) + ndbout << "Error in lookup:" << theTransaction->getNdbError() << endl; + aNdb->closeTransaction(theTransaction); + return ret_value; +}//lookup() + +int update(Ndb* aNdb, unsigned int key, unsigned int long_short, int guess) +{ + int placeholder[500]; + int ret_value, i; + unsigned int flip, count; + NdbConnection* theTransaction; + NdbOperation* theOperation; + + if ( !aNdb ) return -1 ; + + if (guess != 0) + theTransaction = aNdb->startTransaction((Uint32)0, (const char*)&key, (Uint32)4); + else + theTransaction = aNdb->startTransaction(); + + for (i = 0; i < tNoOfOpsPerExecute; i++) { + if (long_short == 0) + theOperation = theTransaction->getNdbOperation("SHORT_REC"); // Use table SHORT_REC + else + theOperation = theTransaction->getNdbOperation("LONG_REC"); // Use table LONG_REC + if (theOperation == NULL) { + ndbout << "Table missing" << endl; + aNdb->closeTransaction(theTransaction) ; + delete aNdb ; + return -1; + }//if + theOperation->interpretedUpdateTuple(); // Send interpreted program to NDB kernel + theOperation->equal((Uint32)0, key); // Search key + theOperation->getValue((Uint32)1, (char*)&flip); // Read value of flip + theOperation->getValue((Uint32)2, (char*)&count); // Read value of count + theOperation->getValue((Uint32)3, (char*)&placeholder[0]); // Read value of placeholder + theOperation->load_const_u32((Uint32)1, (Uint32)0); // Load register 1 with 0 + theOperation->read_attr((Uint32)1, (Uint32)2); // Read Flip value into register 2 + theOperation->branch_eq((Uint32)1, (Uint32)2, (Uint32)0); // If Flip (register 2) == 0 (register 1) goto label 0 + theOperation->branch_label((Uint32)1); // Goto label 1 + theOperation->def_label((Uint32)0); // Define label 0 + theOperation->load_const_u32((Uint32)1, (Uint32)1); // Load register 1 with 1 + theOperation->def_label((Uint32)1); // Define label 0 + theOperation->write_attr((Uint32)1, (Uint32)1); // Write 1 (register 1) into Flip + ret_value = theOperation->incValue((Uint32)2, (Uint32)1); // Increment Count by 1 + if (ret_value == -1) { + ndbout << "Error in definition phase " << endl; + aNdb->closeTransaction(theTransaction); + return ret_value; + }//if + }//for + ret_value = theTransaction->execute(Commit); // Perform the actual read and update + if (ret_value == -1) { + ndbout << "Error in update:" << theTransaction->getNdbError() << endl; + aNdb->closeTransaction(theTransaction); // < epaulsa + return ret_value ; + }//if + aNdb->closeTransaction(theTransaction); + return ret_value; +}//update() + +int update_bug(Ndb* aNdb, unsigned int key, unsigned int long_short) +{ + int placeholder[500]; + int ret_value, i; + unsigned int flip, count; + NdbConnection* theTransaction; + NdbOperation* theOperation; + + if ( !aNdb ) return -1 ; + + theTransaction = aNdb->startTransaction(); + for (i = 0; i < tNoOfOpsPerExecute; i++) { + if (long_short == 0) + theOperation = theTransaction->getNdbOperation("SHORT_REC"); // Use table SHORT_REC + else + theOperation = theTransaction->getNdbOperation("LONG_REC"); // Use table LONG_REC + if (theOperation == NULL) { + ndbout << "Table missing" << endl; + aNdb->closeTransaction(theTransaction) ; + return -1; + }//if + theOperation->interpretedUpdateTuple(); // Send interpreted program to NDB kernel + theOperation->equal((Uint32)0, key); // Search key + theOperation->getValue((Uint32)1, (char*)&flip); // Read value of flip + theOperation->getValue((Uint32)2, (char*)&count); // Read value of count + theOperation->getValue((Uint32)3, (char*)&placeholder[0]); // Read value of placeholder + theOperation->load_const_u32((Uint32)1, (Uint32)0); // Load register 1 with 0 + theOperation->read_attr((Uint32)1, (Uint32)2); // Read Flip value into register 2 + theOperation->branch_eq((Uint32)1, (Uint32)2, (Uint32)0); // If Flip (register 2) == 0 (register 1) goto label 0 + theOperation->branch_label((Uint32)1); // Goto label 1 + theOperation->def_label((Uint32)0); // Define label 0 + theOperation->load_const_u32((Uint32)1, (Uint32)1); // Load register 1 with 1 + theOperation->def_label((Uint32)1); // Define label 0 + theOperation->write_attr((Uint32)1, (Uint32)1); // Write 1 (register 1) into Flip + ret_value = theOperation->incValue((Uint32)2, (Uint32)1); // Increment Count by 1 + if (ret_value == -1) { + ndbout << "Error in definition phase " << endl; + aNdb->closeTransaction(theTransaction); + return ret_value; + }//if + }//for + ret_value = theTransaction->execute(NoCommit); // Perform the actual read and update + if (ret_value == -1) { + ndbout << "Error in update:" << theTransaction->getNdbError() << endl; + aNdb->closeTransaction(theTransaction); + return ret_value ; + }//if + aNdb->closeTransaction(theTransaction); + return ret_value; +}//update_bug() + +int update_interpreter_test(Ndb* aNdb, unsigned int key, unsigned int long_short) +{ + int placeholder[500]; + int ret_value, i; + unsigned int flip, count; + NdbConnection* theTransaction; + NdbOperation* theOperation; + Uint32 Tlabel = 0; + + if ( !aNdb ) return -1 ; + +//------------------------------------------------------------------------------ +// Start the transaction and get a unique transaction id +//------------------------------------------------------------------------------ + theTransaction = aNdb->startTransaction(); + for (i = 0; i < tNoOfOpsPerExecute; i++) { +//------------------------------------------------------------------------------ +// Get the proper table object and load schema information if not already +// present. +//------------------------------------------------------------------------------ + if (long_short == 0) + theOperation = theTransaction->getNdbOperation("SHORT_REC"); // Use table SHORT_REC + else + theOperation = theTransaction->getNdbOperation("LONG_REC"); // Use table LONG_REC + if (theOperation == NULL) { + ndbout << "Table missing" << endl; + aNdb->closeTransaction(theTransaction) ; + return -1; + }//if +//------------------------------------------------------------------------------ +// Define the operation type and the tuple key (primary key in this case). +//------------------------------------------------------------------------------ + theOperation->interpretedUpdateTuple(); // Send interpreted program to NDB kernel + theOperation->equal((Uint32)0, key); // Search key + +//------------------------------------------------------------------------------ +// Perform initial read of attributes before updating them +//------------------------------------------------------------------------------ + theOperation->getValue((Uint32)1, (char*)&flip); // Read value of flip + theOperation->getValue((Uint32)2, (char*)&count); // Read value of count + theOperation->getValue((Uint32)3, (char*)&placeholder[0]); // Read value of placeholder + +//------------------------------------------------------------------------------ +// Test that the various branch operations can handle things correctly. +// Test first 2 + 3 = 5 with 32 bit registers +// Next test the same with 32 bit + 64 bit = 64 +//------------------------------------------------------------------------------ + theOperation->load_const_u32((Uint32)4, (Uint32)0); // Load register 4 with 0 + + theOperation->load_const_u32((Uint32)0, (Uint32)0); + theOperation->load_const_u32((Uint32)1, (Uint32)3); + theOperation->load_const_u32((Uint32)2, (Uint32)5); + theOperation->load_const_u32((Uint32)3, (Uint32)1); + theOperation->def_label(Tlabel++); + theOperation->def_label(Tlabel++); + theOperation->sub_reg((Uint32)2, (Uint32)3, (Uint32)2); + theOperation->branch_ne((Uint32)2, (Uint32)0, (Uint32)0); + theOperation->load_const_u32((Uint32)2, (Uint32)5); + theOperation->sub_reg((Uint32)1, (Uint32)3, (Uint32)1); + theOperation->branch_ne((Uint32)1, (Uint32)0, (Uint32)1); + + theOperation->load_const_u32((Uint32)1, (Uint32)2); // Load register 1 with 2 + theOperation->load_const_u32((Uint32)2, (Uint32)3); // Load register 2 with 3 + theOperation->add_reg((Uint32)1, (Uint32)2, (Uint32)1); // 2+3 = 5 into reg 1 + theOperation->load_const_u32((Uint32)2, (Uint32)5); // Load register 2 with 5 + + theOperation->def_label(Tlabel++); + + theOperation->branch_eq((Uint32)1, (Uint32)2, Tlabel); + theOperation->interpret_exit_nok((Uint32)6001); + + theOperation->def_label(Tlabel++); + theOperation->branch_ne((Uint32)1, (Uint32)2, Tlabel); + theOperation->branch_label(Tlabel + 1); + theOperation->def_label(Tlabel++); + theOperation->interpret_exit_nok((Uint32)6002); + + theOperation->def_label(Tlabel++); + theOperation->branch_lt((Uint32)1, (Uint32)2, Tlabel); + theOperation->branch_label(Tlabel + 1); + theOperation->def_label(Tlabel++); + theOperation->interpret_exit_nok((Uint32)6003); + + theOperation->def_label(Tlabel++); + theOperation->branch_gt((Uint32)1, (Uint32)2, Tlabel); + theOperation->branch_label(Tlabel + 1); + theOperation->def_label(Tlabel++); + theOperation->interpret_exit_nok((Uint32)6005); + + theOperation->def_label(Tlabel++); + theOperation->branch_eq_null((Uint32)1, Tlabel); + theOperation->branch_label(Tlabel + 1); + theOperation->def_label(Tlabel++); + theOperation->interpret_exit_nok((Uint32)6006); + + theOperation->def_label(Tlabel++); + theOperation->branch_ne_null((Uint32)1,Tlabel); + theOperation->interpret_exit_nok((Uint32)6007); + + theOperation->def_label(Tlabel++); + theOperation->branch_ge((Uint32)1, (Uint32)2, Tlabel); + theOperation->interpret_exit_nok((Uint32)6008); + + theOperation->def_label(Tlabel++); + theOperation->branch_eq_null((Uint32)6,Tlabel); + theOperation->interpret_exit_nok((Uint32)6009); + + theOperation->def_label(Tlabel++); + theOperation->branch_ne_null((Uint32)6, Tlabel); + theOperation->branch_label(Tlabel + 1); + theOperation->def_label(Tlabel++); + theOperation->interpret_exit_nok((Uint32)6010); + + theOperation->def_label(Tlabel++); + + theOperation->load_const_u32((Uint32)5, (Uint32)1); + theOperation->add_reg((Uint32)4, (Uint32)5, (Uint32)4); + + theOperation->load_const_u32((Uint32)5, (Uint32)1); + theOperation->branch_eq((Uint32)4, (Uint32)5, Tlabel); + + + theOperation->load_const_u32((Uint32)5, (Uint32)2); + theOperation->branch_eq((Uint32)4, (Uint32)5, (Tlabel + 1)); + + theOperation->load_const_u32((Uint32)5, (Uint32)3); + theOperation->branch_eq((Uint32)4, (Uint32)5, (Tlabel + 2)); + + theOperation->load_const_u32((Uint32)5, (Uint32)4); + theOperation->branch_eq((Uint32)4, (Uint32)5, (Tlabel + 3)); + + theOperation->branch_label(Tlabel + 4); + + theOperation->def_label(Tlabel++); + theOperation->load_const_u32((Uint32)1, (Uint32)200000); + theOperation->load_const_u32((Uint32)2, (Uint32)300000); + theOperation->add_reg((Uint32)1, (Uint32)2, (Uint32)1); + theOperation->load_const_u32((Uint32)2, (Uint32)500000); + theOperation->branch_label((Uint32)2); + + theOperation->def_label(Tlabel++); + theOperation->load_const_u32((Uint32)1, (Uint32)200000); + theOperation->load_const_u32((Uint32)2, (Uint32)300000); + theOperation->add_reg((Uint32)1, (Uint32)2, (Uint32)1); + theOperation->load_const_u32((Uint32)2, (Uint32)500000); + theOperation->branch_label((Uint32)2); + + theOperation->def_label(Tlabel++); + theOperation->load_const_u32((Uint32)1, (Uint32)2); + Uint64 x = 0; + theOperation->load_const_u64((Uint32)2, (Uint64)(x - 1)); + theOperation->add_reg((Uint32)1, (Uint32)2, (Uint32)1); + theOperation->load_const_u32((Uint32)2, (Uint32)1); + theOperation->branch_label((Uint32)2); + + theOperation->def_label(Tlabel++); + theOperation->load_const_u32((Uint32)1, (Uint32)2); + theOperation->load_const_u64((Uint32)2, (Uint64)(x - 1)); + theOperation->add_reg((Uint32)1, (Uint32)2, (Uint32)1); + theOperation->load_const_u64((Uint32)2, (Uint64)1); + theOperation->branch_label((Uint32)2); + + theOperation->def_label(Tlabel++); + theOperation->read_attr((Uint32)1, (Uint32)2); + theOperation->branch_eq((Uint32)1, (Uint32)2, Tlabel); + theOperation->load_const_u32((Uint32)1, (Uint32)0); + theOperation->branch_label(Tlabel + 1); + theOperation->def_label(Tlabel++); + theOperation->load_const_u32((Uint32)1, (Uint32)1); + theOperation->def_label(Tlabel++); + theOperation->write_attr((Uint32)1, (Uint32)1); + ret_value = theOperation->incValue((Uint32)2, (Uint32)1); + if (ret_value == -1) { + ndbout << "Error in definition phase " << endl; + ndbout << "Error = " << theOperation->getNdbError() << " on line = " << theOperation->getNdbErrorLine() << endl; + aNdb->closeTransaction(theTransaction); + return ret_value; + }//if + }//for +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ + ret_value = theTransaction->execute(Commit); // Perform the actual read and update + if (ret_value == -1) { + ndbout << "Error in update:" << theTransaction->getNdbError() << endl; + aNdb->closeTransaction(theTransaction); // < epaulsa + return ret_value ; + }//if +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ + aNdb->closeTransaction(theTransaction); + return ret_value; +}//update_interpreter_test() + +void* ThreadExec(void* ThreadData){ + + ThreadNdb* tabThread = (ThreadNdb*)ThreadData; + Ndb* pMyNdb = NULL ; + myRandom48Init(NdbTick_CurrentMillisecond()); + + int Tsuccess = 0 ; + int check = 0 ; + int loop_count_ops = 0; + int count, i, Ti; + int tType = 0 ; + int remType = 0 ; + unsigned int thread_no = 0 ; + unsigned long total_milliseconds; + unsigned int key = 0 ; + unsigned int prob = 0 ; + unsigned long transaction_time = 0 ; + unsigned long transaction_max_time = 0 ; + unsigned long min_time, max_time[MAX_TIMERS]; + double mean_time, mean_square_time, std_time; + + thread_no = tabThread->ThreadNo; + pMyNdb = tabThread->NdbRef; + if (!pMyNdb) { + pMyNdb = new Ndb( "TEST_DB" ); + pMyNdb->init(); + }//if + + for (;;){ + + min_time = 0xFFFFFFFF; + //for (Ti = 0; Ti < MAX_TIMERS ; Ti++) max_time[Ti] = 0; + memset(&max_time, 0, sizeof max_time) ; + mean_time = 0; + mean_square_time = 0; + ThreadReady[thread_no] = 1; + + while (!ThreadStart[thread_no]){ + NdbSleep_MilliSleep(1); + } + + // Check if signal to exit is received + if (ThreadStart[thread_no] == 999){ + delete pMyNdb; + pMyNdb = NULL ; + ThreadReady[thread_no] = 1; + NdbThread_Exit(0) ; + return 0 ; + }//if + + tType = ThreadStart[thread_no]; + remType = tType; + ThreadStart[thread_no] = 0; + ThreadReady[thread_no] = 0 ; + + // Start transaction, type of transaction + // is received in the array ThreadStart + loop_count_ops = tNoOfOperations; + + START_TIMER_TOP + for (count=0 ; count < loop_count_ops ; count++) { + + Tsuccess = 0; +//---------------------------------------------------- +// Generate a random key between 0 and tNoOfRecords - 1 +//---------------------------------------------------- + key = myRandom48(tNoOfRecords); +//---------------------------------------------------- +// Start time measurement of transaction. +//---------------------------------------------------- + START_TIMER + //do { + switch (remType){ + case 1: +//---------------------------------------------------- +// Only lookups in short record table +//---------------------------------------------------- + Tsuccess = lookup(pMyNdb, key, 0, 1); + break; + + case 2: +//---------------------------------------------------- +// Only lookups in long record table +//---------------------------------------------------- + Tsuccess = lookup(pMyNdb, key, 1, 1); + break; + case 3: +//---------------------------------------------------- +// Only updates in short record table +//---------------------------------------------------- + Tsuccess = update(pMyNdb, key, 0, 1); + break; + case 4: +//---------------------------------------------------- +// Only updates in long record table +//---------------------------------------------------- + Tsuccess = update(pMyNdb, key, 1, 1); + break; + case 5: +//---------------------------------------------------- +// 50% read/50 % update in short record table +//---------------------------------------------------- + prob = myRandom48(100); + if (prob < 50) + Tsuccess = update(pMyNdb, key, 0, 1); + else + Tsuccess = lookup(pMyNdb, key, 0, 1); + break; + case 6: +//---------------------------------------------------- +// 50% read/50 % update in long record table +//---------------------------------------------------- + prob = myRandom48(100); + if (prob < 50) + Tsuccess = update(pMyNdb, key, 1, 1); + else + Tsuccess = lookup(pMyNdb, key, 1, 1); + break; + case 7: +//---------------------------------------------------- +// 80 read/20 % update in short record table +//---------------------------------------------------- + prob = myRandom48(100); + if (prob < 20) + Tsuccess = update(pMyNdb, key, 0, 1); + else + Tsuccess = lookup(pMyNdb, key, 0, 1); + break; + case 8: +//---------------------------------------------------- +// 80 read/20 % update in long record table +//---------------------------------------------------- + prob = myRandom48(100); + if (prob < 20) + Tsuccess = update(pMyNdb, key, 1, 1); + else + Tsuccess = lookup(pMyNdb, key, 1, 1); + break; + case 9: +//---------------------------------------------------- +// 25 read short/25 % read long/25 % update short/25 % update long +//---------------------------------------------------- + prob = myRandom48(100); + if (prob < 25) + Tsuccess = update(pMyNdb, key, 0, 1); + else if (prob < 50) + Tsuccess = update(pMyNdb, key, 1, 1); + else if (prob < 75) + Tsuccess = lookup(pMyNdb, key, 0, 1); + else + Tsuccess = lookup(pMyNdb, key, 1, 1); + break; + case 10: +//---------------------------------------------------- +// Test bug with replicated interpreted update, short table +//---------------------------------------------------- + Tsuccess = update_bug(pMyNdb, key, 0); + break; + case 11: +//---------------------------------------------------- +// Test interpreter functions, short table +//---------------------------------------------------- + Tsuccess = update_interpreter_test(pMyNdb, key, 0); + break; + case 12: +//---------------------------------------------------- +// Test bug with replicated interpreted update, long table +//---------------------------------------------------- + Tsuccess = update_bug(pMyNdb, key, 1); + break; + case 13: +//---------------------------------------------------- +// Test interpreter functions, long table +//---------------------------------------------------- + Tsuccess = update_interpreter_test(pMyNdb, key, 1); + break; + case 14: +//---------------------------------------------------- +// Only lookups in short record table +//---------------------------------------------------- + Tsuccess = lookup(pMyNdb, key, 0, 0); + break; + case 15: +//---------------------------------------------------- +// Only lookups in long record table +//---------------------------------------------------- + Tsuccess = lookup(pMyNdb, key, 1, 0); + break; + case 16: +//---------------------------------------------------- +// Only updates in short record table +//---------------------------------------------------- + Tsuccess = update(pMyNdb, key, 0, 0); + break; + case 17: +//---------------------------------------------------- +// Only updates in long record table +//---------------------------------------------------- + Tsuccess = update(pMyNdb, key, 1, 0); + break; + case 18: + Tsuccess = multiRecordTest(pMyNdb, key); + break; + default: + break; + }//switch + //} while (0);// + if(-1 == Tsuccess) { + NDBT_ProgramExit(NDBT_FAILED); + exit(-1); + } // for +//---------------------------------------------------- +// Stop time measurement of transaction. +//---------------------------------------------------- + STOP_TIMER + transaction_time = (unsigned long)timer.elapsedTime() ;//stopTimer(&theStartTime); +//---------------------------------------------------- +// Perform calculations of time measurements. +//---------------------------------------------------- + transaction_max_time = transaction_time; + for (Ti = 0; Ti < MAX_TIMERS; Ti++) { + if (transaction_max_time > max_time[Ti]) { + Uint32 tmp = max_time[Ti]; + max_time[Ti] = transaction_max_time; + transaction_max_time = tmp; + }//if + }//if + if (transaction_time < min_time) min_time = transaction_time; + mean_time = (double)transaction_time + mean_time; + mean_square_time = (double)(transaction_time * transaction_time) + mean_square_time; + }//for +//---------------------------------------------------- +// Calculate mean and standard deviation +//---------------------------------------------------- + STOP_TIMER_TOP + total_milliseconds = (unsigned long)timer_top.elapsedTime() ;//stopTimer(&total_time); + mean_time = mean_time / loop_count_ops; + mean_square_time = mean_square_time / loop_count_ops; + std_time = sqrt(mean_square_time - (mean_time * mean_time)); +//---------------------------------------------------- +// Report statistics +//---------------------------------------------------- + ndbout << "Thread = " << thread_no << " reporting:" << endl ; + ndbout << "------------------------------" << endl ; + ndbout << "Total time is " << (unsigned int)(total_milliseconds /1000); + ndbout << " seconds and " << (unsigned int)(total_milliseconds % 1000); + ndbout << " milliseconds" << endl; + ndbout << "Minimum time = " << (unsigned int)min_time << " milliseconds" << endl; + for (Ti = 0; Ti < MAX_TIMERS; Ti++) { + ndbout << "Maximum timer " << Ti << " = " << (unsigned int)max_time[Ti] << " milliseconds" << endl; + ndbout << "Mean time = " << (unsigned int)mean_time << " milliseconds" << endl; + ndbout << "Standard deviation on time = " << (unsigned int)std_time; + ndbout << " milliseconds" << endl << endl ; + }//for + ndbout << endl ; + + } // for(;;) + + delete pMyNdb ; + NdbThread_Exit(0) ; + return 0 ; // Compiler is happy now +} + diff --git a/ndb/test/ndbapi/bulk_copy.cpp b/ndb/test/ndbapi/bulk_copy.cpp new file mode 100644 index 00000000000..18881cae216 --- /dev/null +++ b/ndb/test/ndbapi/bulk_copy.cpp @@ -0,0 +1,275 @@ +/* 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 */ + + +#include +#include +#include +#include + +#include + + +int setValuesFromLine(NdbOperation* pOp, + const NdbDictionary::Table* pTab, + char* line){ + + int check = 0; + char* p = line; + char* pn; + char buf[8000]; + // Loop through each attribute in this table + for (int a = 0; agetNoOfColumns(); a++){ + + pn = p; + while (*pn != ';') + pn++; + + memset(buf, 0, sizeof(buf)); + strncpy(buf, p, pn-p); + // ndbout << a << ": " << buf << endl; + const NdbDictionary::Column* attr = pTab->getColumn(a); + switch (attr->getType()){ + case NdbDictionary::Column::Unsigned: + Int32 sval; + if (sscanf(buf, "%d", &sval) == 0) + return -2; + check = pOp->setValue(a, sval); + break; + + case NdbDictionary::Column::Int: + Uint32 uval; + if (sscanf(buf, "%u", &uval) == 0) + return -2; + check = pOp->setValue(a, uval); + break; + + case NdbDictionary::Column::Char: + char buf2[8000]; + char* p2; + memset(buf2, 0, sizeof(buf)); + p2 = &buf2[0]; + while(*p != ';'){ + *p2 = *p; + p++;p2++; + }; + *p2 = 0; + check = pOp->setValue(a, buf2); + break; + + default: + check = -2; + break; + } + + // Move pointer to after next ";" + while (*p != ';') + p++; + p++; + + } + + return check; +} + + +int insertLine(Ndb* pNdb, + const NdbDictionary::Table* pTab, + char* line){ + int check; + int retryAttempt = 0; + int retryMax = 5; + NdbConnection *pTrans; + NdbOperation *pOp; + + while (retryAttempt < retryMax){ + + pTrans = pNdb->startTransaction(); + if (pTrans == NULL) { + ERR(pNdb->getNdbError()); + NdbSleep_MilliSleep(50); + retryAttempt++; + continue; + } + + pOp = pTrans->getNdbOperation(pTab->getName()); + if (pOp == NULL) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return -1; + } + + check = pOp->insertTuple(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return -1; + } + + check = setValuesFromLine(pOp, + pTab, + line); + if (check == -2){ + pNdb->closeTransaction(pTrans); + return -2; + } + if( check == -1 ) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return -1; + } + + + // Execute the transaction and insert the record + check = pTrans->execute( Commit ); + if(check == -1 ) { + const NdbError err = pTrans->getNdbError(); + pNdb->closeTransaction(pTrans); + + switch(err.status){ + case NdbError::Success: + ERR(err); + ndbout << "ERROR: NdbError reports success when transcaction failed" << endl; + return -1; + break; + + case NdbError::TemporaryError: + ERR(err); + NdbSleep_MilliSleep(50); + retryAttempt++; + continue; + break; + + case NdbError::UnknownResult: + ERR(err); + return -1; + break; + + case NdbError::PermanentError: + switch (err.classification){ + case NdbError::ConstraintViolation: + // Tuple already existed, OK in this application, but should be reported + ndbout << err.code << " " << err.message << endl; + break; + default: + ERR(err); + return -1; + break; + } + break; + } + } + else{ + + pNdb->closeTransaction(pTrans); + } + return 0; + } + return check; +} + +int insertFile(Ndb* pNdb, + const NdbDictionary::Table* pTab, + const char* fileName){ + + const int MAX_LINE_LEN = 8000; + char line[MAX_LINE_LEN]; + int lineNo = 0; + + FILE* instr = fopen(fileName, "r"); + if (instr == NULL){ + ndbout << "Coul'd not open " << fileName << endl; + return -1; + } + + while(fgets(line, MAX_LINE_LEN, instr)){ + lineNo++; + + if (line[strlen(line)-1] == '\n') { + line[strlen(line)-1] = '\0'; + } + + int check = insertLine(pNdb, pTab, line); + if (check == -2){ + ndbout << "Wrong format in input data file, line: " << lineNo << endl; + fclose(instr); + return -1; + } + if (check == -1){ + fclose(instr); + return -1; + + } + } + + fclose(instr); + return 0; +} + + +int main(int argc, const char** argv){ + + const char* _tabname = NULL; + int _help = 0; + + struct getargs args[] = { + { "usage", '?', arg_flag, &_help, "Print help", "" } + }; + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + char desc[] = + "tabname\n"\ + "This program will bulk copy data from a file to a table in Ndb.\n"; + + if(getarg(args, num_args, argc, argv, &optind) || + argv[optind] == NULL || _help) { + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + _tabname = argv[optind]; + ndbout << "Tablename: " << _tabname << endl; + + // Connect to Ndb + Ndb MyNdb( "TEST_DB" ); + + if(MyNdb.init() != 0){ + ERR(MyNdb.getNdbError()); + return NDBT_ProgramExit(NDBT_FAILED); + } + + // Connect to Ndb and wait for it to become ready + while(MyNdb.waitUntilReady() != 0) + ndbout << "Waiting for ndb to become ready..." << endl; + + // Check if table exists in db + const NdbDictionary::Table* pTab = MyNdb.getDictionary()->getTable(_tabname); + if(pTab == NULL){ + ndbout << " Table " << _tabname << " does not exist!" << endl; + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + + char buf[255]; + snprintf(buf, sizeof(buf), "%s.data", (const char*)_tabname); + if (insertFile(&MyNdb, pTab, buf) != 0){ + return NDBT_ProgramExit(NDBT_FAILED); + } + + return NDBT_ProgramExit(NDBT_OK); + +} + + + diff --git a/ndb/test/ndbapi/bulk_copy/Makefile b/ndb/test/ndbapi/bulk_copy/Makefile deleted file mode 100644 index 22c05b138b7..00000000000 --- a/ndb/test/ndbapi/bulk_copy/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := bulk_copy - -SOURCES := bulk_copy.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/bulk_copy/bulk_copy.cpp b/ndb/test/ndbapi/bulk_copy/bulk_copy.cpp deleted file mode 100644 index 18881cae216..00000000000 --- a/ndb/test/ndbapi/bulk_copy/bulk_copy.cpp +++ /dev/null @@ -1,275 +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 */ - - -#include -#include -#include -#include - -#include - - -int setValuesFromLine(NdbOperation* pOp, - const NdbDictionary::Table* pTab, - char* line){ - - int check = 0; - char* p = line; - char* pn; - char buf[8000]; - // Loop through each attribute in this table - for (int a = 0; agetNoOfColumns(); a++){ - - pn = p; - while (*pn != ';') - pn++; - - memset(buf, 0, sizeof(buf)); - strncpy(buf, p, pn-p); - // ndbout << a << ": " << buf << endl; - const NdbDictionary::Column* attr = pTab->getColumn(a); - switch (attr->getType()){ - case NdbDictionary::Column::Unsigned: - Int32 sval; - if (sscanf(buf, "%d", &sval) == 0) - return -2; - check = pOp->setValue(a, sval); - break; - - case NdbDictionary::Column::Int: - Uint32 uval; - if (sscanf(buf, "%u", &uval) == 0) - return -2; - check = pOp->setValue(a, uval); - break; - - case NdbDictionary::Column::Char: - char buf2[8000]; - char* p2; - memset(buf2, 0, sizeof(buf)); - p2 = &buf2[0]; - while(*p != ';'){ - *p2 = *p; - p++;p2++; - }; - *p2 = 0; - check = pOp->setValue(a, buf2); - break; - - default: - check = -2; - break; - } - - // Move pointer to after next ";" - while (*p != ';') - p++; - p++; - - } - - return check; -} - - -int insertLine(Ndb* pNdb, - const NdbDictionary::Table* pTab, - char* line){ - int check; - int retryAttempt = 0; - int retryMax = 5; - NdbConnection *pTrans; - NdbOperation *pOp; - - while (retryAttempt < retryMax){ - - pTrans = pNdb->startTransaction(); - if (pTrans == NULL) { - ERR(pNdb->getNdbError()); - NdbSleep_MilliSleep(50); - retryAttempt++; - continue; - } - - pOp = pTrans->getNdbOperation(pTab->getName()); - if (pOp == NULL) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return -1; - } - - check = pOp->insertTuple(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return -1; - } - - check = setValuesFromLine(pOp, - pTab, - line); - if (check == -2){ - pNdb->closeTransaction(pTrans); - return -2; - } - if( check == -1 ) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return -1; - } - - - // Execute the transaction and insert the record - check = pTrans->execute( Commit ); - if(check == -1 ) { - const NdbError err = pTrans->getNdbError(); - pNdb->closeTransaction(pTrans); - - switch(err.status){ - case NdbError::Success: - ERR(err); - ndbout << "ERROR: NdbError reports success when transcaction failed" << endl; - return -1; - break; - - case NdbError::TemporaryError: - ERR(err); - NdbSleep_MilliSleep(50); - retryAttempt++; - continue; - break; - - case NdbError::UnknownResult: - ERR(err); - return -1; - break; - - case NdbError::PermanentError: - switch (err.classification){ - case NdbError::ConstraintViolation: - // Tuple already existed, OK in this application, but should be reported - ndbout << err.code << " " << err.message << endl; - break; - default: - ERR(err); - return -1; - break; - } - break; - } - } - else{ - - pNdb->closeTransaction(pTrans); - } - return 0; - } - return check; -} - -int insertFile(Ndb* pNdb, - const NdbDictionary::Table* pTab, - const char* fileName){ - - const int MAX_LINE_LEN = 8000; - char line[MAX_LINE_LEN]; - int lineNo = 0; - - FILE* instr = fopen(fileName, "r"); - if (instr == NULL){ - ndbout << "Coul'd not open " << fileName << endl; - return -1; - } - - while(fgets(line, MAX_LINE_LEN, instr)){ - lineNo++; - - if (line[strlen(line)-1] == '\n') { - line[strlen(line)-1] = '\0'; - } - - int check = insertLine(pNdb, pTab, line); - if (check == -2){ - ndbout << "Wrong format in input data file, line: " << lineNo << endl; - fclose(instr); - return -1; - } - if (check == -1){ - fclose(instr); - return -1; - - } - } - - fclose(instr); - return 0; -} - - -int main(int argc, const char** argv){ - - const char* _tabname = NULL; - int _help = 0; - - struct getargs args[] = { - { "usage", '?', arg_flag, &_help, "Print help", "" } - }; - int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; - char desc[] = - "tabname\n"\ - "This program will bulk copy data from a file to a table in Ndb.\n"; - - if(getarg(args, num_args, argc, argv, &optind) || - argv[optind] == NULL || _help) { - arg_printusage(args, num_args, argv[0], desc); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - _tabname = argv[optind]; - ndbout << "Tablename: " << _tabname << endl; - - // Connect to Ndb - Ndb MyNdb( "TEST_DB" ); - - if(MyNdb.init() != 0){ - ERR(MyNdb.getNdbError()); - return NDBT_ProgramExit(NDBT_FAILED); - } - - // Connect to Ndb and wait for it to become ready - while(MyNdb.waitUntilReady() != 0) - ndbout << "Waiting for ndb to become ready..." << endl; - - // Check if table exists in db - const NdbDictionary::Table* pTab = MyNdb.getDictionary()->getTable(_tabname); - if(pTab == NULL){ - ndbout << " Table " << _tabname << " does not exist!" << endl; - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - - char buf[255]; - snprintf(buf, sizeof(buf), "%s.data", (const char*)_tabname); - if (insertFile(&MyNdb, pTab, buf) != 0){ - return NDBT_ProgramExit(NDBT_FAILED); - } - - return NDBT_ProgramExit(NDBT_OK); - -} - - - diff --git a/ndb/test/ndbapi/cdrserver.cpp b/ndb/test/ndbapi/cdrserver.cpp new file mode 100644 index 00000000000..8354d28f53f --- /dev/null +++ b/ndb/test/ndbapi/cdrserver.cpp @@ -0,0 +1,1627 @@ +/* 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 */ + +/* **************************************************************** */ +/* */ +/* S E R V . T C P */ +/* * This is an example program that demonstrates the use of */ +/* stream sockets as an IPC mechanism. This contains the server, */ +/* and is intended to operate in conjunction with the client */ +/* program found in client.tcp. Together, these two programs */ +/* demonstrate many of the features of sockets, as well as good */ +/* conventions for using these features. */ +/* * This program provides a service called "example". In order for*/ +/* it to function, an entry for it needs to exist in the */ +/* ./etc/services file. The port address for this service can be */ +/* any port number that is likely to be unused, such as 22375, */ +/* for example. The host on which the client will be running */ +/* must also have the same entry (same port number) in its */ +/* ./etc/services file. */ +/* **************************************************************** */ + +#include + +/******** NDB INCLUDE ******/ +#include +/***************************/ +/*#include */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern "C" { +#include "utv.h" +#include "vcdrfunc.h" +#include "bcd.h" +} + +#ifndef TESTLEV +#define TESTLEV +#endif +//#define DEBUG +//#define MYDEBUG +//#define SETDBG + +//#define ops_before_exe 64 +#define MAXOPSEXEC 1024 + +/* Used in nanosleep */ +/**** NDB ********/ +static int bTestPassed; +void create_table(Ndb* pMyNdb); +void error_handler(const char* errorText); +/*****************/ +static struct timespec tmspec1; +static int server(long int); + +/* Function for initiating the cdr-area and make it clean for ongoing calls */ + +static int s; /* connected socket descriptor */ +static int ls; /* listen socket descriptor */ + +static struct hostent *hp; /* pointer to host info for remote host */ +static struct servent *sp; /* pointer to service information */ + +struct linger linger; /* allow a lingering, graceful close; */ + /* used when setting SO_LINGER */ + +static struct sockaddr_in myaddr_in; /* for local socket address */ +static struct sockaddr_in peeraddr_in; /* for peer socket address */ + +static FILE *fi; /* Log output */ +static char temp[600]=""; + +static int ops_before_exe = 1; /* Number of operations per execute, default is 1, + but it can be changed with the -o parameter. */ + +/*---------------------------------------------------------------------- + + M A I N + * This routine starts the server. It forks, leaving the child + to do all the work, so it does not have to be run in the + background. It sets up the listen socket, and for each incoming + connection, it forks a child process to process the data. It + will loop forever, until killed by a signal. + + ----------------------------------------------------------------------*/ + +/****** NDB *******/ +static char *tableName = "VWTABLE"; +/******************/ + +#include +using namespace std; + +int main(int argc, const char** argv) +{ + /******** NDB ***********/ + /* + Ndb MyNdb( "TEST_DB" ); + int tTableId; + */ + /************************/ + char tmpbuf[400]; + /* Loop and status variables */ + int i,j,found; + + /* Used by the server */ + int addrlen; + + /* return code used with functions */ + int rc; + + i = 1; + while (argc > 1) + { + if (strcmp(argv[i], "-o") == 0) + { + ops_before_exe = atoi(argv[i+1]); + if ((ops_before_exe < 1) || (ops_before_exe > MAXOPSEXEC)) + { + cout << "Number of operations per execute must be at least 1, and at most " << MAXOPSEXEC << endl; + exit(1); + } + + } + else + { + cout << "Invalid parameter!" << endl << "Look in cdrserver.C for more info." << endl; + exit(1); + } + + argc -= 2; + i = i + 2; + } + + + /* Setup log handling */ + logname(temp,"Cdrserver","Mother",""); + puts(temp); + fi=fopen(temp,"w"); + if (fi == NULL) + { + perror(argv[0]); + exit(EXIT_FAILURE); + } + m2log(fi,"Initiation of program"); + + /***** NDB ******/ + /* + MyNdb.init(); + if (MyNdb.waitUntilReady(30) != 0) + { + puts("Not ready"); + exit(-1); + } + tTableId = MyNdb.getTable()->openTable(tableName); + if (tTableId == -1) + { + printf("%d: Creating table",getpid()); + create_table(&MyNdb); + } + else printf("%d: Table already create",getpid()); + */ + + /****************/ + + /* clear out address structures */ + memset ((char *)&myaddr_in, 0, sizeof(struct sockaddr_in)); + memset ((char *)&peeraddr_in, 0, sizeof(struct sockaddr_in)); + + m2log(fi,"Socket setup starting"); + + /* Set up address structure for the listen socket. */ + myaddr_in.sin_family = AF_INET; + + /* The server should listen on the wildcard address, */ + /* rather than its own internet address. This is */ + /* generally good practice for servers, because on */ + /* systems which are connected to more than one */ + /* network at once will be able to have one server */ + /* listening on all networks at once. Even when the */ + /* host is connected to only one network, this is good */ + /* practice, because it makes the server program more */ + /* portable. */ + + myaddr_in.sin_addr.s_addr = INADDR_ANY; + /* Find the information for the "cdrserver" server */ + /* in order to get the needed port number. */ + + sp = getservbyname ("cdrserver", "tcp"); + if (sp == NULL) { + m2log(fi,"Service cdrserver not found in /etc/services"); + m2log(fi,"Terminating."); + exit(EXIT_FAILURE); + } + + myaddr_in.sin_port = sp->s_port; + + /* Create the listen socket.i */ + + ls = socket (AF_INET, SOCK_STREAM, 0); + if (ls == -1) { + m2log(fi,"Unable to create socket"); + m2log(fi,"Terminating."); + exit(EXIT_FAILURE); + } + printf("Socket created\n"); + printf("Wait..........\n"); + /* Bind the listen address to the socket. */ + if (bind(ls,(struct sockaddr*)&myaddr_in, sizeof(struct sockaddr_in)) == -1) { + m2log(fi,"Unable to bind address"); + m2log(fi,"Terminating."); + exit(EXIT_FAILURE); + } + + /* Initiate the listen on the socket so remote users */ + /* can connect. The listen backlog is set to 5, which */ + /* is the largest currently supported. */ + + if (listen(ls, 5) == -1) { + m2log(fi,"Unable to listen on socket"); + m2log(fi,"Terminating."); + exit(EXIT_FAILURE); + } + + /* Now, all the initialization of the server is */ + /* complete, and any user errors will have already */ + /* been detected. Now we can fork the daemon and */ + /* return to the user. We need to do a setpgrp */ + /* so that the daemon will no longer be associated */ + /* with the user's control terminal. This is done */ + /* before the fork, so that the child will not be */ + /* a process group leader. Otherwise, if the child */ + /* were to open a terminal, it would become associated */ + /* with that terminal as its control terminal. It is */ + /* always best for the parent to do the setpgrp. */ + + m2log(fi,"Socket setup completed"); + m2log(fi,"Start server"); + + setpgrp(); + + /* Initiate the tmspec struct for use with nanosleep() */ + tmspec1.tv_sec = 0; + tmspec1.tv_nsec = 1; + + printf("Waiting for client to connect.........\n"); + printf("Done\n"); + switch (fork()) { + case -1: /* Unable to fork, for some reason. */ + m2log(fi,"Failed to start server"); + m2log(fi,"Terminating."); + fclose(fi); + perror(argv[0]); + fprintf(stderr, "%s: unable to fork daemon\n", argv[0]); + exit(EXIT_FAILURE); + + break; + case 0: /* The child process (daemon) comes here. */ + m2log(fi,"Server started"); + + /* Close stdin and stderr so that they will not */ + /* be kept open. Stdout is assumed to have been */ + /* redirected to some logging file, or /dev/null. */ + /* From now on, the daemon will not report any */ + /* error messages. This daemon will loop forever, */ + /* waiting for connections and forking a child */ + /* server to handle each one. */ + + close((int)stdin); + close((int)stderr); + /* Set SIGCLD to SIG_IGN, in order to prevent */ + /* the accumulation of zombies as each child */ + /* terminates. This means the daemon does not */ + /* have to make wait calls to clean them up. */ + + signal(SIGCLD, SIG_IGN); + for(EVER) { + if ((checkchangelog(fi,temp))==0) + m2log(fi,"Waiting for connection"); + /* Note that addrlen is passed as a pointer */ + /* so that the accept call can return the */ + /* size of the returned address. */ + + addrlen = sizeof(struct sockaddr_in); + + /* This call will block until a new */ + /* connection arrives. Then, it will */ + /* return the address of the connecting */ + /* peer, and a new socket descriptor, s, */ + /* for that connection. */ + + s = accept(ls,(struct sockaddr*) &peeraddr_in, &addrlen); + #ifdef MYDEBUG + puts("accepted"); + #endif + if ((checkchangelog(fi,temp))==0) + m2log(fi,"Connection attempt from a client"); + if ((checkchangelog(fi,temp))==0) + m2log(fi,"Start communication server"); + + if ( s == -1) exit(EXIT_FAILURE); + switch (fork()) { + case -1: /* Can't fork, just exit. */ + if ((checkchangelog(fi,temp))==0) + m2log(fi,"Start communication server failed."); + exit(EXIT_FAILURE); + break; + case 0: /* Child process comes here. */ + + /* Get clients adress and save it in the info area */ + /* Keep track of how many times the client connects to the server */ + printf("Connect attempt from client %u\n",peeraddr_in.sin_addr.s_addr); + server(peeraddr_in.sin_addr.s_addr); + exit(EXIT_FAILURE); + break; + default: /* Daemon process comes here. */ + /* The daemon needs to remember */ + /* to close the new accept socket */ + /* after forking the child. This */ + /* prevents the daemon from running */ + /* out of file descriptor space. It */ + /* also means that when the server */ + /* closes the socket, that it will */ + /* allow the socket to be destroyed */ + /* since it will be the last close. */ + close(s); + break; + } + } + default: /* Parent process comes here. */ + exit(EXIT_FAILURE); + } + return EXIT_SUCCESS; +} + +/*---------------------------------------------------------------------- + + S E R V E R + * This is the actual server routine that the daemon forks to + handle each individual connection. Its purpose is to receive + the request packets from the remote client, process them, + and return the results to the client. It will also write some + logging information to stdout. + + ----------------------------------------------------------------------*/ + +server(long int servernum) +{ + /******** NDB ***********/ + Ndb MyNdb( "TEST_DB" ); + int tTableId; + NdbConnection *MyTransaction; + NdbOperation *MyOperation; + int check; + int c1 = 0; + int c2 = 0; + int c3 = 0; + int c4 = 0; + int act_index = 0; + /************************/ + register unsigned int reqcnt; /* keeps count of number of requests */ + register unsigned int i; /* Loop counters */ + register int x; + register short done; /* Loop variable */ + short int found; + + /* The server index number */ + int thisServer; + + /* Variables used to keep track of some statistics */ + time_t ourtime; + time_t tmptime; + int tmpvalue; + long int tmptransfer; + long int transfer; + int ops = 0; + + /* Variables used by the server */ + char buf[400]; /* This example uses 10 byte messages. */ + char *inet_ntoa(); + char *hostname; /* points to the remote host's name string */ + int len; + int rcvbuf_size; + + long ctid; + + unsigned char uc; + + /* Variables used by the logging facilitiy */ + char msg[600]; + char crap[600]; + char lognamn[600]; + + FILE *log; + + /* scheduling parameter for pthread */ + struct sched_param param1,param2,param3; + + /* Header information */ + /* cdrtype not used */ + /*short cdrtype; */ /* 1 CDR Typ */ + short cdrlen; /* 2 CDR recored length in bytes excluding CDR type */ + short cdrsubtype; /* 1 CDR subtype */ + unsigned int cdrid; /* 8 CDR unique number of each call */ + unsigned int cdrtime; /* 4 CDR Time in seconds */ + short cdrmillisec; /* 2 CDR Milliseconds */ + short cdrstatus; /* 1 CDR For future use */ + short cdrequipeid; /* 1 CDR Equipment id */ + int cdrreserved1; /* 4 CDR For future use */ + + /* Defined or calculated for each record */ + int cdrrestlen; /* Unprocessed data left in record in bytes */ + + /* Gemensamma datatyper */ + unsigned short parmtype_prev; /* 1 Parameter type */ + unsigned short parmtype; /* 1 Parameter type */ + unsigned short parmlen; /* 1 Parameter type */ + + int rc; /* return code for functions */ + + /* Attribute object used with threads */ + pthread_attr_t attr1; + pthread_attr_t attr2; + pthread_attr_t attr3; + struct cdr_record *tmpcdrptr,*ftest; + void *dat; + + int error_from_client = 0; + + /* Konstanter */ + const int headerlen = 24; /* Length of header record */ + + parmtype_prev = 99; + reqcnt = 0; + + /* Close the listen socket inherited from the daemon. */ + close(ls); + + printf("Use the readinfo program to get information about server status\n\n"); + + if((checkchangelog(fi,temp))==0) + c2log(fi,"Communication server started"); + + /* Look up the host information for the remote host */ + /* that we have connected with. Its internet address */ + /* was returned by the accept call, in the main */ + /* daemon loop above. */ + + hp=gethostbyaddr((char *) &peeraddr_in.sin_addr,sizeof(struct in_addr),peeraddr_in.sin_family); + + if (hp == NULL) { + /* The information is unavailable for the remote */ + /* host. Just format its internet address to be */ + /* printed out in the logging information. The */ + /* address will be shown in "internet dot format". */ + + /* + hostname = inet_ntoa(peeraddr_in.sin_addr); + */ + sprintf(hostname,"Test"); + logname(lognamn,"Cdrserver","Child",hostname); + } + else { + hostname = hp->h_name; /* point to host's name */ + logname(lognamn,"Cdrserver","Child",hostname); + } + + log=fopen(lognamn,"w"); + if (log == NULL) + { + perror(hostname); + exit(EXIT_FAILURE); + } + n2log(log,"Setup in progress"); + /* Log a startup message. */ + + /* The port number must be converted first to host byte */ + /* order before printing. On most hosts, this is not */ + /* necessary, but the ntohs() call is included here so */ + /* that this program could easily be ported to a host */ + /* that does require it. */ + + snprintf(msg,sizeof(msg),"Startup from %s port %u",hostname,ntohs(peeraddr_in.sin_port)); + if ((checkchangelog(fi,temp))==0) + c2log(fi,msg); + n2log(log,msg); + snprintf(msg,sizeof(msg),"For further information, see log(%s)",lognamn); + if ((checkchangelog(fi,temp))==0) + c2log(fi,msg); + + /* Set the socket for a lingering, graceful close. */ + /* This will cause a final close of this socket to wait until */ + /* all * data sent on it has been received by the remote host. */ + + linger.l_onoff =1; + linger.l_linger =0; + if (setsockopt(s, SOL_SOCKET, SO_LINGER,(const char*)&linger,sizeof(linger)) == -1) { + snprintf(msg,sizeof(msg),"Setting SO_LINGER, l_onoff=%d, l_linger=%d",linger.l_onoff,linger.l_linger); + if ((checkchangelog(log,lognamn))==0) + n2log(log,msg); + goto errout; + } + + /* Set the socket for a lingering, graceful close. */ + /* This will cause a final close of this socket to wait until all * data sent */ + /* on it has been received by the remote host. */ + + rcvbuf_size=64*1024; + + if (setsockopt(s, SOL_SOCKET, SO_RCVBUF,(const char*) &rcvbuf_size,sizeof(rcvbuf_size)) == -1) { + snprintf(msg,sizeof(msg),"Setting SO_RCVBUF = %d",rcvbuf_size); + if ((checkchangelog(log,lognamn))==0) + n2log(log,msg); + goto errout; + } + + /* Set nodelay on socket */ + n2log(log,"Port setup complete"); + + /* Go into a loop, receiving requests from the remote */ + /* client. After the client has sent the last request, */ + /* it will do a shutdown for sending, which will cause */ + /* an end-of-file condition to appear on this end of the */ + /* connection. After all of the client's requests have */ + /* been received, the next recv call will return zero */ + /* bytes, signalling an end-of-file condition. This is */ + /* how the server will know that no more requests will */ + /* follow, and the loop will be exited. */ + + n2log(log,"Setup completed"); + + /* Fetch the process id for the server */ + + /* Inititate the variables used for counting transfer rates and rec/sec */ + tmpvalue = 0; + tmptime = 0; + tmptransfer = 0; + transfer = 0; + + printf("Client %s connected\nStarting to process the data\n\n",hostname); + + tmpcdrptr = (struct cdr_record*)malloc(sizeof(struct cdr_record)); + + /***** NDB ******/ + MyNdb.init(); + if (MyNdb.waitUntilReady(30) != 0) + { + puts("Not ready"); + exit(-1); + } + tTableId = MyNdb.getTable()->openTable(tableName); + if (tTableId == -1) + { + printf("%d: Creating table",getpid()); + create_table(&MyNdb); + } + else printf("%d: Table already created",getpid()); + + /****************/ + + while (len = recv(s,buf,headerlen,MSG_WAITALL)) { + if (len == -1) { + snprintf(msg,sizeof(msg),"Error from recv"); + if ((checkchangelog(log,lognamn))==0) + n2log(log,msg); + goto errout; /* error from recv */ + } + + /* The reason this while loop exists is that there */ + /* is a remote possibility of the above recv returning */ + /* less than 10 bytes. This is because a recv returns */ + /* as soon as there is some data, and will not wait for */ + /* all of the requested data to arrive. Since 10 bytes */ + /* is relatively small compared to the allowed TCP */ + /* packet sizes, a partial receive is unlikely. If */ + /* this example had used 2048 bytes requests instead, */ + /* a partial receive would be far more likely. */ + /* This loop will keep receiving until all 10 bytes */ + /* have been received, thus guaranteeing that the */ + /* next recv at the top of the loop will start at */ + /* the begining of the next request. */ + + for (;len < headerlen;) { + x = recv(s,buf,(headerlen-len),0); + if (x == -1) { + snprintf(msg,sizeof(msg),"Error from recv"); + if ((checkchangelog(log,lognamn))==0) + n2log(log,msg); + goto errout; /* error from recv */ + } + len=len+x; + } + + if (ops == 0) { + MyTransaction = MyNdb.startTransaction(); + if (MyTransaction == NULL) + error_handler(MyNdb.getNdbErrorString()); + }//if + + MyOperation = MyTransaction->getNdbOperation(tableName); + if (MyOperation == NULL) + error_handler(MyTransaction->getNdbErrorString()); + /*------------------------------------------------------*/ + /* Parse header of CDR records */ + /*------------------------------------------------------*/ + + /*------------------------------------------------------*/ + /* 1. Type of cdr */ + /*------------------------------------------------------*/ + /* Not used for the moment + cdrtype=(char)buf[0]; + */ + /*------------------------------------------------------*/ + /* 2. Total length of CDR */ + /*------------------------------------------------------*/ + swab(buf+1,buf+1,2); + memcpy(&cdrlen,buf+1,2); + /*------------------------------------------------------*/ + /* 3. Partial type of CDR */ + /*------------------------------------------------------*/ + cdrsubtype=(char)buf[3]; + switch (cdrsubtype) + { + case 0: + c1++; + tmpcdrptr->CallAttemptState = 1; + check = MyOperation->insertTuple(); + break; + case 1: + c2++; + tmpcdrptr->CallAttemptState = 2; + check = MyOperation->updateTuple(); + break; + case 2: + c3++; + tmpcdrptr->CallAttemptState = 3; + check = MyOperation->deleteTuple(); + break; + case 3: + c4++; + tmpcdrptr->CallAttemptState = 4; + check = MyOperation->deleteTuple(); + break; + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + } + /*cdrsubtype=(cdrsubtype << 24) >> 24;*/ + /*------------------------------------------------------*/ + /* 4. ID number */ + /*------------------------------------------------------*/ + /*swab(buf+4,buf+4,4);*/ /* ABCD -> BADC */ + /* + swab(buf+4,buf+4,4); + swab(buf+5,buf+5,2); + swab(buf+6,buf+6,2); + swab(buf+4,buf+4,2); + swab(buf+5,buf+5,2); + */ + memcpy(&cdrid,buf+4,4); + tmpcdrptr->CallIdentificationNumber = cdrid; + #ifdef SETDBG + puts("CIN"); + #endif + check = MyOperation->equal("CIN",(char*)&cdrid); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + #ifdef SETDBG + puts("CAS"); + #endif + + if (cdrsubtype < 2) + { + check = MyOperation->setValue("CAS",(char*)&cdrsubtype); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + } + /*------------------------------------------------------*/ + /* 5. Time stamp */ + /*------------------------------------------------------*/ + swab(buf+12,buf+12,4); + swab(buf+13,buf+13,2); + swab(buf+14,buf+14,2); + swab(buf+12,buf+12,2); + swab(buf+13,buf+13,2); + memcpy(&cdrtime,buf+12,4); + switch (cdrsubtype) + { + case 0: + #ifdef SETDBG + puts("START_TIME"); + #endif + check = MyOperation->setValue("START_TIME",(char*)&cdrtime); + break; + case 1: + #ifdef SETDBG + puts("Start1"); + #endif + check = MyOperation->setValue("StartOfCharge",(char*)&cdrtime); + break; + case 2: + #ifdef SETDBG + puts("Start2"); + #endif + /* + check = MyOperation->setValue("StopOfCharge",(char*)&cdrtime); + */ + check = 0; + break; + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + } + /*------------------------------------------------------*/ + /* 6. Milliseconds */ + /*------------------------------------------------------*/ + /* Not used by application + swab(buf+16,buf+16,2); + memcpy(&cdrmillisec,buf+16,2); + */ + /*------------------------------------------------------*/ + /* 7. CDR status reserverd for future use */ + /*------------------------------------------------------*/ + /* Not used by application + memcpy(&cdrstatus,buf+18,1); + */ + /*------------------------------------------------------*/ + /* 8. CDR equipe id, number of sending equipement */ + /*------------------------------------------------------*/ + /* Not used by application + memcpy(&cdrequipeid,buf+19,1); + */ + /*cdrequipeid=(cdrequipeid << 24) >> 24;*/ + /*------------------------------------------------------*/ + /* 9. CDR reserverd for furter use */ + /*------------------------------------------------------*/ + /* Not used by applikation + swab(buf+20,buf+20,4); + swab(buf+21,buf+21,2); + swab(buf+22,buf+22,2); + swab(buf+20,buf+20,2); + swab(buf+21,buf+21,2); + memcpy(&cdrreserved1,buf+20,4); + */ + /*------------------------------------------------------*/ + /* calculate length of datapart in record */ + /* Formula recordlength-headerlen-1 */ + /*------------------------------------------------------*/ + cdrrestlen=cdrlen-(headerlen-1); + /*------------------------------------------------------*/ + /* Finished with header */ + /*------------------------------------------------------*/ + /* Read remaining cdr data into buffer for furter */ + /* handling. */ + /*------------------------------------------------------*/ + len = recv(s,buf,cdrrestlen,MSG_WAITALL); + if (len == -1) { + snprintf(msg,sizeof(msg),"Error from recv"); + if ((checkchangelog(log,lognamn))==0) + n2log(log,msg); + goto errout; /* error from recv */ + } + for (;len 1) + { + #ifdef SETDBG + puts("Going to execute"); + #endif + ops++; + if (ops == ops_before_exe) { + ops = 0; + check = MyTransaction->execute(Commit, CommitAsMuchAsPossible); + if ((check == -1) && (MyTransaction->getNdbError() != 0)) + error_handler(MyTransaction->getNdbErrorString()); + MyNdb.closeTransaction(MyTransaction); + #ifdef SETDBG + puts("Transaction closed"); + #endif + }//if + reqcnt++; + continue; + } + for (x=0;x<=cdrrestlen && !done && cdrrestlen > 1;) { + uc=buf[x]; + parmtype=uc; + /*parmtype=(parmtype << 24) >> 24;*/ /* Modified in sun worked in hp */ + + parmlen = buf[x+1]; + /*parmlen =(parmlen << 24) >> 24;*/ + x+=2; + + switch (parmtype) { + case 4: /* Called party number */ + bcd_decode2(parmlen,&buf[x],crap); + tmpcdrptr->BSubscriberNumberLength = (char)parmlen; + strcpy(tmpcdrptr->BSubscriberNumber,crap); + tmpcdrptr->BSubscriberNumber[parmlen] = '\0'; + x=x+(parmlen/2); + if (parmlen % 2) x++; + tmpcdrptr->USED_FIELDS |= B_BSubscriberNumber; + #ifdef SETDBG + puts("BNumber"); + #endif + check = MyOperation->setValue("BNumber",(char*)&tmpcdrptr->BSubscriberNumber); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + break; + case 9: /* Calling Partys cataegory */ + if (parmlen != 1) printf("ERROR: Calling partys category has wrong length %d\n",parmlen); + else tmpcdrptr->ACategory=(char)buf[x]; + x+=parmlen; + tmpcdrptr->USED_FIELDS |= B_ACategory; + #ifdef SETDBG + puts("ACategory"); + #endif + check = MyOperation->setValue("ACategory",(char*)&tmpcdrptr->ACategory); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + break; + case 10: /* Calling Party Number */ + bcd_decode2(parmlen,&buf[x],crap); + tmpcdrptr->ASubscriberNumberLength = (char)parmlen; + strcpy(tmpcdrptr->ASubscriberNumber,crap); + tmpcdrptr->ASubscriberNumber[parmlen] = '\0'; + x=x+(parmlen/2); + if (parmlen % 2) x++; + tmpcdrptr->USED_FIELDS |= B_ASubscriberNumber; + #ifdef SETDBG + puts("ANumber"); + #endif + check = MyOperation->setValue("ANumber",(char*)&tmpcdrptr->ASubscriberNumber); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + break; + case 11: /* Redirecting number */ + bcd_decode2(parmlen,&buf[x],crap); + strcpy(tmpcdrptr->RedirectingNumber,crap); + x=x+(parmlen/2); + if (parmlen % 2) x++; + tmpcdrptr->USED_FIELDS |= B_RedirectingNumber; + #ifdef SETDBG + puts("RNumber"); + #endif + check = MyOperation->setValue("RNumber",(char*)&tmpcdrptr->RedirectingNumber); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + break; + case 17: /* Called partys category */ + if (parmlen != 1) printf("ERROR: Called partys category has wrong length %d\n",parmlen); + else tmpcdrptr->EndOfSelectionInformation=(char)buf[x]; + x+=parmlen; + tmpcdrptr->USED_FIELDS |= B_EndOfSelectionInformation; + #ifdef SETDBG + puts("EndOfSelInf"); + #endif + check = MyOperation->setValue("EndOfSelInf",(char*)&tmpcdrptr->EndOfSelectionInformation); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + break; + case 18: /* Release reason */ + if (parmlen != 1) printf("ERROR: Release reason has wrong length %d\n",parmlen); + else tmpcdrptr->CauseCode=(char)buf[x]; + x+=parmlen; + tmpcdrptr->USED_FIELDS |= B_CauseCode; + #ifdef SETDBG + puts("CauseCode"); + #endif + check = MyOperation->setValue("CauseCode",(char*)&tmpcdrptr->CauseCode); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + break; + case 19: /* Redirection information */ + switch (parmlen) { + case 1: + tmpcdrptr->ReroutingIndicator= (char)buf[x]; + tmpcdrptr->USED_FIELDS |= B_ReroutingIndicator; + break; + case 2: + swab(buf+x,buf+x,2); + tmpcdrptr->ReroutingIndicator= buf[x]; + tmpcdrptr->USED_FIELDS |= B_ReroutingIndicator; + break; + default : + snprintf(msg,sizeof(msg),"ERROR: Redirection information has wrong length %d\n",parmlen); + if ((checkchangelog(log,lognamn))==0) + n2log(log,msg); + break; + #ifdef SETDBG + puts("RI"); + #endif + check = MyOperation->setValue("RI",(char*)&tmpcdrptr->ReroutingIndicator); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + } + x+=parmlen; + break; + case 32: /* User to user information */ + if (parmlen != 1) printf("ERROR: User to User information has wrong length %d\n",parmlen); + else tmpcdrptr->UserToUserInformation=(char)buf[x]; + x+=parmlen; + tmpcdrptr->USED_FIELDS |= B_UserToUserInformation; + #ifdef SETDBG + puts("UserToUserInf"); + #endif + check = MyOperation->setValue("UserToUserInf",(char*)&tmpcdrptr->UserToUserInformation); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + break; + case 40: /* Original called number */ + bcd_decode2(parmlen,&buf[x],crap); + strcpy(tmpcdrptr->OriginalCalledNumber,crap); + x=x+(parmlen/2); + if (parmlen % 2) x++; + tmpcdrptr->USED_FIELDS |= B_OriginalCalledNumber; + #ifdef SETDBG + puts("ONumber"); + #endif + check = MyOperation->setValue("ONumber",(char*)&tmpcdrptr->OriginalCalledNumber); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + break; + case 42: /* User to user indicator */ + if (parmlen != 1) printf("ERROR: User to User indicator has wrong length %d\n",parmlen); + else tmpcdrptr->UserToUserIndicatior=(char)buf[x]; + x+=parmlen; + tmpcdrptr->USED_FIELDS |= B_UserToUserIndicatior; + #ifdef SETDBG + puts("UserToUserInd"); + #endif + check = MyOperation->setValue("UserToUserInd",(char*)&tmpcdrptr->UserToUserIndicatior); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + break; + case 63: /* Location number */ + bcd_decode2(parmlen,&buf[x],crap); + strcpy(tmpcdrptr->LocationCode,crap); + x=x+(parmlen/2); + if (parmlen % 2) x++; + tmpcdrptr->USED_FIELDS |= B_LocationCode; + #ifdef SETDBG + puts("LocationCode"); + #endif + check = MyOperation->setValue("LocationCode",(char*)&tmpcdrptr->LocationCode); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + break; + case 240: /* Calling Partys cataegory */ + if (parmlen != 1) printf("ERROR: Calling partys category has wrong length %d\n",parmlen); + else tmpcdrptr->NetworkIndicator=(char)buf[x]; + x+=parmlen; + tmpcdrptr->USED_FIELDS |= B_NetworkIndicator; + #ifdef SETDBG + puts("NIndicator"); + #endif + check = MyOperation->setValue("NIndicator",(char*)&tmpcdrptr->NetworkIndicator); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + break; + case 241: /* Calling Partys cataegory */ + if (parmlen != 1) printf("ERROR: Calling partys category has wrong length %d\n",parmlen); + else tmpcdrptr->TonASubscriberNumber=(char)buf[x]; + x+=parmlen; + tmpcdrptr->USED_FIELDS |= B_TonASubscriberNumber; + #ifdef SETDBG + puts("TonANumber"); + #endif + check = MyOperation->setValue("TonANumber",(char*)&tmpcdrptr->TonASubscriberNumber); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + break; + case 242: /* Calling Partys cataegory */ + if (parmlen != 1) printf("ERROR: Calling partys category has wrong length %d\n",parmlen); + else tmpcdrptr->TonBSubscriberNumber=(char)buf[x]; + x+=parmlen; + tmpcdrptr->USED_FIELDS |= B_TonBSubscriberNumber; + #ifdef SETDBG + puts("TonBNumber"); + #endif + check = MyOperation->setValue("TonBNumber",(char*)&tmpcdrptr->TonBSubscriberNumber); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + break; + case 243: /* Calling Partys cataegory */ + if (parmlen != 1) printf("ERROR: Calling partys category has wrong length %d\n",parmlen); + else tmpcdrptr->TonRedirectingNumber=(char)buf[x]; + x+=parmlen; + tmpcdrptr->USED_FIELDS |= B_TonRedirectingNumber; + #ifdef SETDBG + puts("TonRNumber"); + #endif + check = MyOperation->setValue("TonRNumber",(char*)&tmpcdrptr->TonRedirectingNumber); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + break; + case 244: /* Calling Partys cataegory */ + if (parmlen != 1) printf("ERROR: Calling partys category has wrong length %d\n",parmlen); + else tmpcdrptr->TonOriginalCalledNumber=(char)buf[x]; + x+=parmlen; + tmpcdrptr->USED_FIELDS |= B_TonOriginalCalledNumber; + #ifdef SETDBG + puts("TonONumber"); + #endif + check = MyOperation->setValue("TonONumber",(char*)&tmpcdrptr->TonOriginalCalledNumber); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + break; + case 245: /* Calling Partys cataegory */ + if (parmlen != 1) printf("ERROR: Calling partys category has wrong length %d\n",parmlen); + else tmpcdrptr->TonLocationCode=(char)buf[x]; + x+=parmlen; + tmpcdrptr->USED_FIELDS |= B_TonLocationCode; + #ifdef SETDBG + puts("TonLocationCode"); + #endif + check = MyOperation->setValue("TonLocationCode",(char*)&tmpcdrptr->TonLocationCode); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + break; + case 252: /* RINParameter Parameter */ + switch (parmlen) { + case 1: + tmpcdrptr->RINParameter=buf[x]; + tmpcdrptr->USED_FIELDS |= B_RINParameter; + break; + case 2: + swab(buf+x,buf+x,2); + tmpcdrptr->RINParameter = buf[x] << 8; + tmpcdrptr->USED_FIELDS |= B_RINParameter; + break; + default : + snprintf(msg,sizeof(msg),"ERROR: Rin parameter has wrong length %d\n",parmlen); + if ((checkchangelog(log,lognamn))==0) + n2log(log,msg); + break; + } + x+=parmlen; + #ifdef SETDBG + puts("RINParameter"); + #endif + check = MyOperation->setValue("RINParameter",(char*)&tmpcdrptr->RINParameter); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + break; + case 253: /* OriginatingPointCode */ + switch (parmlen) { + case 2: + swab(buf+x,buf+x,2); + memcpy(&tmpcdrptr->OriginatingPointCode,(buf+x),2); + tmpcdrptr->USED_FIELDS |= B_OriginatingPointCode; + break; + case 3: + swab(buf+x,buf+x,2); + swab(buf+(x+1),buf+(x+1),2); + swab(buf+x,buf+x,2); + memcpy(&tmpcdrptr->OriginatingPointCode,(buf+x),3); + tmpcdrptr->USED_FIELDS |= B_OriginatingPointCode; + break; + default : + snprintf(msg,sizeof(msg),"ERROR: OriginatingPointCode parameter has wrong length %d\n",parmlen); + if ((checkchangelog(log,lognamn))==0) + n2log(log,msg); + break; + } + x+=parmlen; + #ifdef SETDBG + puts("OPC"); + #endif + check = MyOperation->setValue("OPC",(char*)&tmpcdrptr->OriginatingPointCode); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + break; + case 254: /* DestinationPointCode */ + switch (parmlen) { + case 2: + swab(buf+x,buf+x,2); + memcpy(&tmpcdrptr->DestinationPointCode,(buf+x),2); + /* + tmpcdrptr->DestinationPointCode = buf[x] << 8; + */ + tmpcdrptr->USED_FIELDS |= B_DestinationPointCode; + break; + case 3: + swab(buf+x,buf+x,2); + swab(buf+(x+1),buf+(x+1),2); + swab(buf+x,buf+x,2); + memcpy(&tmpcdrptr->DestinationPointCode,(buf+x),3); + tmpcdrptr->USED_FIELDS |= B_DestinationPointCode; + break; + default : + snprintf(msg,sizeof(msg),"ERROR: DestinationPointCode parameter has wrong length %d\n",parmlen); + if ((checkchangelog(log,lognamn))==0) + n2log(log,msg); + break; + } + x+=parmlen; + #ifdef SETDBG + puts("DPC"); + #endif + check = MyOperation->setValue("DPC",(char*)&tmpcdrptr->DestinationPointCode); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + break; + case 255: /* CircuitIdentificationCode */ + swab(buf+x,buf+x,2); + memcpy(&tmpcdrptr->CircuitIdentificationCode,(buf+x),2); + tmpcdrptr->USED_FIELDS |= B_CircuitIdentificationCode; + x+=parmlen; + #ifdef SETDBG + puts("CIC"); + #endif + check = MyOperation->setValue("CIC",(char*)&tmpcdrptr->CircuitIdentificationCode); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + break; + default: + printf("ERROR: Undefined parmtype %d , previous %d, length %d\n",parmtype,parmtype_prev,parmlen); + snprintf(msg,sizeof(msg),"ERROR: Undefined parmtype %d , previous %d, length %d\n",parmtype,parmtype_prev,parmlen); + if ((checkchangelog(log,lognamn))==0) + n2log(log,msg); + if (parmlen == 0) { + x++; + } + x+=parmlen; + break; + } + parmtype_prev=parmtype; + if ((cdrrestlen-x) == 1) { + done=TRUE; + } + } + time(&ourtime); + if (ourtime != tmptime) + { + transfer = tmptransfer; + tmptransfer = 0; + if (++act_index == 30) + { + act_index = 0; + printf("Transfer=%d\n",transfer); + printf("Total operations=%d\n",reqcnt); + printf("CAS1=%d\n",c1/30); + printf("CAS2=%d\n",c2/30); + printf("CAS3=%d\n",c3/30); + c1=0; + c2=0; + c3=0; + } + tmptime = ourtime; + } + switch (cdrsubtype) { + case 0: + tmpcdrptr->ClientId = servernum; + #ifdef SETDBG + puts("ClientId"); + #endif + check = MyOperation->setValue("ClientId",(char*)&tmpcdrptr->ClientId); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + tmpcdrptr->OurSTART_TIME = ourtime; + #ifdef SETDBG + puts("OurSTART_TIME"); + #endif + check = MyOperation->setValue("OurSTART_TIME",(char*)&tmpcdrptr->OurSTART_TIME); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + tmpcdrptr->USED_FIELDS |= B_START_TIME; + #ifdef SETDBG + puts("USED_FIELDS"); + #endif + check = MyOperation->setValue("USED_FIELDS",(char*)&tmpcdrptr->USED_FIELDS); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + break; + + case 1: + tmpcdrptr->OurTimeForStartOfCharge = ourtime; + #ifdef SETDBG + puts("OurStartOfCharge"); + #endif + check = MyOperation->setValue("OurStartOfCharge",(char*)&tmpcdrptr->OurTimeForStartOfCharge); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + tmpcdrptr->USED_FIELDS |= B_TimeForStartOfCharge; + #ifdef SETDBG + puts("USED_FIELDS"); + #endif + check = MyOperation->setValue("USED_FIELDS",(char*)&tmpcdrptr->USED_FIELDS); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + break; + + case 2: + tmpcdrptr->OurTimeForStopOfCharge = ourtime; + #ifdef SETDBG + puts("OurStopOfCharge"); + #endif + check = MyOperation->setValue("OurStopOfCharge",(char*)&tmpcdrptr->OurTimeForStopOfCharge); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + tmpcdrptr->USED_FIELDS |= B_TimeForStopOfCharge; + #ifdef SETDBG + puts("USED_FIELDS"); + #endif + check = MyOperation->setValue("USED_FIELDS",(char*)&tmpcdrptr->USED_FIELDS); + if (check == -1) + error_handler(MyTransaction->getNdbErrorString()); + break; + + case 3: + tmpcdrptr->CallAttemptState = 4; + break; + default: + snprintf(msg,sizeof(msg),"cdrtype %d unknown",cdrsubtype); + if ((checkchangelog(log,lognamn))==0) + n2log(log,msg); + goto errout; + break; + } + ops++; + if (ops == ops_before_exe) { + ops = 0; + #ifdef SETDBG + puts("Going to execute"); + #endif + check = MyTransaction->execute(Commit, CommitAsMuchAsPossible); + if ((check == -1) && (MyTransaction->getNdbError() != 0)) + error_handler(MyTransaction->getNdbErrorString()); + MyNdb.closeTransaction(MyTransaction); + #ifdef SETDBG + puts("Transaction closed"); + #endif + + #ifdef SETDBG + puts("New transaction initiated"); + #endif + }//if + /* Increment the request count. */ + reqcnt++; + + /* Send a response back to the client. */ + + /* if (send(s, buf, 10, 0) != 10) goto errout; */ + } + + /* The loop has terminated, because there are no */ + /* more requests to be serviced. As mentioned above, */ + /* this close will block until all of the sent replies */ + /* have been received by the remote host. The reason */ + /* for lingering on the close is so that the server will */ + /* have a better idea of when the remote has picked up */ + /* all of the data. This will allow the start and finish */ + /* times printed in the log file to reflect more accurately */ + /* the length of time this connection was */ + /* The port number must be converted first to host byte */ + /* order before printing. On most hosts, this is not */ + /* necessary, but the ntohs() call is included here so */ + /* that this program could easily be ported to a host */ + /* that does require it. */ + + snprintf(msg,sizeof(msg),"Completed %s port %u, %d requests",hostname,ntohs(peeraddr_in.sin_port), reqcnt); + if ((checkchangelog(fi,temp))==0) + c2log(fi,msg); + error_from_client = 1; + snprintf(msg,sizeof(msg),"Communicate with threads"); + if ((checkchangelog(log,lognamn))==0) + n2log(log,msg); + snprintf(msg,sizeof(msg),"Waiting for threads to return from work"); + if ((checkchangelog(log,lognamn))==0) + n2log(log,msg); + snprintf(msg,sizeof(msg),"Closing down"); + if ((checkchangelog(log,lognamn))==0) + n2log(log,msg); + close(s); + fclose(log); + return EXIT_SUCCESS; + +errout: + snprintf(msg,sizeof(msg),"Connection with %s aborted on error\n", hostname); + if ((checkchangelog(log,lognamn))==0) + n2log(log,msg); + if ((checkchangelog(fi,temp))==0) + c2log(fi,msg); + error_from_client = 1; + snprintf(msg,sizeof(msg),"Communicate with threads"); + if ((checkchangelog(log,lognamn))==0) + n2log(log,msg); + snprintf(msg,sizeof(msg),"Waiting for threads to return from work"); + if ((checkchangelog(log,lognamn))==0) + n2log(log,msg); + snprintf(msg,sizeof(msg),"Closing down"); + if ((checkchangelog(log,lognamn))==0) + n2log(log,msg); + close(s); + fclose(log); + return EXIT_FAILURE; +} + +void +create_table(Ndb* pMyNdb) +{ + + /**************************************************************** + * Create table and attributes. + * + * create table basictab1( + * col1 int, + * col2 int not null, + * col3 int not null, + * col4 int not null + * ) + * + ***************************************************************/ + + int check; + int i; + NdbSchemaCon *MySchemaTransaction; + NdbSchemaOp *MySchemaOp; + int tAttributeSize; + + tAttributeSize = 1; + + cout << "Creating " << tableName << "..." << endl; + + MySchemaTransaction = pMyNdb->startSchemaTransaction(); + if( MySchemaTransaction == NULL ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); + if( MySchemaOp == NULL ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // Createtable + check = MySchemaOp->createTable( tableName, + 8, // Table Size + TupleKey, // Key Type + 40 // Nr of Pages + ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // CallIdentificationNumber Create first column, primary key + check = MySchemaOp->createAttribute( "CIN", + TupleKey, + 32, + tAttributeSize, + UnSigned, MMBased, + NotNullAttribute + ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + + // USED_FIELDS Create attributes + check = MySchemaOp->createAttribute( "USED_FIELDS", NoKey, 32, + tAttributeSize, UnSigned, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // ClientId Create attributes + check = MySchemaOp->createAttribute( "ClientId", NoKey, 32, + tAttributeSize, UnSigned, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // START_TIME Create attributes + check = MySchemaOp->createAttribute( "START_TIME", NoKey, 32, + tAttributeSize, UnSigned, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // OurSTART_TIME Create attributes + check = MySchemaOp->createAttribute( "OurSTART_TIME", NoKey, 32, + tAttributeSize, UnSigned, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // TimeForStartOfCharge Create attributes + check = MySchemaOp->createAttribute( "StartOfCharge", NoKey, 32, + tAttributeSize, UnSigned, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // TimeForStopOfCharge Create attributes + check = MySchemaOp->createAttribute( "StopOfCharge", NoKey, 32, + tAttributeSize, UnSigned, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // OurTimeForStartOfCharge Create attributes + check = MySchemaOp->createAttribute( "OurStartOfCharge", NoKey, 32, + tAttributeSize, UnSigned, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // OurTimeForStopOfCharge Create attributes + check = MySchemaOp->createAttribute( "OurStopOfCharge", NoKey, 32, + tAttributeSize, UnSigned, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // DestinationPointCode Create attributes + check = MySchemaOp->createAttribute( "DPC", NoKey, 16, + tAttributeSize, UnSigned, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // OriginatingPointCode Create attributes + check = MySchemaOp->createAttribute( "OPC", NoKey, 16, + tAttributeSize, UnSigned, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // CircuitIdentificationCode Create attributes + check = MySchemaOp->createAttribute( "CIC", NoKey, 16, + tAttributeSize, UnSigned, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // ReroutingIndicator Create attributes + check = MySchemaOp->createAttribute( "RI", NoKey, 16, + tAttributeSize, UnSigned, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // RINParameter Create attributes + check = MySchemaOp->createAttribute( "RINParameter", NoKey, 16, + tAttributeSize, UnSigned, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // NetworkIndicator Create attributes + check = MySchemaOp->createAttribute( "NIndicator", NoKey, 8, + tAttributeSize, Signed, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // CallAttemptState Create attributes + check = MySchemaOp->createAttribute( "CAS", NoKey, 8, + tAttributeSize, Signed, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // ACategory Create attributes + check = MySchemaOp->createAttribute( "ACategory", NoKey, 8, + tAttributeSize, Signed, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // EndOfSelectionInformation Create attributes + check = MySchemaOp->createAttribute( "EndOfSelInf", NoKey, 8, + tAttributeSize, Signed, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // UserToUserInformation Create attributes + check = MySchemaOp->createAttribute( "UserToUserInf", NoKey, 8, + tAttributeSize, Signed, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // UserToUserIndicator Create attributes + check = MySchemaOp->createAttribute( "UserToUserInd", NoKey, 8, + tAttributeSize, Signed, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // CauseCode Create attributes + check = MySchemaOp->createAttribute( "CauseCode", NoKey, 8, + tAttributeSize, Signed, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // ASubscriberNumber attributes + check = MySchemaOp->createAttribute( "ANumber", NoKey, 8, + ASubscriberNumber_SIZE, Signed, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // ASubscriberNumberLenght attributes + check = MySchemaOp->createAttribute( "ANumberLength", NoKey, 8, + tAttributeSize, Signed, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // TonASubscriberNumber attributes + check = MySchemaOp->createAttribute( "TonANumber", NoKey, 8, + tAttributeSize, Signed, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // BSubscriberNumber attributes + check = MySchemaOp->createAttribute( "BNumber", NoKey, 8, + BSubscriberNumber_SIZE, Signed, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // BSubscriberNumberLength attributes + check = MySchemaOp->createAttribute( "BNumberLength", NoKey, 8, + tAttributeSize, Signed, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // TonBSubscriberNumber attributes + check = MySchemaOp->createAttribute( "TonBNumber", NoKey, 8, + tAttributeSize, Signed, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // RedirectingNumber attributes + check = MySchemaOp->createAttribute( "RNumber", NoKey, 8, + ASubscriberNumber_SIZE, Signed, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // TonRedirectingNumber attributes + check = MySchemaOp->createAttribute( "TonRNumber", NoKey, 8, + tAttributeSize, Signed, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // OriginalCalledNumber attributes + check = MySchemaOp->createAttribute( "ONumber", NoKey, 8, + ASubscriberNumber_SIZE, Signed, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // TonOriginalCalledNumber attributes + check = MySchemaOp->createAttribute( "TonONumber", NoKey, 8, + tAttributeSize, Signed, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // LocationCode attributes + check = MySchemaOp->createAttribute( "LocationCode", NoKey, 8, + ASubscriberNumber_SIZE, Signed, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // TonLocationCode attributes + check = MySchemaOp->createAttribute( "TonLocationCode", NoKey, 8, + tAttributeSize, Signed, MMBased, + NullAttribute ); + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + if( MySchemaTransaction->execute() == -1 ) { + cout << tableName << " already exist" << endl; + cout << "Message: " << MySchemaTransaction->getNdbErrorString() << endl; + } + else + { + cout << tableName << " created" << endl; + } + pMyNdb->closeSchemaTransaction(MySchemaTransaction); + + return; +} + +void +error_handler(const char* errorText) +{ + // Test failed + cout << endl << "ErrorMessage: " << errorText << endl; + bTestPassed = -1; +} diff --git a/ndb/test/ndbapi/cello-sessionDb/celloDb.cpp b/ndb/test/ndbapi/cello-sessionDb/celloDb.cpp deleted file mode 100644 index ec61e783585..00000000000 --- a/ndb/test/ndbapi/cello-sessionDb/celloDb.cpp +++ /dev/null @@ -1,1503 +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 */ - - -/* *************************************************** - BASIC TEST 1 - Test basic functions and status of NDB - - Arguments: - none - - Returns: - 0 - Test passed - -1 - Test failed - 1 - Invalid arguments -flexBench - * *************************************************** */ - -#include -#include - -#define MAXATTR 4 -#define MAXTABLES 4 -#define PAGESIZE 8192 -#define OVERHEAD 0.02 -#define NUMBEROFRECORDS 10 -#define PKSIZE 1 -#define ATTRNAMELEN 16 - - -static void createTable_IPACCT(Ndb*); -static void createTable_RPACCT(Ndb*); -static void createTable_SBMCALL(Ndb*); -static void createTable_TODACCT(Ndb*); - -static void error_handler(const char*); -static bool error_handler2(const char*, int) ; - -static void setAttrNames(void); -static void setTableNames(void); -static void create_table(Ndb*); -static void insert_rows(Ndb*); -static void update_rows(Ndb*); -static void delete_rows(Ndb*); -static void verify_deleted(Ndb*); -static void read_and_verify_rows(Ndb*); - -static void insert_IPACCT(Ndb*, Uint32, Uint32, Uint32, Uint32, Uint32); //3 for Pk, and two data. just to test; - -static void read_IPACCT(Ndb* , Uint32 , Uint32 , Uint32 ); - -static int tAttributeSize; -static int bTestPassed; - -static char tableName[MAXTABLES][ATTRNAMELEN];static char attrName[MAXATTR][ATTRNAMELEN]; -static int attrValue[NUMBEROFRECORDS]; -static int pkValue[NUMBEROFRECORDS]; -static int failed = 0 ; -#include - -NDB_COMMAND(celloDb, "celloDb", "celloDb", "celloDb", 65535) -{ - - int tTableId; - int i; - Ndb MyNdb( "CELLO-SESSION-DB" ); - - MyNdb.init(); - - // Assume test passed - bTestPassed = 0; - /* - // Initialize global variables - for (i = 0; i < NUMBEROFRECORDS; i ++) - pkValue[i] = i; - - for (i = 0; i < NUMBEROFRECORDS; i ++) - attrValue[i] = i; - */ - tAttributeSize = 1; - - // Wait for Ndb to become ready - if (MyNdb.waitUntilReady() == 0) { - ndbout << endl << "Cello session db - Starting " << endl; - ndbout << "Test basic functions and status of NDB" << endl; - - - - createTable_SBMCALL (&MyNdb ); - createTable_RPACCT (&MyNdb ); - createTable_TODACCT (&MyNdb ); - createTable_IPACCT (&MyNdb ); - - insert_IPACCT(&MyNdb, 1,2,1,2,2); - read_IPACCT(&MyNdb, 1, 2 , 1); - /* - insert_rows(&MyNdb); - - read_and_verify_rows(&MyNdb); - - - // Create some new values to use for update - for (i = 0; i < NUMBEROFRECORDS; i++) - attrValue[i] = NUMBEROFRECORDS-i; - - update_rows(&MyNdb); - - read_and_verify_rows(&MyNdb); - - delete_rows(&MyNdb); - - verify_deleted(&MyNdb); - */ - } - else { - bTestPassed = -1; - } - - - if (bTestPassed == 0) - { - // Test passed - ndbout << "OK - Test passed" << endl; - } - else - { - // Test failed - ndbout << "FAIL - Test failed" << endl; - exit(-1); - } - return NULL; -} - -static void -error_handler(const char* errorText) -{ - // Test failed - ndbout << endl << "ErrorMessage: " << errorText << endl; - bTestPassed = -1; -} - -static void -createTable_SBMCALL ( Ndb* pMyNdb ) -{ - /**************************************************************** - * Create table and attributes. - * - * create table SBMCALL( - * for attribs, see the REQ SPEC for cello session DB - * ) - * - ***************************************************************/ - - const char* tname = "SBMCALL"; - Uint32 recordsize = 244; //including 12 byte overhead - Uint32 pksize = 8; //size of total prim. key. in bytes. sum of entire composite PK. - Uint32 tTableId = pMyNdb->getTable()->openTable(tname); - - if (tTableId == -1) { - Uint32 check; - Uint32 i; - NdbSchemaCon *MySchemaTransaction; - NdbSchemaOp *MySchemaOp; - - ndbout << "Creating " << tname << "..." << endl; - - MySchemaTransaction = pMyNdb->startSchemaTransaction(); - if( ( MySchemaTransaction == NULL ) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); - if( ( MySchemaOp == NULL ) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - // Createtable - - Uint32 tablesize=(recordsize*NUMBEROFRECORDS + OVERHEAD * NUMBEROFRECORDS)/1024; - Uint32 noPages=(pksize*NUMBEROFRECORDS)/PAGESIZE; - - ndbout << "table size " << tablesize << "for table name " << tname << endl; - - check = MySchemaOp->createTable( tname, - tablesize, // Table Size - TupleKey, // Key Type - noPages, // Nr of Pages - All, - 6, - 78, - 80, - 1, - true - ); - - if( check == -1 ) { - error_handler(MySchemaTransaction->getNdbErrorString()); - exit(-1); - } - - - - // Create first column, primary key - check = MySchemaOp->createAttribute( "SPBBOARDID", - TupleKey, - 32, - PKSIZE, - UnSigned, - MMBased, - NotNullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - // Create second column, primary key - check = MySchemaOp->createAttribute( "CALLID", - TupleKey, - 32, - PKSIZE, - UnSigned, - MMBased, - NotNullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - // Creat thrid column, RP Session info, byte[16] represented as (String, 16) - check = MySchemaOp->createAttribute( "RPSESS", - NoKey, - 32, - 16, - String, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - -// Creat fourth column, GRE Tunnel info, byte[16] represented as (String, 16) - check = MySchemaOp->createAttribute( "GRETUNNEL", - NoKey, - 32, - 16, - String, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - -// Creat fifth column, PPP Session info, byte[24] represented as (String, 24) - check = MySchemaOp->createAttribute( "PPPSESS", - NoKey, - 32, - 24, - String, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - if( (MySchemaTransaction->execute() == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - pMyNdb->closeSchemaTransaction(MySchemaTransaction); - ndbout << "done" << endl; - - - } //if - - //else table already created , proceed -} - - - -static void -createTable_RPACCT(Ndb*pMyNdb) -{ - - /**************************************************************** - * Create table and attributes. - * - * create table RPACCT( - * for attribs, see the REQ SPEC for cello session DB - * ) - * - ***************************************************************/ - - const char* tname = "RPACCT"; - Uint32 recordsize = 380; //including 12 byte overhead - Uint32 pksize = 8; //size of total prim. key. in bytes. - Uint32 tTableId = pMyNdb->getTable()->openTable(tname); - - if (tTableId == -1) { - Uint32 check; - Uint32 i; - NdbSchemaCon *MySchemaTransaction; - NdbSchemaOp *MySchemaOp; - - ndbout << "Creating " << tname << "..." << endl; - - MySchemaTransaction = pMyNdb->startSchemaTransaction(); - if( MySchemaTransaction == NULL ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); - if( MySchemaOp == NULL ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // Createtable - - Uint32 tablesize=(recordsize*NUMBEROFRECORDS + OVERHEAD * NUMBEROFRECORDS)/1024; - Uint32 noPages=(pksize*NUMBEROFRECORDS)/PAGESIZE; - - ndbout << "table size " << tablesize << "for table name " << tname << endl; - - check = MySchemaOp->createTable( tname, - tablesize, // Table Size - TupleKey, // Key Type - noPages // Nr of Pages - ); - - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - - - // Create first column, primary key - check = MySchemaOp->createAttribute( "SPBBOARDID", - TupleKey, - 32, - PKSIZE, - UnSigned, - MMBased, - NotNullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - // Create second column, primary key - check = MySchemaOp->createAttribute( "CALLID", - TupleKey, - 32, - PKSIZE, - UnSigned, - MMBased, - NotNullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - // Creat thrid column MS ID, 4 byte unsigned - check = MySchemaOp->createAttribute( "MSID", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - // Create PDSN FA Address, 4 byte unsigned - check = MySchemaOp->createAttribute( "PDSN", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - // Create Serving PCF, 4 byte unsigned - check = MySchemaOp->createAttribute( "SPCF", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - - // Create BS ID, 12 byte char, represented as String,12 - check = MySchemaOp->createAttribute( "BSID", - NoKey, - 32, - 12, - String, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - - - - // Create User Zone, 4 byte unsigned - check = MySchemaOp->createAttribute( "UZ", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - // Create Forward Multiplex, 4 byte unsigned - check = MySchemaOp->createAttribute( "FMO", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - // Create Reverse Multiplex, 4 byte unsigned - check = MySchemaOp->createAttribute( "RMO", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - // Create Forward Fund rate, 4 byte unsigned - check = MySchemaOp->createAttribute( "FFR", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - // Create Reverse Fund rate, 4 byte unsigned - check = MySchemaOp->createAttribute( "RFR", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - - // Create Service Option, 4 byte unsigned - check = MySchemaOp->createAttribute( "SO", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - - - // Create Forward Traffic Type, 4 byte unsigned - check = MySchemaOp->createAttribute( "FTT", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - -// Create Reverse Traffic Type, 4 byte unsigned - check = MySchemaOp->createAttribute( "RTT", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - -// Create Fund Frame Size, 4 byte unsigned - check = MySchemaOp->createAttribute( "FFS", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - -// Create Forware Fund RC, 4 byte unsigned - check = MySchemaOp->createAttribute( "FFRC", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - - // Create Reverse Fund RC, 4 byte unsigned - check = MySchemaOp->createAttribute( "RFRC", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - // Create DCCH Frame Format, 4 byte unsigned - check = MySchemaOp->createAttribute( "DCCH", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - // Create Airlink QOS, 4 byte unsigned - check = MySchemaOp->createAttribute( "AQOS", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - -// Create Bad PPP Frame Count , 4 byte unsigned - check = MySchemaOp->createAttribute( "BPPPFC", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - - -// Create Active Time , 4 byte unsigned - check = MySchemaOp->createAttribute( "AT", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - -// Create Nb Active Transitions , 4 byte unsigned - check = MySchemaOp->createAttribute( "NBAT", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - -// Create SDB Octet Count In , 4 byte unsigned - check = MySchemaOp->createAttribute( "SDBOCI", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - - -// Create Nb SDB In, 4 byte unsigned - check = MySchemaOp->createAttribute( "NBSDBI", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - - -// Create Nb SDB Out, 4 byte unsigned - check = MySchemaOp->createAttribute( "NBSDBO", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - - -// Create HDLC Bytes received, 4 byte unsigned - check = MySchemaOp->createAttribute( "HDLC", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - - if( (MySchemaTransaction->execute() == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - pMyNdb->closeSchemaTransaction(MySchemaTransaction); - ndbout << "done" << endl; - - } //if - - //else table already created , proceed - } - - -static void -createTable_IPACCT(Ndb* pMyNdb) -{ - - - /**************************************************************** - * Create table and attributes. - * - * create table IPACCT( - * for attribs, see the REQ SPEC for cello session DB - * ) - * - ***************************************************************/ - - const char* tname = "IPACCT"; - Uint32 recordsize = 70; //including 12 byte overhead - Uint32 pksize = 12; //size of total prim. key. in bytes. - Uint32 tTableId = pMyNdb->getTable()->openTable(tname); - - if (tTableId == -1) { - Uint32 check; - Uint32 i; - NdbSchemaCon *MySchemaTransaction; - NdbSchemaOp *MySchemaOp; - - ndbout << "Creating " << tname << "..." << endl; - - MySchemaTransaction = pMyNdb->startSchemaTransaction(); - if( MySchemaTransaction == NULL ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); - if( MySchemaOp == NULL ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // Createtable - - Uint32 tablesize=(recordsize*NUMBEROFRECORDS + OVERHEAD * NUMBEROFRECORDS)/1024; - Uint32 noPages=(pksize*NUMBEROFRECORDS)/PAGESIZE; - - ndbout << "table size " << tablesize << "for table name " << tname << endl; - - check = MySchemaOp->createTable( tname, - tablesize, // Table Size - TupleKey, // Key Type - noPages // Nr of Pages - ); - - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - - - // Create first column, primary key - check = MySchemaOp->createAttribute( "SPBBOARDID", - TupleKey, - 32, - PKSIZE, - UnSigned, - MMBased, - NotNullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - // Create second column, primary key - check = MySchemaOp->createAttribute( "CALLID", - TupleKey, - 32, - PKSIZE, - UnSigned, - MMBased, - NotNullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - // Create third column, primary key - check = MySchemaOp->createAttribute( "IPADDR", - TupleKey, - 32, - PKSIZE, - String, - MMBased, - NotNullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - - -// Create Acct session id 4 byte unsigned - check = MySchemaOp->createAttribute( "ASID", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - -// Create Correlation ID, 4 byte unsigned - check = MySchemaOp->createAttribute( "CID", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - -// Create MIP HA Address, 4 byte unsigned - check = MySchemaOp->createAttribute( "MIPHA", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - - - -// Create IP technology, 4 byte unsigned - check = MySchemaOp->createAttribute( "IPT", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - -// Create Compuls Tunnel ID, 4 byte unsigned - check = MySchemaOp->createAttribute( "CTID", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - -// Create IP QOS, 4 byte unsigned - check = MySchemaOp->createAttribute( "IPQOS", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - // Create Data octet count in, 4 byte unsigned - check = MySchemaOp->createAttribute( "DOCI", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - // Create Data octet count out, 4 byte unsigned - check = MySchemaOp->createAttribute( "DOCO", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - // Create Event time, 4 byte unsigned - check = MySchemaOp->createAttribute( "ET", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - // Create In mip sig count, 4 byte unsigned - check = MySchemaOp->createAttribute( "IMSC", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - -// Create Out mip sig count, 4 byte unsigned - check = MySchemaOp->createAttribute( "OMSC", - NoKey, - 32, - 1, - UnSigned, - MMBased, - NullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - if( (MySchemaTransaction->execute() == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - pMyNdb->closeSchemaTransaction(MySchemaTransaction); - ndbout << "done" << endl; - - - - } //if - - //else table already created , proceed -} - - -static void -createTable_TODACCT(Ndb* pMyNdb) -{ - - - /**************************************************************** - * Create table and attributes. - * - * create table TODACCT( - * for attribs, see the REQ SPEC for cello session DB - * ) - * - ***************************************************************/ - - const char* tname = "TODACCT"; - Uint32 recordsize = 92; //including 12 byte overhead - Uint32 pksize = 12; //size of total prim. key. in bytes. - Uint32 tTableId = pMyNdb->getTable()->openTable(tname); - - if (tTableId == -1) { - Uint32 check; - Uint32 i; - NdbSchemaCon *MySchemaTransaction; - NdbSchemaOp *MySchemaOp; - - ndbout << "Creating " << tname << "..." << endl; - - MySchemaTransaction = pMyNdb->startSchemaTransaction(); - if( MySchemaTransaction == NULL ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); - if( MySchemaOp == NULL ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // Createtable - - Uint32 tablesize=(recordsize*NUMBEROFRECORDS + OVERHEAD * NUMBEROFRECORDS)/1024; - Uint32 noPages=(pksize*NUMBEROFRECORDS)/PAGESIZE; - - ndbout << "table size " << tablesize << "for table name " << tname << endl; - - check = MySchemaOp->createTable( tname, - tablesize, // Table Size - TupleKey, // Key Type - noPages // Nr of Pages - ); - - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - - - // Create first column, primary key - check = MySchemaOp->createAttribute( "SPBBOARDID", - TupleKey, - 32, - PKSIZE, - UnSigned, - MMBased, - NotNullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - // Create second column, primary key - check = MySchemaOp->createAttribute( "CALLID", - TupleKey, - 32, - PKSIZE, - UnSigned, - MMBased, - NotNullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - // Create third column, primary key - check = MySchemaOp->createAttribute( "IPADDR", - TupleKey, - 32, - PKSIZE, - String, - MMBased, - NotNullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - - // Create third column, primary key - check = MySchemaOp->createAttribute( "INDEX", - TupleKey, - 32, - PKSIZE, - UnSigned, - MMBased, - NotNullAttribute ); - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - - -// Create Acct session id 4 byte unsigned - check = MySchemaOp->createAttribute( "TOD", - NoKey, - 32, - 16, - String, - MMBased, - NullAttribute ); - - - if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - - - if( (MySchemaTransaction->execute() == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) - exit (-1) ; - - pMyNdb->closeSchemaTransaction(MySchemaTransaction); - ndbout << "done" << endl; - - } //if - - //else table already created , proceed -} - - - - - - -static void read_IPACCT(Ndb* pMyNdb, Uint32 CALLID, Uint32 SPBBOARDID , Uint32 IPADDR) -{ - - - int check; - int loop_count_ops; - int count; - int count_attributes; - char* value; - NdbConnection *MyTransaction; - NdbOperation *MyOperation; - NdbRecAttr* tTmp; - - - - MyTransaction = pMyNdb->startTransaction(); - if (MyTransaction == NULL) - error_handler(pMyNdb->getNdbErrorString()); - - MyOperation = MyTransaction->getNdbOperation("IPACCT"); - if (MyOperation == NULL) - error_handler( MyTransaction->getNdbErrorString()); - - check = MyOperation->readTuple(); - if( check == -1 ) - error_handler( MyTransaction->getNdbErrorString()); - - check = MyOperation->equal( "SPBBOARDID",SPBBOARDID ); - if( check == -1 ) - error_handler( MyTransaction->getNdbErrorString()); - - - check = MyOperation->equal( "IPADDR","IPADDR" ); - if( check == -1 ) - error_handler( MyTransaction->getNdbErrorString()); - - - check = MyOperation->equal( "CALLID",CALLID ); - if( check == -1 ) - error_handler( MyTransaction->getNdbErrorString()); - - - - - tTmp = MyOperation->getValue("IPQOS", NULL ); - if( tTmp == NULL ) - error_handler( MyTransaction->getNdbErrorString()); - ndbout << " tTmp " << tTmp->isNULL() << endl; - MyTransaction->execute(Commit); - - ndbout << " value read " << tTmp->int32_value() << endl; - -} - - - -static void insert_IPACCT(Ndb* pMyNdb, Uint32 CALLID, Uint32 SPBBOARDID , Uint32 IPADDR, Uint32 ASID, Uint32 IPQOS) -{ - /**************************************************************** - * Insert rows - * - ***************************************************************/ - - int check; - int loop_count_ops; - int count; - int i; - NdbConnection *MyTransaction; - NdbOperation *MyOperation; - - ndbout << "Inserting records..." << flush; - - MyTransaction = pMyNdb->startTransaction(); - if (MyTransaction == NULL) - error_handler(pMyNdb->getNdbErrorString()); - - MyOperation = MyTransaction->getNdbOperation("IPACCT"); - if (MyOperation == NULL) - error_handler(MyTransaction->getNdbErrorString()); - - - - check = MyOperation->insertTuple(); - if( check == -1 ) - error_handler(MyTransaction->getNdbErrorString()); - - ndbout << "insertTuple" << endl; - - check = MyOperation->equal("CALLID",CALLID ); - if( check == -1 ) - error_handler(MyTransaction->getNdbErrorString()); - ndbout << "equal" << endl; - - - check = MyOperation->equal("SPBBOARDID",SPBBOARDID ); - if( check == -1 ) - error_handler(MyTransaction->getNdbErrorString()); - ndbout << "equal" << endl; - - - check = MyOperation->equal("IPADDR","IPADDR" ); - if( check == -1 ) - error_handler(MyTransaction->getNdbErrorString()); - ndbout << "equal" << endl; - - - check = MyOperation->setValue( "IPQOS", IPQOS); - if( check == -1 ) - error_handler(MyTransaction->getNdbErrorString()); - ndbout << "Set Value" << endl; - - - - check = MyOperation->setValue( "ASID", ASID); - if( check == -1 ) - error_handler(MyTransaction->getNdbErrorString()); - ndbout << "Set Value" << endl; - - - check = MyTransaction->execute( Commit ); - if(check == -1 ) { - ndbout << "error at commit" << endl; - error_handler(MyTransaction->getNdbErrorString()); - } - else - ;//ndbout << "."; - - pMyNdb->closeTransaction(MyTransaction); - - - - ndbout << "OK" << endl; - - return; -} - -static void -update_rows(Ndb* pMyNdb){ - /**************************************************************** - * Update rows in SimpleTable - * - ***************************************************************/ - - int check; - int loop_count_ops; - int count; - int i; - NdbConnection *MyTransaction; - NdbOperation *MyOperation; - - ndbout << "Updating records..." << flush; - - loop_count_ops = NUMBEROFRECORDS; - - for (count=0 ; count < loop_count_ops ; count++) { - - MyTransaction = pMyNdb->startTransaction(); - if (MyTransaction == NULL) - error_handler( pMyNdb->getNdbErrorString() ); - - MyOperation = MyTransaction->getNdbOperation(tableName[0]); - if (MyOperation == NULL) - error_handler(MyTransaction->getNdbErrorString()); - - check = MyOperation->updateTuple(); - if( check == -1 ) - error_handler(MyTransaction->getNdbErrorString()); - - check = MyOperation->equal( attrName[0], (char*)&pkValue[count] ); - if( check == -1 ) - error_handler(MyTransaction->getNdbErrorString()); - - for (i = 1; i < MAXATTR; i++) - { - check = MyOperation->setValue( attrName[i], (char*)&attrValue[count]); - if( check == -1 ) - error_handler(MyTransaction->getNdbErrorString()); - } - - if( MyTransaction->execute( Commit ) == -1 ) - error_handler(MyTransaction->getNdbErrorString()); - else - ;//ndbout << "."; - - pMyNdb->closeTransaction(MyTransaction); - - } - - ndbout << "OK" << endl; - return; - -}; - -static void -delete_rows(Ndb* pMyNdb){ - - /**************************************************************** - * Delete rows from SimpleTable - * - ***************************************************************/ - - int check; - int loop_count_ops; - int count; - NdbConnection *MyTransaction; - NdbOperation *MyOperation; - - ndbout << "Deleting records..."<< flush; - - loop_count_ops = NUMBEROFRECORDS; - - for (count=0 ; count < loop_count_ops ; count++) { - - MyTransaction = pMyNdb->startTransaction(); - if (MyTransaction == NULL) - error_handler( pMyNdb->getNdbErrorString() ); - - MyOperation = MyTransaction->getNdbOperation(tableName[0]); - if (MyOperation == NULL) - error_handler(MyTransaction->getNdbErrorString()); - - - check = MyOperation->deleteTuple(); - if( check == -1 ) - error_handler(MyTransaction->getNdbErrorString()); - - check = MyOperation->equal( attrName[0], (char*)&pkValue[count] ); - if( check == -1 ) - error_handler(MyTransaction->getNdbErrorString()); - - - if( MyTransaction->execute( Commit ) == -1 ) - error_handler(MyTransaction->getNdbErrorString()); - else - ;// ndbout << "."; - - pMyNdb->closeTransaction(MyTransaction); - - } - - ndbout << "OK" << endl; - return; - -}; - -static void -verify_deleted(Ndb* pMyNdb){ - int check; - int loop_count_ops; - int count; - NdbConnection *MyTransaction; - NdbOperation *MyOperation; - - ndbout << "Verifying deleted records..."<< flush; - - loop_count_ops = NUMBEROFRECORDS; - - for (count=0 ; count < loop_count_ops ; count++) - { - MyTransaction = pMyNdb->startTransaction(); - if (MyTransaction == NULL) - error_handler(pMyNdb->getNdbErrorString()); - - MyOperation = MyTransaction->getNdbOperation(tableName[0]); - if (MyOperation == NULL) - error_handler( MyTransaction->getNdbErrorString()); - - check = MyOperation->readTuple(); - if( check == -1 ) - error_handler( MyTransaction->getNdbErrorString()); - - check = MyOperation->equal( attrName[0],(char*)&pkValue[count] ); - if( check == -1 ) - error_handler( MyTransaction->getNdbErrorString()); - - // Exepect to receive an error - if( MyTransaction->execute( Commit ) != -1 ) - error_handler(MyTransaction->getNdbErrorString()); - else - { - ;//ndbout << "."; - } - - pMyNdb->closeTransaction(MyTransaction); - - } - - ndbout << "OK" << endl; - return; -}; - -static void -read_and_verify_rows(Ndb* pMyNdb) -{ - - int check; - int loop_count_ops; - int count; - int count_attributes; - - NdbConnection *MyTransaction; - NdbOperation *MyOperation; - NdbRecAttr* tTmp; - - int readValue[MAXATTR]; - - ndbout << "Verifying records..."<< flush; - - loop_count_ops = NUMBEROFRECORDS; - - for (count=0 ; count < loop_count_ops ; count++) - { - MyTransaction = pMyNdb->startTransaction(); - if (MyTransaction == NULL) - error_handler(pMyNdb->getNdbErrorString()); - - MyOperation = MyTransaction->getNdbOperation(tableName[0]); - if (MyOperation == NULL) - error_handler( MyTransaction->getNdbErrorString()); - - check = MyOperation->readTuple(); - if( check == -1 ) - error_handler( MyTransaction->getNdbErrorString()); - - check = MyOperation->equal( attrName[0],(char*)&pkValue[count] ); - if( check == -1 ) - error_handler( MyTransaction->getNdbErrorString()); - - for (count_attributes = 1; count_attributes < MAXATTR; count_attributes++) - { - tTmp = MyOperation->getValue( (char*)attrName[count_attributes], (char*)&readValue[count_attributes] ); - if( tTmp == NULL ) - error_handler( MyTransaction->getNdbErrorString()); - } - - if( MyTransaction->execute( Commit ) == -1 ) - error_handler(MyTransaction->getNdbErrorString()); - else - { - // Check value in db against value in mem - - //ndbout << readValue[1] << " == " << attrValue[count] << endl; - - if ( readValue[1]!=attrValue[count] ) - error_handler("Verification error!"); - else - if ( readValue[2]!=attrValue[count] ) - error_handler("Verification error!"); - else - if ( readValue[3]!=attrValue[count] ) - error_handler("Verification error!"); - else - { - ;//ndbout << "."; - } - } - pMyNdb->closeTransaction(MyTransaction); - - } - - ndbout << "OK" << endl; - return; - - - -}; - - -static void -setAttrNames() -{ - int i; - - for (i = 0; i < MAXATTR ; i++) - { - sprintf(&attrName[i][0], "Col%d", i); - } -} - -static void -setTableNames() -{ - int i; - - sprintf(&tableName[0][0], "SBMCALL", 0); - sprintf(&tableName[1][0], "RPACCT", 0); - sprintf(&tableName[2][0], "IPACCT", 0); - sprintf(&tableName[3][0], "TODACCT", 0); - -} - - -bool error_handler2(const char* error_string, int error_int) { - failed++ ; - ndbout << error_string << endl ; - if ( 4008==error_int || 721==error_int || 266==error_int ){ - ndbout << endl << "Attempting to recover and continue now..." << endl ; - return true ; // return true to retry - } - return false ; // return false to abort -} diff --git a/ndb/test/ndbapi/celloDb.cpp b/ndb/test/ndbapi/celloDb.cpp new file mode 100644 index 00000000000..ec61e783585 --- /dev/null +++ b/ndb/test/ndbapi/celloDb.cpp @@ -0,0 +1,1503 @@ +/* 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 */ + + +/* *************************************************** + BASIC TEST 1 + Test basic functions and status of NDB + + Arguments: + none + + Returns: + 0 - Test passed + -1 - Test failed + 1 - Invalid arguments +flexBench + * *************************************************** */ + +#include +#include + +#define MAXATTR 4 +#define MAXTABLES 4 +#define PAGESIZE 8192 +#define OVERHEAD 0.02 +#define NUMBEROFRECORDS 10 +#define PKSIZE 1 +#define ATTRNAMELEN 16 + + +static void createTable_IPACCT(Ndb*); +static void createTable_RPACCT(Ndb*); +static void createTable_SBMCALL(Ndb*); +static void createTable_TODACCT(Ndb*); + +static void error_handler(const char*); +static bool error_handler2(const char*, int) ; + +static void setAttrNames(void); +static void setTableNames(void); +static void create_table(Ndb*); +static void insert_rows(Ndb*); +static void update_rows(Ndb*); +static void delete_rows(Ndb*); +static void verify_deleted(Ndb*); +static void read_and_verify_rows(Ndb*); + +static void insert_IPACCT(Ndb*, Uint32, Uint32, Uint32, Uint32, Uint32); //3 for Pk, and two data. just to test; + +static void read_IPACCT(Ndb* , Uint32 , Uint32 , Uint32 ); + +static int tAttributeSize; +static int bTestPassed; + +static char tableName[MAXTABLES][ATTRNAMELEN];static char attrName[MAXATTR][ATTRNAMELEN]; +static int attrValue[NUMBEROFRECORDS]; +static int pkValue[NUMBEROFRECORDS]; +static int failed = 0 ; +#include + +NDB_COMMAND(celloDb, "celloDb", "celloDb", "celloDb", 65535) +{ + + int tTableId; + int i; + Ndb MyNdb( "CELLO-SESSION-DB" ); + + MyNdb.init(); + + // Assume test passed + bTestPassed = 0; + /* + // Initialize global variables + for (i = 0; i < NUMBEROFRECORDS; i ++) + pkValue[i] = i; + + for (i = 0; i < NUMBEROFRECORDS; i ++) + attrValue[i] = i; + */ + tAttributeSize = 1; + + // Wait for Ndb to become ready + if (MyNdb.waitUntilReady() == 0) { + ndbout << endl << "Cello session db - Starting " << endl; + ndbout << "Test basic functions and status of NDB" << endl; + + + + createTable_SBMCALL (&MyNdb ); + createTable_RPACCT (&MyNdb ); + createTable_TODACCT (&MyNdb ); + createTable_IPACCT (&MyNdb ); + + insert_IPACCT(&MyNdb, 1,2,1,2,2); + read_IPACCT(&MyNdb, 1, 2 , 1); + /* + insert_rows(&MyNdb); + + read_and_verify_rows(&MyNdb); + + + // Create some new values to use for update + for (i = 0; i < NUMBEROFRECORDS; i++) + attrValue[i] = NUMBEROFRECORDS-i; + + update_rows(&MyNdb); + + read_and_verify_rows(&MyNdb); + + delete_rows(&MyNdb); + + verify_deleted(&MyNdb); + */ + } + else { + bTestPassed = -1; + } + + + if (bTestPassed == 0) + { + // Test passed + ndbout << "OK - Test passed" << endl; + } + else + { + // Test failed + ndbout << "FAIL - Test failed" << endl; + exit(-1); + } + return NULL; +} + +static void +error_handler(const char* errorText) +{ + // Test failed + ndbout << endl << "ErrorMessage: " << errorText << endl; + bTestPassed = -1; +} + +static void +createTable_SBMCALL ( Ndb* pMyNdb ) +{ + /**************************************************************** + * Create table and attributes. + * + * create table SBMCALL( + * for attribs, see the REQ SPEC for cello session DB + * ) + * + ***************************************************************/ + + const char* tname = "SBMCALL"; + Uint32 recordsize = 244; //including 12 byte overhead + Uint32 pksize = 8; //size of total prim. key. in bytes. sum of entire composite PK. + Uint32 tTableId = pMyNdb->getTable()->openTable(tname); + + if (tTableId == -1) { + Uint32 check; + Uint32 i; + NdbSchemaCon *MySchemaTransaction; + NdbSchemaOp *MySchemaOp; + + ndbout << "Creating " << tname << "..." << endl; + + MySchemaTransaction = pMyNdb->startSchemaTransaction(); + if( ( MySchemaTransaction == NULL ) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); + if( ( MySchemaOp == NULL ) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + // Createtable + + Uint32 tablesize=(recordsize*NUMBEROFRECORDS + OVERHEAD * NUMBEROFRECORDS)/1024; + Uint32 noPages=(pksize*NUMBEROFRECORDS)/PAGESIZE; + + ndbout << "table size " << tablesize << "for table name " << tname << endl; + + check = MySchemaOp->createTable( tname, + tablesize, // Table Size + TupleKey, // Key Type + noPages, // Nr of Pages + All, + 6, + 78, + 80, + 1, + true + ); + + if( check == -1 ) { + error_handler(MySchemaTransaction->getNdbErrorString()); + exit(-1); + } + + + + // Create first column, primary key + check = MySchemaOp->createAttribute( "SPBBOARDID", + TupleKey, + 32, + PKSIZE, + UnSigned, + MMBased, + NotNullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + // Create second column, primary key + check = MySchemaOp->createAttribute( "CALLID", + TupleKey, + 32, + PKSIZE, + UnSigned, + MMBased, + NotNullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + // Creat thrid column, RP Session info, byte[16] represented as (String, 16) + check = MySchemaOp->createAttribute( "RPSESS", + NoKey, + 32, + 16, + String, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + +// Creat fourth column, GRE Tunnel info, byte[16] represented as (String, 16) + check = MySchemaOp->createAttribute( "GRETUNNEL", + NoKey, + 32, + 16, + String, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + +// Creat fifth column, PPP Session info, byte[24] represented as (String, 24) + check = MySchemaOp->createAttribute( "PPPSESS", + NoKey, + 32, + 24, + String, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + if( (MySchemaTransaction->execute() == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + pMyNdb->closeSchemaTransaction(MySchemaTransaction); + ndbout << "done" << endl; + + + } //if + + //else table already created , proceed +} + + + +static void +createTable_RPACCT(Ndb*pMyNdb) +{ + + /**************************************************************** + * Create table and attributes. + * + * create table RPACCT( + * for attribs, see the REQ SPEC for cello session DB + * ) + * + ***************************************************************/ + + const char* tname = "RPACCT"; + Uint32 recordsize = 380; //including 12 byte overhead + Uint32 pksize = 8; //size of total prim. key. in bytes. + Uint32 tTableId = pMyNdb->getTable()->openTable(tname); + + if (tTableId == -1) { + Uint32 check; + Uint32 i; + NdbSchemaCon *MySchemaTransaction; + NdbSchemaOp *MySchemaOp; + + ndbout << "Creating " << tname << "..." << endl; + + MySchemaTransaction = pMyNdb->startSchemaTransaction(); + if( MySchemaTransaction == NULL ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); + if( MySchemaOp == NULL ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // Createtable + + Uint32 tablesize=(recordsize*NUMBEROFRECORDS + OVERHEAD * NUMBEROFRECORDS)/1024; + Uint32 noPages=(pksize*NUMBEROFRECORDS)/PAGESIZE; + + ndbout << "table size " << tablesize << "for table name " << tname << endl; + + check = MySchemaOp->createTable( tname, + tablesize, // Table Size + TupleKey, // Key Type + noPages // Nr of Pages + ); + + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + + + // Create first column, primary key + check = MySchemaOp->createAttribute( "SPBBOARDID", + TupleKey, + 32, + PKSIZE, + UnSigned, + MMBased, + NotNullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + // Create second column, primary key + check = MySchemaOp->createAttribute( "CALLID", + TupleKey, + 32, + PKSIZE, + UnSigned, + MMBased, + NotNullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + // Creat thrid column MS ID, 4 byte unsigned + check = MySchemaOp->createAttribute( "MSID", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + // Create PDSN FA Address, 4 byte unsigned + check = MySchemaOp->createAttribute( "PDSN", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + // Create Serving PCF, 4 byte unsigned + check = MySchemaOp->createAttribute( "SPCF", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + + // Create BS ID, 12 byte char, represented as String,12 + check = MySchemaOp->createAttribute( "BSID", + NoKey, + 32, + 12, + String, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + + + + // Create User Zone, 4 byte unsigned + check = MySchemaOp->createAttribute( "UZ", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + // Create Forward Multiplex, 4 byte unsigned + check = MySchemaOp->createAttribute( "FMO", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + // Create Reverse Multiplex, 4 byte unsigned + check = MySchemaOp->createAttribute( "RMO", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + // Create Forward Fund rate, 4 byte unsigned + check = MySchemaOp->createAttribute( "FFR", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + // Create Reverse Fund rate, 4 byte unsigned + check = MySchemaOp->createAttribute( "RFR", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + + // Create Service Option, 4 byte unsigned + check = MySchemaOp->createAttribute( "SO", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + + + // Create Forward Traffic Type, 4 byte unsigned + check = MySchemaOp->createAttribute( "FTT", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + +// Create Reverse Traffic Type, 4 byte unsigned + check = MySchemaOp->createAttribute( "RTT", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + +// Create Fund Frame Size, 4 byte unsigned + check = MySchemaOp->createAttribute( "FFS", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + +// Create Forware Fund RC, 4 byte unsigned + check = MySchemaOp->createAttribute( "FFRC", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + + // Create Reverse Fund RC, 4 byte unsigned + check = MySchemaOp->createAttribute( "RFRC", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + // Create DCCH Frame Format, 4 byte unsigned + check = MySchemaOp->createAttribute( "DCCH", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + // Create Airlink QOS, 4 byte unsigned + check = MySchemaOp->createAttribute( "AQOS", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + +// Create Bad PPP Frame Count , 4 byte unsigned + check = MySchemaOp->createAttribute( "BPPPFC", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + + +// Create Active Time , 4 byte unsigned + check = MySchemaOp->createAttribute( "AT", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + +// Create Nb Active Transitions , 4 byte unsigned + check = MySchemaOp->createAttribute( "NBAT", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + +// Create SDB Octet Count In , 4 byte unsigned + check = MySchemaOp->createAttribute( "SDBOCI", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + + +// Create Nb SDB In, 4 byte unsigned + check = MySchemaOp->createAttribute( "NBSDBI", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + + +// Create Nb SDB Out, 4 byte unsigned + check = MySchemaOp->createAttribute( "NBSDBO", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + + +// Create HDLC Bytes received, 4 byte unsigned + check = MySchemaOp->createAttribute( "HDLC", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + + if( (MySchemaTransaction->execute() == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + pMyNdb->closeSchemaTransaction(MySchemaTransaction); + ndbout << "done" << endl; + + } //if + + //else table already created , proceed + } + + +static void +createTable_IPACCT(Ndb* pMyNdb) +{ + + + /**************************************************************** + * Create table and attributes. + * + * create table IPACCT( + * for attribs, see the REQ SPEC for cello session DB + * ) + * + ***************************************************************/ + + const char* tname = "IPACCT"; + Uint32 recordsize = 70; //including 12 byte overhead + Uint32 pksize = 12; //size of total prim. key. in bytes. + Uint32 tTableId = pMyNdb->getTable()->openTable(tname); + + if (tTableId == -1) { + Uint32 check; + Uint32 i; + NdbSchemaCon *MySchemaTransaction; + NdbSchemaOp *MySchemaOp; + + ndbout << "Creating " << tname << "..." << endl; + + MySchemaTransaction = pMyNdb->startSchemaTransaction(); + if( MySchemaTransaction == NULL ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); + if( MySchemaOp == NULL ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // Createtable + + Uint32 tablesize=(recordsize*NUMBEROFRECORDS + OVERHEAD * NUMBEROFRECORDS)/1024; + Uint32 noPages=(pksize*NUMBEROFRECORDS)/PAGESIZE; + + ndbout << "table size " << tablesize << "for table name " << tname << endl; + + check = MySchemaOp->createTable( tname, + tablesize, // Table Size + TupleKey, // Key Type + noPages // Nr of Pages + ); + + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + + + // Create first column, primary key + check = MySchemaOp->createAttribute( "SPBBOARDID", + TupleKey, + 32, + PKSIZE, + UnSigned, + MMBased, + NotNullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + // Create second column, primary key + check = MySchemaOp->createAttribute( "CALLID", + TupleKey, + 32, + PKSIZE, + UnSigned, + MMBased, + NotNullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + // Create third column, primary key + check = MySchemaOp->createAttribute( "IPADDR", + TupleKey, + 32, + PKSIZE, + String, + MMBased, + NotNullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + + +// Create Acct session id 4 byte unsigned + check = MySchemaOp->createAttribute( "ASID", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + +// Create Correlation ID, 4 byte unsigned + check = MySchemaOp->createAttribute( "CID", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + +// Create MIP HA Address, 4 byte unsigned + check = MySchemaOp->createAttribute( "MIPHA", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + + + +// Create IP technology, 4 byte unsigned + check = MySchemaOp->createAttribute( "IPT", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + +// Create Compuls Tunnel ID, 4 byte unsigned + check = MySchemaOp->createAttribute( "CTID", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + +// Create IP QOS, 4 byte unsigned + check = MySchemaOp->createAttribute( "IPQOS", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + // Create Data octet count in, 4 byte unsigned + check = MySchemaOp->createAttribute( "DOCI", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + // Create Data octet count out, 4 byte unsigned + check = MySchemaOp->createAttribute( "DOCO", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + // Create Event time, 4 byte unsigned + check = MySchemaOp->createAttribute( "ET", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + // Create In mip sig count, 4 byte unsigned + check = MySchemaOp->createAttribute( "IMSC", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + +// Create Out mip sig count, 4 byte unsigned + check = MySchemaOp->createAttribute( "OMSC", + NoKey, + 32, + 1, + UnSigned, + MMBased, + NullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + if( (MySchemaTransaction->execute() == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + pMyNdb->closeSchemaTransaction(MySchemaTransaction); + ndbout << "done" << endl; + + + + } //if + + //else table already created , proceed +} + + +static void +createTable_TODACCT(Ndb* pMyNdb) +{ + + + /**************************************************************** + * Create table and attributes. + * + * create table TODACCT( + * for attribs, see the REQ SPEC for cello session DB + * ) + * + ***************************************************************/ + + const char* tname = "TODACCT"; + Uint32 recordsize = 92; //including 12 byte overhead + Uint32 pksize = 12; //size of total prim. key. in bytes. + Uint32 tTableId = pMyNdb->getTable()->openTable(tname); + + if (tTableId == -1) { + Uint32 check; + Uint32 i; + NdbSchemaCon *MySchemaTransaction; + NdbSchemaOp *MySchemaOp; + + ndbout << "Creating " << tname << "..." << endl; + + MySchemaTransaction = pMyNdb->startSchemaTransaction(); + if( MySchemaTransaction == NULL ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); + if( MySchemaOp == NULL ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + // Createtable + + Uint32 tablesize=(recordsize*NUMBEROFRECORDS + OVERHEAD * NUMBEROFRECORDS)/1024; + Uint32 noPages=(pksize*NUMBEROFRECORDS)/PAGESIZE; + + ndbout << "table size " << tablesize << "for table name " << tname << endl; + + check = MySchemaOp->createTable( tname, + tablesize, // Table Size + TupleKey, // Key Type + noPages // Nr of Pages + ); + + if( check == -1 ) + error_handler(MySchemaTransaction->getNdbErrorString()); + + + + // Create first column, primary key + check = MySchemaOp->createAttribute( "SPBBOARDID", + TupleKey, + 32, + PKSIZE, + UnSigned, + MMBased, + NotNullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + // Create second column, primary key + check = MySchemaOp->createAttribute( "CALLID", + TupleKey, + 32, + PKSIZE, + UnSigned, + MMBased, + NotNullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + // Create third column, primary key + check = MySchemaOp->createAttribute( "IPADDR", + TupleKey, + 32, + PKSIZE, + String, + MMBased, + NotNullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + + // Create third column, primary key + check = MySchemaOp->createAttribute( "INDEX", + TupleKey, + 32, + PKSIZE, + UnSigned, + MMBased, + NotNullAttribute ); + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + + +// Create Acct session id 4 byte unsigned + check = MySchemaOp->createAttribute( "TOD", + NoKey, + 32, + 16, + String, + MMBased, + NullAttribute ); + + + if( (check == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + + + if( (MySchemaTransaction->execute() == -1) && (!error_handler2((const char*)MySchemaTransaction->getNdbErrorString(), MySchemaTransaction->getNdbError())) ) + exit (-1) ; + + pMyNdb->closeSchemaTransaction(MySchemaTransaction); + ndbout << "done" << endl; + + } //if + + //else table already created , proceed +} + + + + + + +static void read_IPACCT(Ndb* pMyNdb, Uint32 CALLID, Uint32 SPBBOARDID , Uint32 IPADDR) +{ + + + int check; + int loop_count_ops; + int count; + int count_attributes; + char* value; + NdbConnection *MyTransaction; + NdbOperation *MyOperation; + NdbRecAttr* tTmp; + + + + MyTransaction = pMyNdb->startTransaction(); + if (MyTransaction == NULL) + error_handler(pMyNdb->getNdbErrorString()); + + MyOperation = MyTransaction->getNdbOperation("IPACCT"); + if (MyOperation == NULL) + error_handler( MyTransaction->getNdbErrorString()); + + check = MyOperation->readTuple(); + if( check == -1 ) + error_handler( MyTransaction->getNdbErrorString()); + + check = MyOperation->equal( "SPBBOARDID",SPBBOARDID ); + if( check == -1 ) + error_handler( MyTransaction->getNdbErrorString()); + + + check = MyOperation->equal( "IPADDR","IPADDR" ); + if( check == -1 ) + error_handler( MyTransaction->getNdbErrorString()); + + + check = MyOperation->equal( "CALLID",CALLID ); + if( check == -1 ) + error_handler( MyTransaction->getNdbErrorString()); + + + + + tTmp = MyOperation->getValue("IPQOS", NULL ); + if( tTmp == NULL ) + error_handler( MyTransaction->getNdbErrorString()); + ndbout << " tTmp " << tTmp->isNULL() << endl; + MyTransaction->execute(Commit); + + ndbout << " value read " << tTmp->int32_value() << endl; + +} + + + +static void insert_IPACCT(Ndb* pMyNdb, Uint32 CALLID, Uint32 SPBBOARDID , Uint32 IPADDR, Uint32 ASID, Uint32 IPQOS) +{ + /**************************************************************** + * Insert rows + * + ***************************************************************/ + + int check; + int loop_count_ops; + int count; + int i; + NdbConnection *MyTransaction; + NdbOperation *MyOperation; + + ndbout << "Inserting records..." << flush; + + MyTransaction = pMyNdb->startTransaction(); + if (MyTransaction == NULL) + error_handler(pMyNdb->getNdbErrorString()); + + MyOperation = MyTransaction->getNdbOperation("IPACCT"); + if (MyOperation == NULL) + error_handler(MyTransaction->getNdbErrorString()); + + + + check = MyOperation->insertTuple(); + if( check == -1 ) + error_handler(MyTransaction->getNdbErrorString()); + + ndbout << "insertTuple" << endl; + + check = MyOperation->equal("CALLID",CALLID ); + if( check == -1 ) + error_handler(MyTransaction->getNdbErrorString()); + ndbout << "equal" << endl; + + + check = MyOperation->equal("SPBBOARDID",SPBBOARDID ); + if( check == -1 ) + error_handler(MyTransaction->getNdbErrorString()); + ndbout << "equal" << endl; + + + check = MyOperation->equal("IPADDR","IPADDR" ); + if( check == -1 ) + error_handler(MyTransaction->getNdbErrorString()); + ndbout << "equal" << endl; + + + check = MyOperation->setValue( "IPQOS", IPQOS); + if( check == -1 ) + error_handler(MyTransaction->getNdbErrorString()); + ndbout << "Set Value" << endl; + + + + check = MyOperation->setValue( "ASID", ASID); + if( check == -1 ) + error_handler(MyTransaction->getNdbErrorString()); + ndbout << "Set Value" << endl; + + + check = MyTransaction->execute( Commit ); + if(check == -1 ) { + ndbout << "error at commit" << endl; + error_handler(MyTransaction->getNdbErrorString()); + } + else + ;//ndbout << "."; + + pMyNdb->closeTransaction(MyTransaction); + + + + ndbout << "OK" << endl; + + return; +} + +static void +update_rows(Ndb* pMyNdb){ + /**************************************************************** + * Update rows in SimpleTable + * + ***************************************************************/ + + int check; + int loop_count_ops; + int count; + int i; + NdbConnection *MyTransaction; + NdbOperation *MyOperation; + + ndbout << "Updating records..." << flush; + + loop_count_ops = NUMBEROFRECORDS; + + for (count=0 ; count < loop_count_ops ; count++) { + + MyTransaction = pMyNdb->startTransaction(); + if (MyTransaction == NULL) + error_handler( pMyNdb->getNdbErrorString() ); + + MyOperation = MyTransaction->getNdbOperation(tableName[0]); + if (MyOperation == NULL) + error_handler(MyTransaction->getNdbErrorString()); + + check = MyOperation->updateTuple(); + if( check == -1 ) + error_handler(MyTransaction->getNdbErrorString()); + + check = MyOperation->equal( attrName[0], (char*)&pkValue[count] ); + if( check == -1 ) + error_handler(MyTransaction->getNdbErrorString()); + + for (i = 1; i < MAXATTR; i++) + { + check = MyOperation->setValue( attrName[i], (char*)&attrValue[count]); + if( check == -1 ) + error_handler(MyTransaction->getNdbErrorString()); + } + + if( MyTransaction->execute( Commit ) == -1 ) + error_handler(MyTransaction->getNdbErrorString()); + else + ;//ndbout << "."; + + pMyNdb->closeTransaction(MyTransaction); + + } + + ndbout << "OK" << endl; + return; + +}; + +static void +delete_rows(Ndb* pMyNdb){ + + /**************************************************************** + * Delete rows from SimpleTable + * + ***************************************************************/ + + int check; + int loop_count_ops; + int count; + NdbConnection *MyTransaction; + NdbOperation *MyOperation; + + ndbout << "Deleting records..."<< flush; + + loop_count_ops = NUMBEROFRECORDS; + + for (count=0 ; count < loop_count_ops ; count++) { + + MyTransaction = pMyNdb->startTransaction(); + if (MyTransaction == NULL) + error_handler( pMyNdb->getNdbErrorString() ); + + MyOperation = MyTransaction->getNdbOperation(tableName[0]); + if (MyOperation == NULL) + error_handler(MyTransaction->getNdbErrorString()); + + + check = MyOperation->deleteTuple(); + if( check == -1 ) + error_handler(MyTransaction->getNdbErrorString()); + + check = MyOperation->equal( attrName[0], (char*)&pkValue[count] ); + if( check == -1 ) + error_handler(MyTransaction->getNdbErrorString()); + + + if( MyTransaction->execute( Commit ) == -1 ) + error_handler(MyTransaction->getNdbErrorString()); + else + ;// ndbout << "."; + + pMyNdb->closeTransaction(MyTransaction); + + } + + ndbout << "OK" << endl; + return; + +}; + +static void +verify_deleted(Ndb* pMyNdb){ + int check; + int loop_count_ops; + int count; + NdbConnection *MyTransaction; + NdbOperation *MyOperation; + + ndbout << "Verifying deleted records..."<< flush; + + loop_count_ops = NUMBEROFRECORDS; + + for (count=0 ; count < loop_count_ops ; count++) + { + MyTransaction = pMyNdb->startTransaction(); + if (MyTransaction == NULL) + error_handler(pMyNdb->getNdbErrorString()); + + MyOperation = MyTransaction->getNdbOperation(tableName[0]); + if (MyOperation == NULL) + error_handler( MyTransaction->getNdbErrorString()); + + check = MyOperation->readTuple(); + if( check == -1 ) + error_handler( MyTransaction->getNdbErrorString()); + + check = MyOperation->equal( attrName[0],(char*)&pkValue[count] ); + if( check == -1 ) + error_handler( MyTransaction->getNdbErrorString()); + + // Exepect to receive an error + if( MyTransaction->execute( Commit ) != -1 ) + error_handler(MyTransaction->getNdbErrorString()); + else + { + ;//ndbout << "."; + } + + pMyNdb->closeTransaction(MyTransaction); + + } + + ndbout << "OK" << endl; + return; +}; + +static void +read_and_verify_rows(Ndb* pMyNdb) +{ + + int check; + int loop_count_ops; + int count; + int count_attributes; + + NdbConnection *MyTransaction; + NdbOperation *MyOperation; + NdbRecAttr* tTmp; + + int readValue[MAXATTR]; + + ndbout << "Verifying records..."<< flush; + + loop_count_ops = NUMBEROFRECORDS; + + for (count=0 ; count < loop_count_ops ; count++) + { + MyTransaction = pMyNdb->startTransaction(); + if (MyTransaction == NULL) + error_handler(pMyNdb->getNdbErrorString()); + + MyOperation = MyTransaction->getNdbOperation(tableName[0]); + if (MyOperation == NULL) + error_handler( MyTransaction->getNdbErrorString()); + + check = MyOperation->readTuple(); + if( check == -1 ) + error_handler( MyTransaction->getNdbErrorString()); + + check = MyOperation->equal( attrName[0],(char*)&pkValue[count] ); + if( check == -1 ) + error_handler( MyTransaction->getNdbErrorString()); + + for (count_attributes = 1; count_attributes < MAXATTR; count_attributes++) + { + tTmp = MyOperation->getValue( (char*)attrName[count_attributes], (char*)&readValue[count_attributes] ); + if( tTmp == NULL ) + error_handler( MyTransaction->getNdbErrorString()); + } + + if( MyTransaction->execute( Commit ) == -1 ) + error_handler(MyTransaction->getNdbErrorString()); + else + { + // Check value in db against value in mem + + //ndbout << readValue[1] << " == " << attrValue[count] << endl; + + if ( readValue[1]!=attrValue[count] ) + error_handler("Verification error!"); + else + if ( readValue[2]!=attrValue[count] ) + error_handler("Verification error!"); + else + if ( readValue[3]!=attrValue[count] ) + error_handler("Verification error!"); + else + { + ;//ndbout << "."; + } + } + pMyNdb->closeTransaction(MyTransaction); + + } + + ndbout << "OK" << endl; + return; + + + +}; + + +static void +setAttrNames() +{ + int i; + + for (i = 0; i < MAXATTR ; i++) + { + sprintf(&attrName[i][0], "Col%d", i); + } +} + +static void +setTableNames() +{ + int i; + + sprintf(&tableName[0][0], "SBMCALL", 0); + sprintf(&tableName[1][0], "RPACCT", 0); + sprintf(&tableName[2][0], "IPACCT", 0); + sprintf(&tableName[3][0], "TODACCT", 0); + +} + + +bool error_handler2(const char* error_string, int error_int) { + failed++ ; + ndbout << error_string << endl ; + if ( 4008==error_int || 721==error_int || 266==error_int ){ + ndbout << endl << "Attempting to recover and continue now..." << endl ; + return true ; // return true to retry + } + return false ; // return false to abort +} diff --git a/ndb/test/ndbapi/create_all_tabs.cpp b/ndb/test/ndbapi/create_all_tabs.cpp new file mode 100644 index 00000000000..55d04888144 --- /dev/null +++ b/ndb/test/ndbapi/create_all_tabs.cpp @@ -0,0 +1,63 @@ +/* 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 */ + +#include + +#include +#include +#include + +#include + + + +int main(int argc, const char** argv){ + + int _temp = false; + int _help = 0; + + struct getargs args[] = { + { "temp", 't', arg_flag, &_temp, "Temporary table", "temp" }, + { "usage", '?', arg_flag, &_help, "Print help", "" } + }; + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + char desc[] = + "This program will create all standard tables in Ndb.\n"\ + "The tables is selected from a fixed list of tables\n"\ + "defined in NDBT_Tables class\n"; + + if(getarg(args, num_args, argc, argv, &optind) || _help) { + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + + // Connect to Ndb + Ndb MyNdb( "TEST_DB" ); + + if(MyNdb.init() != 0){ + ERR(MyNdb.getNdbError()); + return NDBT_ProgramExit(NDBT_FAILED); + } + + while(MyNdb.waitUntilReady() != 0) + ndbout << "Waiting for ndb to become ready..." << endl; + + return NDBT_Tables::createAllTables(&MyNdb, _temp); + + } + + diff --git a/ndb/test/ndbapi/create_all_tabs/Makefile b/ndb/test/ndbapi/create_all_tabs/Makefile deleted file mode 100644 index 58309807682..00000000000 --- a/ndb/test/ndbapi/create_all_tabs/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := create_all_tabs - -# Source files of non-templated classes (.C files) -SOURCES = create_all_tabs.cpp - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/test/ndbapi/create_all_tabs/create_all_tabs.cpp b/ndb/test/ndbapi/create_all_tabs/create_all_tabs.cpp deleted file mode 100644 index 55d04888144..00000000000 --- a/ndb/test/ndbapi/create_all_tabs/create_all_tabs.cpp +++ /dev/null @@ -1,63 +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 */ - -#include - -#include -#include -#include - -#include - - - -int main(int argc, const char** argv){ - - int _temp = false; - int _help = 0; - - struct getargs args[] = { - { "temp", 't', arg_flag, &_temp, "Temporary table", "temp" }, - { "usage", '?', arg_flag, &_help, "Print help", "" } - }; - int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; - char desc[] = - "This program will create all standard tables in Ndb.\n"\ - "The tables is selected from a fixed list of tables\n"\ - "defined in NDBT_Tables class\n"; - - if(getarg(args, num_args, argc, argv, &optind) || _help) { - arg_printusage(args, num_args, argv[0], desc); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - - // Connect to Ndb - Ndb MyNdb( "TEST_DB" ); - - if(MyNdb.init() != 0){ - ERR(MyNdb.getNdbError()); - return NDBT_ProgramExit(NDBT_FAILED); - } - - while(MyNdb.waitUntilReady() != 0) - ndbout << "Waiting for ndb to become ready..." << endl; - - return NDBT_Tables::createAllTables(&MyNdb, _temp); - - } - - diff --git a/ndb/test/ndbapi/create_tab.cpp b/ndb/test/ndbapi/create_tab.cpp new file mode 100644 index 00000000000..8bb1e7a9572 --- /dev/null +++ b/ndb/test/ndbapi/create_tab.cpp @@ -0,0 +1,107 @@ +/* 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 */ + +#include + +#include +#include +#include + +#include + + + +int main(int argc, const char** argv){ + + int _temp = false; + int _help = 0; + int _all = 0; + int _print = 0; + const char* _connectstr = NULL; + + struct getargs args[] = { + { "all", 'a', arg_flag, &_all, "Create/print all tables" }, + { "print", 'p', arg_flag, &_print, "Print table(s) instead of creating it"}, + { "temp", 't', arg_flag, &_temp, "Temporary table", "temp" }, + { "connstr", 'c', arg_string, &_connectstr, "connect string", + "How to connect to NDB"}, + { "usage", '?', arg_flag, &_help, "Print help", "" } + }; + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + char desc[] = + "tabname\n"\ + "This program will create one table in Ndb.\n"\ + "The tables may be selected from a fixed list of tables\n"\ + "defined in NDBT_Tables class\n"; + + if(getarg(args, num_args, argc, argv, &optind) || _help){ + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + + if(argv[optind] == NULL && !_all){ + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + + int res = 0; + if(_print){ + /** + * Print instead of creating + */ + if(argv[optind] != NULL){ + for(int i = optind; i - -#include -#include -#include - -#include - - - -int main(int argc, const char** argv){ - - int _temp = false; - int _help = 0; - int _all = 0; - int _print = 0; - const char* _connectstr = NULL; - - struct getargs args[] = { - { "all", 'a', arg_flag, &_all, "Create/print all tables" }, - { "print", 'p', arg_flag, &_print, "Print table(s) instead of creating it"}, - { "temp", 't', arg_flag, &_temp, "Temporary table", "temp" }, - { "connstr", 'c', arg_string, &_connectstr, "connect string", - "How to connect to NDB"}, - { "usage", '?', arg_flag, &_help, "Print help", "" } - }; - int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; - char desc[] = - "tabname\n"\ - "This program will create one table in Ndb.\n"\ - "The tables may be selected from a fixed list of tables\n"\ - "defined in NDBT_Tables class\n"; - - if(getarg(args, num_args, argc, argv, &optind) || _help){ - arg_printusage(args, num_args, argv[0], desc); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - - if(argv[optind] == NULL && !_all){ - arg_printusage(args, num_args, argv[0], desc); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - - int res = 0; - if(_print){ - /** - * Print instead of creating - */ - if(argv[optind] != NULL){ - for(int i = optind; i + +#include +#include +#include + +#include + +int main(int argc, const char** argv){ + + int _help = 0; + struct getargs args[] = { + { "usage", '?', arg_flag, &_help, "Print help", "" } + }; + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + char desc[] = + "This program will drop all Ndb standard tables from NDB\n"; + + if(getarg(args, num_args, argc, argv, &optind) || _help) { + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + + // Connect to Ndb + Ndb MyNdb( "TEST_DB" ); + + if(MyNdb.init() != 0){ + ERR(MyNdb.getNdbError()); + return NDBT_ProgramExit(NDBT_FAILED); + } + + while(MyNdb.waitUntilReady() != 0) + ndbout << "Waiting for ndb to become ready..." << endl; + + return NDBT_Tables::dropAllTables(&MyNdb); + + } + + diff --git a/ndb/test/ndbapi/drop_all_tabs/Makefile b/ndb/test/ndbapi/drop_all_tabs/Makefile deleted file mode 100644 index 96db0781417..00000000000 --- a/ndb/test/ndbapi/drop_all_tabs/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := drop_all_tabs - -# Source files of non-templated classes (.C files) -SOURCES = drop_all_tabs.cpp - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/test/ndbapi/drop_all_tabs/drop_all_tabs.cpp b/ndb/test/ndbapi/drop_all_tabs/drop_all_tabs.cpp deleted file mode 100644 index 59c57396acd..00000000000 --- a/ndb/test/ndbapi/drop_all_tabs/drop_all_tabs.cpp +++ /dev/null @@ -1,56 +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 */ - -#include - -#include -#include -#include - -#include - -int main(int argc, const char** argv){ - - int _help = 0; - struct getargs args[] = { - { "usage", '?', arg_flag, &_help, "Print help", "" } - }; - int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; - char desc[] = - "This program will drop all Ndb standard tables from NDB\n"; - - if(getarg(args, num_args, argc, argv, &optind) || _help) { - arg_printusage(args, num_args, argv[0], desc); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - - // Connect to Ndb - Ndb MyNdb( "TEST_DB" ); - - if(MyNdb.init() != 0){ - ERR(MyNdb.getNdbError()); - return NDBT_ProgramExit(NDBT_FAILED); - } - - while(MyNdb.waitUntilReady() != 0) - ndbout << "Waiting for ndb to become ready..." << endl; - - return NDBT_Tables::dropAllTables(&MyNdb); - - } - - diff --git a/ndb/test/ndbapi/flexAsynch.cpp b/ndb/test/ndbapi/flexAsynch.cpp new file mode 100644 index 00000000000..0822f3ee999 --- /dev/null +++ b/ndb/test/ndbapi/flexAsynch.cpp @@ -0,0 +1,982 @@ +/* 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 */ + + +#include "NdbApi.hpp" +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#define MAX_PARTS 4 +#define MAX_SEEK 16 +#define MAXSTRLEN 16 +#define MAXATTR 64 +#define MAXTABLES 64 +#define MAXTHREADS 128 +#define MAXPAR 1024 +#define MAXATTRSIZE 1000 +#define PKSIZE 2 + +enum StartType { + stIdle, + stInsert, + stRead, + stUpdate, + stDelete, + stStop +} ; + +extern "C" { static void* threadLoop(void*); } +static void setAttrNames(void); +static void setTableNames(void); +static int readArguments(int argc, const char** argv); +static int createTables(Ndb*); +static void defineOperation(NdbConnection* aTransObject, StartType aType, + Uint32 base, Uint32 aIndex); +static void execute(StartType aType); +static bool executeThread(StartType aType, Ndb* aNdbObject, unsigned int); +static void executeCallback(int result, NdbConnection* NdbObject, + void* aObject); +static bool error_handler(const NdbError & err); +static Uint32 getKey(Uint32, Uint32) ; +static void input_error(); + + +static int retry_opt = 3 ; +static int failed = 0 ; + +ErrorData * flexAsynchErrorData; + +struct ThreadNdb +{ + int NoOfOps; + int ThreadNo; +}; + +static NdbThread* threadLife[MAXTHREADS]; +static int tNodeId; +static int ThreadReady[MAXTHREADS]; +static StartType ThreadStart[MAXTHREADS]; +static char tableName[MAXTABLES][MAXSTRLEN+1]; +static char attrName[MAXATTR][MAXSTRLEN+1]; + +// Program Parameters +static bool tLocal = false; +static int tLocalPart = 0; +static int tSendForce = 0; +static int tNoOfLoops = 1; +static int tAttributeSize = 1; +static unsigned int tNoOfThreads = 1; +static unsigned int tNoOfParallelTrans = 32; +static unsigned int tNoOfAttributes = 25; +static unsigned int tNoOfTransactions = 500; +static unsigned int tNoOfOpsPerTrans = 1; +static unsigned int tLoadFactor = 80; +static bool tempTable = false; +static bool startTransGuess = true; + +//Program Flags +static int theTestFlag = 0; +static int theSimpleFlag = 0; +static int theDirtyFlag = 0; +static int theWriteFlag = 0; +static int theStdTableNameFlag = 0; +static int theTableCreateFlag = 0; + +#define START_REAL_TIME +#define STOP_REAL_TIME +#define START_TIMER { NdbTimer timer; timer.doStart(); +#define STOP_TIMER timer.doStop(); +#define PRINT_TIMER(text, trans, opertrans) timer.printTransactionStatistics(text, trans, opertrans); }; + +static void +resetThreads(){ + + for (int i = 0; i < tNoOfThreads ; i++) { + ThreadReady[i] = 0; + ThreadStart[i] = stIdle; + }//for +} + +static void +waitForThreads(void) +{ + int cont = 0; + do { + cont = 0; + NdbSleep_MilliSleep(20); + for (int i = 0; i < tNoOfThreads ; i++) { + if (ThreadReady[i] == 0) { + cont = 1; + }//if + }//for + } while (cont == 1); +} + +static void +tellThreads(StartType what) +{ + for (int i = 0; i < tNoOfThreads ; i++) + ThreadStart[i] = what; +} + +NDB_COMMAND(flexAsynch, "flexAsynch", "flexAsynch", "flexAsynch", 65535) +{ + ThreadNdb* pThreadData; + int tLoops=0; + int returnValue = NDBT_OK; + + flexAsynchErrorData = new ErrorData; + flexAsynchErrorData->resetErrorCounters(); + + if (readArguments(argc, argv) != 0){ + input_error(); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + + pThreadData = new ThreadNdb[MAXTHREADS]; + + ndbout << endl << "FLEXASYNCH - Starting normal mode" << endl; + ndbout << "Perform benchmark of insert, update and delete transactions"; + ndbout << endl; + ndbout << " " << tNoOfThreads << " number of concurrent threads " << endl; + ndbout << " " << tNoOfParallelTrans; + ndbout << " number of parallel operation per thread " << endl; + ndbout << " " << tNoOfTransactions << " transaction(s) per round " << endl; + ndbout << " " << tNoOfLoops << " iterations " << endl; + ndbout << " " << "Load Factor is " << tLoadFactor << "%" << endl; + ndbout << " " << tNoOfAttributes << " attributes per table " << endl; + ndbout << " " << tAttributeSize; + ndbout << " is the number of 32 bit words per attribute " << endl; + if (tempTable == true) { + ndbout << " Tables are without logging " << endl; + } else { + ndbout << " Tables are with logging " << endl; + }//if + if (startTransGuess == true) { + ndbout << " Transactions are executed with hint provided" << endl; + } else { + ndbout << " Transactions are executed with round robin scheme" << endl; + }//if + if (tSendForce == 0) { + ndbout << " No force send is used, adaptive algorithm used" << endl; + } else if (tSendForce == 1) { + ndbout << " Force send used" << endl; + } else { + ndbout << " No force send is used, adaptive algorithm disabled" << endl; + }//if + + ndbout << endl; + + NdbThread_SetConcurrencyLevel(2 + tNoOfThreads); + + /* print Setting */ + flexAsynchErrorData->printSettings(ndbout); + + setAttrNames(); + setTableNames(); + + Ndb * pNdb = new Ndb("TEST_DB"); + pNdb->init(); + tNodeId = pNdb->getNodeId(); + + ndbout << " NdbAPI node with id = " << pNdb->getNodeId() << endl; + ndbout << endl; + + ndbout << "Waiting for ndb to become ready..." <waitUntilReady(10000) != 0){ + ndbout << "NDB is not ready" << endl; + ndbout << "Benchmark failed!" << endl; + returnValue = NDBT_FAILED; + } + + if(returnValue == NDBT_OK){ + if (createTables(pNdb) != 0){ + returnValue = NDBT_FAILED; + } + } + + if(returnValue == NDBT_OK){ + /**************************************************************** + * Create NDB objects. * + ****************************************************************/ + resetThreads(); + for (int i = 0; i < tNoOfThreads ; i++) { + pThreadData[i].ThreadNo = i +; + threadLife[i] = NdbThread_Create(threadLoop, + (void**)&pThreadData[i], + 32768, + "flexAsynchThread", + NDB_THREAD_PRIO_LOW); + }//for + ndbout << endl << "All NDB objects and table created" << endl << endl; + int noOfTransacts = tNoOfParallelTrans*tNoOfTransactions*tNoOfThreads; + /**************************************************************** + * Execute program. * + ****************************************************************/ + + for(;;) { + + int loopCount = tLoops + 1 ; + ndbout << endl << "Loop # " << loopCount << endl << endl ; + + /**************************************************************** + * Perform inserts. * + ****************************************************************/ + + failed = 0 ; + + START_TIMER; + execute(stInsert); + STOP_TIMER; + PRINT_TIMER("insert", noOfTransacts, tNoOfOpsPerTrans); + + if (0 < failed) { + int i = retry_opt ; + int ci = 1 ; + while (0 < failed && 0 < i){ + ndbout << failed << " of the transactions returned errors!" + << endl << endl; + ndbout << "Attempting to redo the failed transactions now..." + << endl ; + ndbout << "Redo attempt " << ci <<" out of " << retry_opt + << endl << endl; + failed = 0 ; + START_TIMER; + execute(stInsert); + STOP_TIMER; + PRINT_TIMER("insert", noOfTransacts, tNoOfOpsPerTrans); + i-- ; + ci++; + } + if(0 == failed ){ + ndbout << endl <<"Redo attempt succeeded" << endl << endl; + }else{ + ndbout << endl <<"Redo attempt failed, moving on now..." << endl + << endl; + }//if + }//if + + /**************************************************************** + * Perform read. * + ****************************************************************/ + + failed = 0 ; + + START_TIMER; + execute(stRead); + STOP_TIMER; + PRINT_TIMER("read", noOfTransacts, tNoOfOpsPerTrans); + + if (0 < failed) { + int i = retry_opt ; + int cr = 1; + while (0 < failed && 0 < i){ + ndbout << failed << " of the transactions returned errors!"<printErrorCounters(ndbout); + + return NDBT_ProgramExit(returnValue); +}//main() + + +static void execute(StartType aType) +{ + resetThreads(); + tellThreads(aType); + waitForThreads(); +}//execute() + +static void* +threadLoop(void* ThreadData) +{ + Ndb* localNdb; + StartType tType; + ThreadNdb* tabThread = (ThreadNdb*)ThreadData; + int threadNo = tabThread->ThreadNo; + localNdb = new Ndb("TEST_DB"); + localNdb->init(1024); + localNdb->waitUntilReady(10000); + unsigned int threadBase = (threadNo << 16) + tNodeId ; + + for (;;){ + while (ThreadStart[threadNo] == stIdle) { + NdbSleep_MilliSleep(10); + }//while + + // Check if signal to exit is received + if (ThreadStart[threadNo] == stStop) { + break; + }//if + + tType = ThreadStart[threadNo]; + ThreadStart[threadNo] = stIdle; + if(!executeThread(tType, localNdb, threadBase)){ + break; + } + ThreadReady[threadNo] = 1; + }//for + + delete localNdb; + ThreadReady[threadNo] = 1; + + NdbThread_Exit(0); + return NULL; // Just to keep compiler happy +}//threadLoop() + +static +bool +executeThread(StartType aType, Ndb* aNdbObject, unsigned int threadBase) { + int i, j, k; + NdbConnection* tConArray[1024]; + unsigned int tBase; + unsigned int tBase2; + + for (i = 0; i < tNoOfTransactions; i++) { + if (tLocal == false) { + tBase = i * tNoOfParallelTrans * tNoOfOpsPerTrans; + } else { + tBase = i * tNoOfParallelTrans * MAX_SEEK; + }//if + START_REAL_TIME; + for (j = 0; j < tNoOfParallelTrans; j++) { + if (tLocal == false) { + tBase2 = tBase + (j * tNoOfOpsPerTrans); + } else { + tBase2 = tBase + (j * MAX_SEEK); + tBase2 = getKey(threadBase, tBase2); + }//if + if (startTransGuess == true) { + Uint64 Tkey64; + Uint32* Tkey32 = (Uint32*)&Tkey64; + Tkey32[0] = threadBase; + Tkey32[1] = tBase2; + tConArray[j] = aNdbObject->startTransaction((Uint32)0, //Priority + (const char*)&Tkey64, //Main PKey + (Uint32)4); //Key Length + } else { + tConArray[j] = aNdbObject->startTransaction(); + }//if + if (tConArray[j] == NULL && + !error_handler(aNdbObject->getNdbError()) ){ + ndbout << endl << "Unable to recover! Quiting now" << endl ; + return false; + }//if + + for (k = 0; k < tNoOfOpsPerTrans; k++) { + //------------------------------------------------------- + // Define the operation, but do not execute it yet. + //------------------------------------------------------- + defineOperation(tConArray[j], aType, threadBase, (tBase2 + k)); + }//for + + tConArray[j]->executeAsynchPrepare(Commit, &executeCallback, NULL); + }//for + STOP_REAL_TIME; + //------------------------------------------------------- + // Now we have defined a set of operations, it is now time + // to execute all of them. + //------------------------------------------------------- + int Tcomp = aNdbObject->sendPollNdb(3000, 0, 0); + while (Tcomp < tNoOfParallelTrans) { + int TlocalComp = aNdbObject->pollNdb(3000, 0); + Tcomp += TlocalComp; + }//while + for (j = 0 ; j < tNoOfParallelTrans ; j++) { + aNdbObject->closeTransaction(tConArray[j]); + }//for + }//for + return true; +}//executeThread() + +static +Uint32 +getKey(Uint32 aBase, Uint32 anIndex) { + Uint32 Tfound = anIndex; + Uint64 Tkey64; + Uint32* Tkey32 = (Uint32*)&Tkey64; + Tkey32[0] = aBase; + Uint32 hash; + for (Uint32 i = anIndex; i < (anIndex + MAX_SEEK); i++) { + Tkey32[1] = (Uint32)i; + hash = md5_hash((Uint64*)&Tkey64, (Uint32)2); + hash = (hash >> 6) & (MAX_PARTS - 1); + if (hash == tLocalPart) { + Tfound = i; + break; + }//if + }//for + return Tfound; +}//getKey() + +static void +executeCallback(int result, NdbConnection* NdbObject, void* aObject) +{ + if (result == -1) { + + // Add complete error handling here + + int retCode = flexAsynchErrorData->handleErrorCommon(NdbObject->getNdbError()); + if (retCode == 1) { + if (NdbObject->getNdbError().code != 626 && NdbObject->getNdbError().code != 630){ + ndbout_c("execute: %s", NdbObject->getNdbError().message); + ndbout_c("Error code = %d", NdbObject->getNdbError().code);} + } else if (retCode == 2) { + ndbout << "4115 should not happen in flexAsynch" << endl; + } else if (retCode == 3) { + /* What can we do here? */ + ndbout_c("execute: %s", NdbObject->getNdbError().message); + }//if(retCode == 3) + + // ndbout << "Error occured in poll:" << endl; + // ndbout << NdbObject->getNdbError() << endl; + failed++ ; + return; + }//if + return; +}//executeCallback() + + + +static void +defineOperation(NdbConnection* localNdbConnection, StartType aType, + Uint32 threadBase, Uint32 aIndex) +{ + NdbOperation* localNdbOperation; + unsigned int loopCountAttributes = tNoOfAttributes; + unsigned int countAttributes; + Uint32 attrValue[MAXATTRSIZE]; + + //------------------------------------------------------- + // Set-up the attribute values for this operation. + //------------------------------------------------------- + attrValue[0] = threadBase; + attrValue[1] = aIndex; + for (int k = 2; k < loopCountAttributes; k++) { + attrValue[k] = aIndex; + }//for + localNdbOperation = localNdbConnection->getNdbOperation(tableName[0]); + if (localNdbOperation == NULL) { + error_handler(localNdbConnection->getNdbError()); + }//if + switch (aType) { + case stInsert: { // Insert case + if (theWriteFlag == 1 && theDirtyFlag == 1) { + localNdbOperation->dirtyWrite(); + } else if (theWriteFlag == 1) { + localNdbOperation->writeTuple(); + } else { + localNdbOperation->insertTuple(); + }//if + break; + }//case + case stRead: { // Read Case + if (theSimpleFlag == 1) { + localNdbOperation->simpleRead(); + } else if (theDirtyFlag == 1) { + localNdbOperation->dirtyRead(); + } else { + localNdbOperation->readTuple(); + }//if + break; + }//case + case stUpdate: { // Update Case + if (theWriteFlag == 1 && theDirtyFlag == 1) { + localNdbOperation->dirtyWrite(); + } else if (theWriteFlag == 1) { + localNdbOperation->writeTuple(); + } else if (theDirtyFlag == 1) { + localNdbOperation->dirtyUpdate(); + } else { + localNdbOperation->updateTuple(); + }//if + break; + }//case + case stDelete: { // Delete Case + localNdbOperation->deleteTuple(); + break; + }//case + default: { + error_handler(localNdbOperation->getNdbError()); + }//default + }//switch + localNdbOperation->equal((Uint32)0,(char*)&attrValue[0]); + switch (aType) { + case stInsert: // Insert case + case stUpdate: // Update Case + { + for (countAttributes = 1; + countAttributes < loopCountAttributes; countAttributes++) { + localNdbOperation->setValue(countAttributes, + (char*)&attrValue[0]); + }//for + break; + }//case + case stRead: { // Read Case + for (countAttributes = 1; + countAttributes < loopCountAttributes; countAttributes++) { + localNdbOperation->getValue(countAttributes, + (char*)&attrValue[0]); + }//for + break; + }//case + case stDelete: { // Delete Case + break; + }//case + default: { + //goto error_handler; < epaulsa + error_handler(localNdbOperation->getNdbError()); + }//default + }//switch + return; +}//defineOperation() + +static void setAttrNames() +{ + int i; + + for (i = 0; i < MAXATTR ; i++){ + snprintf(attrName[i], MAXSTRLEN, "COL%d", i); + } +} + + +static void setTableNames() +{ + // Note! Uses only uppercase letters in table name's + // so that we can look at the tables wits SQL + int i; + for (i = 0; i < MAXTABLES ; i++){ + if (theStdTableNameFlag==0){ + snprintf(tableName[i], MAXSTRLEN, "TAB%d_%d", i, + (int)(NdbTick_CurrentMillisecond()/1000)); + } else { + snprintf(tableName[i], MAXSTRLEN, "TAB%d", i); + } + } +} + +static +int +createTables(Ndb* pMyNdb){ + + NdbSchemaCon *MySchemaTransaction; + NdbSchemaOp *MySchemaOp; + int check; + + if (theTableCreateFlag == 0) { + for(int i=0; i < 1 ;i++) { + ndbout << "Creating " << tableName[i] << "..." << endl; + MySchemaTransaction = pMyNdb->startSchemaTransaction(); + + if(MySchemaTransaction == NULL && + (!error_handler(MySchemaTransaction->getNdbError()))) + return -1; + + MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); + if(MySchemaOp == NULL && + (!error_handler(MySchemaTransaction->getNdbError()))) + return -1; + + check = MySchemaOp->createTable( tableName[i] + ,8 // Table Size + ,TupleKey // Key Type + ,40 // Nr of Pages + ,All + ,6 + ,(tLoadFactor - 5) + ,(tLoadFactor) + ,1 + ,!tempTable + ); + + if (check == -1 && + (!error_handler(MySchemaTransaction->getNdbError()))) + return -1; + + check = MySchemaOp->createAttribute( (char*)attrName[0], + TupleKey, + 32, + PKSIZE, + UnSigned, + MMBased, + NotNullAttribute ); + + if (check == -1 && + (!error_handler(MySchemaTransaction->getNdbError()))) + return -1; + for (int j = 1; j < tNoOfAttributes ; j++){ + check = MySchemaOp->createAttribute( (char*)attrName[j], + NoKey, + 32, + tAttributeSize, + UnSigned, + MMBased, + NotNullAttribute ); + if (check == -1 && + (!error_handler(MySchemaTransaction->getNdbError()))) + return -1; + } + + if (MySchemaTransaction->execute() == -1 && + (!error_handler(MySchemaTransaction->getNdbError()))) + return -1; + + pMyNdb->closeSchemaTransaction(MySchemaTransaction); + } + } + + return 0; +} + +static +bool error_handler(const NdbError & err){ + ndbout << err << endl ; + switch(err.classification){ + case NdbError::TemporaryResourceError: + case NdbError::OverloadError: + case NdbError::SchemaError: + ndbout << endl << "Attempting to recover and continue now..." << endl ; + return true; + } + return false ; // return false to abort +} +static +bool error_handler(const char* error_string, int error_int) { + ndbout << error_string << endl ; + if ((4008 == error_int) || + (721 == error_int) || + (266 == error_int)){ + ndbout << endl << "Attempting to recover and continue now..." << endl ; + return true ; // return true to retry + } + return false ; // return false to abort +} + +static +int +readArguments(int argc, const char** argv){ + + int i = 1; + while (argc > 1){ + if (strcmp(argv[i], "-t") == 0){ + tNoOfThreads = atoi(argv[i+1]); + if ((tNoOfThreads < 1) || (tNoOfThreads > MAXTHREADS)){ + ndbout_c("Invalid no of threads"); + return -1; + } + } else if (strcmp(argv[i], "-p") == 0){ + tNoOfParallelTrans = atoi(argv[i+1]); + if ((tNoOfParallelTrans < 1) || (tNoOfParallelTrans > MAXPAR)){ + ndbout_c("Invalid no of parallell transactions"); + return -1; + } + } else if (strcmp(argv[i], "-load_factor") == 0){ + tLoadFactor = atoi(argv[i+1]); + if ((tLoadFactor < 40) || (tLoadFactor > 99)){ + ndbout_c("Invalid load factor"); + return -1; + } + } else if (strcmp(argv[i], "-c") == 0) { + tNoOfOpsPerTrans = atoi(argv[i+1]); + if (tNoOfOpsPerTrans < 1){ + ndbout_c("Invalid no of operations per transaction"); + return -1; + } + } else if (strcmp(argv[i], "-o") == 0) { + tNoOfTransactions = atoi(argv[i+1]); + if (tNoOfTransactions < 1){ + ndbout_c("Invalid no of transactions"); + return -1; + } + } else if (strcmp(argv[i], "-a") == 0){ + tNoOfAttributes = atoi(argv[i+1]); + if ((tNoOfAttributes < 2) || (tNoOfAttributes > MAXATTR)){ + ndbout_c("Invalid no of attributes"); + return -1; + } + } else if (strcmp(argv[i], "-n") == 0){ + theStdTableNameFlag = 1; + argc++; + i--; + } else if (strcmp(argv[i], "-l") == 0){ + tNoOfLoops = atoi(argv[i+1]); + if ((tNoOfLoops < 0) || (tNoOfLoops > 100000)){ + ndbout_c("Invalid no of loops"); + return -1; + } + } else if (strcmp(argv[i], "-s") == 0){ + tAttributeSize = atoi(argv[i+1]); + if ((tAttributeSize < 1) || (tAttributeSize > MAXATTRSIZE)){ + ndbout_c("Invalid attributes size"); + return -1; + } + } else if (strcmp(argv[i], "-local") == 0){ + tLocalPart = atoi(argv[i+1]); + tLocal = true; + startTransGuess = true; + if ((tLocalPart < 0) || (tLocalPart > MAX_PARTS)){ + ndbout_c("Invalid local part"); + return -1; + } + } else if (strcmp(argv[i], "-simple") == 0){ + theSimpleFlag = 1; + argc++; + i--; + } else if (strcmp(argv[i], "-adaptive") == 0){ + tSendForce = 0; + argc++; + i--; + } else if (strcmp(argv[i], "-force") == 0){ + tSendForce = 1; + argc++; + i--; + } else if (strcmp(argv[i], "-non_adaptive") == 0){ + tSendForce = 2; + argc++; + i--; + } else if (strcmp(argv[i], "-write") == 0){ + theWriteFlag = 1; + argc++; + i--; + } else if (strcmp(argv[i], "-dirty") == 0){ + theDirtyFlag = 1; + argc++; + i--; + } else if (strcmp(argv[i], "-test") == 0){ + theTestFlag = 1; + argc++; + i--; + } else if (strcmp(argv[i], "-no_table_create") == 0){ + theTableCreateFlag = 1; + argc++; + i--; + } else if (strcmp(argv[i], "-temp") == 0){ + tempTable = true; + argc++; + i--; + } else if (strcmp(argv[i], "-no_hint") == 0){ + startTransGuess = false; + argc++; + i--; + } else { + return -1; + } + + argc -= 2; + i = i + 2; + }//while + if (tLocal == true) { + if (tNoOfOpsPerTrans != 1) { + ndbout_c("Not valid to have more than one op per trans with local"); + }//if + if (startTransGuess == false) { + ndbout_c("Not valid to use no_hint with local"); + }//if + }//if + return 0; +} + +static +void +input_error(){ + + ndbout_c("FLEXASYNCH"); + ndbout_c(" Perform benchmark of insert, update and delete transactions"); + ndbout_c(""); + ndbout_c("Arguments:"); + ndbout_c(" -t Number of threads to start, default 1"); + ndbout_c(" -p Number of parallel transactions per thread, default 32"); + ndbout_c(" -o Number of transactions per loop, default 500"); + ndbout_c(" -l Number of loops to run, default 1, 0=infinite"); + ndbout_c(" -load_factor Number Load factor in index in percent (40 -> 99)"); + ndbout_c(" -a Number of attributes, default 25"); + ndbout_c(" -c Number of operations per transaction"); + ndbout_c(" -s Size of each attribute, default 1 "); + ndbout_c(" (PK is always of size 1, independent of this value)"); + ndbout_c(" -simple Use simple read to read from database"); + ndbout_c(" -dirty Use dirty read to read from database"); + ndbout_c(" -write Use writeTuple in insert and update"); + ndbout_c(" -n Use standard table names"); + ndbout_c(" -no_table_create Don't create tables in db"); + ndbout_c(" -temp Create table(s) without logging"); + ndbout_c(" -no_hint Don't give hint on where to execute transaction coordinator"); + ndbout_c(" -adaptive Use adaptive send algorithm (default)"); + ndbout_c(" -force Force send when communicating"); + ndbout_c(" -non_adaptive Send at a 10 millisecond interval"); + ndbout_c(" -local Number of part, only use keys in one part out of 16"); +} + + + diff --git a/ndb/test/ndbapi/flexAsynch/Makefile b/ndb/test/ndbapi/flexAsynch/Makefile deleted file mode 100644 index 2c77c8e21df..00000000000 --- a/ndb/test/ndbapi/flexAsynch/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := flexAsynch - -# Source files of non-templated classes (.C files) -SOURCES = flexAsynch.cpp - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/test/ndbapi/flexAsynch/flexAsynch.cpp b/ndb/test/ndbapi/flexAsynch/flexAsynch.cpp deleted file mode 100644 index 0822f3ee999..00000000000 --- a/ndb/test/ndbapi/flexAsynch/flexAsynch.cpp +++ /dev/null @@ -1,982 +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 */ - - -#include "NdbApi.hpp" -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#define MAX_PARTS 4 -#define MAX_SEEK 16 -#define MAXSTRLEN 16 -#define MAXATTR 64 -#define MAXTABLES 64 -#define MAXTHREADS 128 -#define MAXPAR 1024 -#define MAXATTRSIZE 1000 -#define PKSIZE 2 - -enum StartType { - stIdle, - stInsert, - stRead, - stUpdate, - stDelete, - stStop -} ; - -extern "C" { static void* threadLoop(void*); } -static void setAttrNames(void); -static void setTableNames(void); -static int readArguments(int argc, const char** argv); -static int createTables(Ndb*); -static void defineOperation(NdbConnection* aTransObject, StartType aType, - Uint32 base, Uint32 aIndex); -static void execute(StartType aType); -static bool executeThread(StartType aType, Ndb* aNdbObject, unsigned int); -static void executeCallback(int result, NdbConnection* NdbObject, - void* aObject); -static bool error_handler(const NdbError & err); -static Uint32 getKey(Uint32, Uint32) ; -static void input_error(); - - -static int retry_opt = 3 ; -static int failed = 0 ; - -ErrorData * flexAsynchErrorData; - -struct ThreadNdb -{ - int NoOfOps; - int ThreadNo; -}; - -static NdbThread* threadLife[MAXTHREADS]; -static int tNodeId; -static int ThreadReady[MAXTHREADS]; -static StartType ThreadStart[MAXTHREADS]; -static char tableName[MAXTABLES][MAXSTRLEN+1]; -static char attrName[MAXATTR][MAXSTRLEN+1]; - -// Program Parameters -static bool tLocal = false; -static int tLocalPart = 0; -static int tSendForce = 0; -static int tNoOfLoops = 1; -static int tAttributeSize = 1; -static unsigned int tNoOfThreads = 1; -static unsigned int tNoOfParallelTrans = 32; -static unsigned int tNoOfAttributes = 25; -static unsigned int tNoOfTransactions = 500; -static unsigned int tNoOfOpsPerTrans = 1; -static unsigned int tLoadFactor = 80; -static bool tempTable = false; -static bool startTransGuess = true; - -//Program Flags -static int theTestFlag = 0; -static int theSimpleFlag = 0; -static int theDirtyFlag = 0; -static int theWriteFlag = 0; -static int theStdTableNameFlag = 0; -static int theTableCreateFlag = 0; - -#define START_REAL_TIME -#define STOP_REAL_TIME -#define START_TIMER { NdbTimer timer; timer.doStart(); -#define STOP_TIMER timer.doStop(); -#define PRINT_TIMER(text, trans, opertrans) timer.printTransactionStatistics(text, trans, opertrans); }; - -static void -resetThreads(){ - - for (int i = 0; i < tNoOfThreads ; i++) { - ThreadReady[i] = 0; - ThreadStart[i] = stIdle; - }//for -} - -static void -waitForThreads(void) -{ - int cont = 0; - do { - cont = 0; - NdbSleep_MilliSleep(20); - for (int i = 0; i < tNoOfThreads ; i++) { - if (ThreadReady[i] == 0) { - cont = 1; - }//if - }//for - } while (cont == 1); -} - -static void -tellThreads(StartType what) -{ - for (int i = 0; i < tNoOfThreads ; i++) - ThreadStart[i] = what; -} - -NDB_COMMAND(flexAsynch, "flexAsynch", "flexAsynch", "flexAsynch", 65535) -{ - ThreadNdb* pThreadData; - int tLoops=0; - int returnValue = NDBT_OK; - - flexAsynchErrorData = new ErrorData; - flexAsynchErrorData->resetErrorCounters(); - - if (readArguments(argc, argv) != 0){ - input_error(); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - - pThreadData = new ThreadNdb[MAXTHREADS]; - - ndbout << endl << "FLEXASYNCH - Starting normal mode" << endl; - ndbout << "Perform benchmark of insert, update and delete transactions"; - ndbout << endl; - ndbout << " " << tNoOfThreads << " number of concurrent threads " << endl; - ndbout << " " << tNoOfParallelTrans; - ndbout << " number of parallel operation per thread " << endl; - ndbout << " " << tNoOfTransactions << " transaction(s) per round " << endl; - ndbout << " " << tNoOfLoops << " iterations " << endl; - ndbout << " " << "Load Factor is " << tLoadFactor << "%" << endl; - ndbout << " " << tNoOfAttributes << " attributes per table " << endl; - ndbout << " " << tAttributeSize; - ndbout << " is the number of 32 bit words per attribute " << endl; - if (tempTable == true) { - ndbout << " Tables are without logging " << endl; - } else { - ndbout << " Tables are with logging " << endl; - }//if - if (startTransGuess == true) { - ndbout << " Transactions are executed with hint provided" << endl; - } else { - ndbout << " Transactions are executed with round robin scheme" << endl; - }//if - if (tSendForce == 0) { - ndbout << " No force send is used, adaptive algorithm used" << endl; - } else if (tSendForce == 1) { - ndbout << " Force send used" << endl; - } else { - ndbout << " No force send is used, adaptive algorithm disabled" << endl; - }//if - - ndbout << endl; - - NdbThread_SetConcurrencyLevel(2 + tNoOfThreads); - - /* print Setting */ - flexAsynchErrorData->printSettings(ndbout); - - setAttrNames(); - setTableNames(); - - Ndb * pNdb = new Ndb("TEST_DB"); - pNdb->init(); - tNodeId = pNdb->getNodeId(); - - ndbout << " NdbAPI node with id = " << pNdb->getNodeId() << endl; - ndbout << endl; - - ndbout << "Waiting for ndb to become ready..." <waitUntilReady(10000) != 0){ - ndbout << "NDB is not ready" << endl; - ndbout << "Benchmark failed!" << endl; - returnValue = NDBT_FAILED; - } - - if(returnValue == NDBT_OK){ - if (createTables(pNdb) != 0){ - returnValue = NDBT_FAILED; - } - } - - if(returnValue == NDBT_OK){ - /**************************************************************** - * Create NDB objects. * - ****************************************************************/ - resetThreads(); - for (int i = 0; i < tNoOfThreads ; i++) { - pThreadData[i].ThreadNo = i -; - threadLife[i] = NdbThread_Create(threadLoop, - (void**)&pThreadData[i], - 32768, - "flexAsynchThread", - NDB_THREAD_PRIO_LOW); - }//for - ndbout << endl << "All NDB objects and table created" << endl << endl; - int noOfTransacts = tNoOfParallelTrans*tNoOfTransactions*tNoOfThreads; - /**************************************************************** - * Execute program. * - ****************************************************************/ - - for(;;) { - - int loopCount = tLoops + 1 ; - ndbout << endl << "Loop # " << loopCount << endl << endl ; - - /**************************************************************** - * Perform inserts. * - ****************************************************************/ - - failed = 0 ; - - START_TIMER; - execute(stInsert); - STOP_TIMER; - PRINT_TIMER("insert", noOfTransacts, tNoOfOpsPerTrans); - - if (0 < failed) { - int i = retry_opt ; - int ci = 1 ; - while (0 < failed && 0 < i){ - ndbout << failed << " of the transactions returned errors!" - << endl << endl; - ndbout << "Attempting to redo the failed transactions now..." - << endl ; - ndbout << "Redo attempt " << ci <<" out of " << retry_opt - << endl << endl; - failed = 0 ; - START_TIMER; - execute(stInsert); - STOP_TIMER; - PRINT_TIMER("insert", noOfTransacts, tNoOfOpsPerTrans); - i-- ; - ci++; - } - if(0 == failed ){ - ndbout << endl <<"Redo attempt succeeded" << endl << endl; - }else{ - ndbout << endl <<"Redo attempt failed, moving on now..." << endl - << endl; - }//if - }//if - - /**************************************************************** - * Perform read. * - ****************************************************************/ - - failed = 0 ; - - START_TIMER; - execute(stRead); - STOP_TIMER; - PRINT_TIMER("read", noOfTransacts, tNoOfOpsPerTrans); - - if (0 < failed) { - int i = retry_opt ; - int cr = 1; - while (0 < failed && 0 < i){ - ndbout << failed << " of the transactions returned errors!"<printErrorCounters(ndbout); - - return NDBT_ProgramExit(returnValue); -}//main() - - -static void execute(StartType aType) -{ - resetThreads(); - tellThreads(aType); - waitForThreads(); -}//execute() - -static void* -threadLoop(void* ThreadData) -{ - Ndb* localNdb; - StartType tType; - ThreadNdb* tabThread = (ThreadNdb*)ThreadData; - int threadNo = tabThread->ThreadNo; - localNdb = new Ndb("TEST_DB"); - localNdb->init(1024); - localNdb->waitUntilReady(10000); - unsigned int threadBase = (threadNo << 16) + tNodeId ; - - for (;;){ - while (ThreadStart[threadNo] == stIdle) { - NdbSleep_MilliSleep(10); - }//while - - // Check if signal to exit is received - if (ThreadStart[threadNo] == stStop) { - break; - }//if - - tType = ThreadStart[threadNo]; - ThreadStart[threadNo] = stIdle; - if(!executeThread(tType, localNdb, threadBase)){ - break; - } - ThreadReady[threadNo] = 1; - }//for - - delete localNdb; - ThreadReady[threadNo] = 1; - - NdbThread_Exit(0); - return NULL; // Just to keep compiler happy -}//threadLoop() - -static -bool -executeThread(StartType aType, Ndb* aNdbObject, unsigned int threadBase) { - int i, j, k; - NdbConnection* tConArray[1024]; - unsigned int tBase; - unsigned int tBase2; - - for (i = 0; i < tNoOfTransactions; i++) { - if (tLocal == false) { - tBase = i * tNoOfParallelTrans * tNoOfOpsPerTrans; - } else { - tBase = i * tNoOfParallelTrans * MAX_SEEK; - }//if - START_REAL_TIME; - for (j = 0; j < tNoOfParallelTrans; j++) { - if (tLocal == false) { - tBase2 = tBase + (j * tNoOfOpsPerTrans); - } else { - tBase2 = tBase + (j * MAX_SEEK); - tBase2 = getKey(threadBase, tBase2); - }//if - if (startTransGuess == true) { - Uint64 Tkey64; - Uint32* Tkey32 = (Uint32*)&Tkey64; - Tkey32[0] = threadBase; - Tkey32[1] = tBase2; - tConArray[j] = aNdbObject->startTransaction((Uint32)0, //Priority - (const char*)&Tkey64, //Main PKey - (Uint32)4); //Key Length - } else { - tConArray[j] = aNdbObject->startTransaction(); - }//if - if (tConArray[j] == NULL && - !error_handler(aNdbObject->getNdbError()) ){ - ndbout << endl << "Unable to recover! Quiting now" << endl ; - return false; - }//if - - for (k = 0; k < tNoOfOpsPerTrans; k++) { - //------------------------------------------------------- - // Define the operation, but do not execute it yet. - //------------------------------------------------------- - defineOperation(tConArray[j], aType, threadBase, (tBase2 + k)); - }//for - - tConArray[j]->executeAsynchPrepare(Commit, &executeCallback, NULL); - }//for - STOP_REAL_TIME; - //------------------------------------------------------- - // Now we have defined a set of operations, it is now time - // to execute all of them. - //------------------------------------------------------- - int Tcomp = aNdbObject->sendPollNdb(3000, 0, 0); - while (Tcomp < tNoOfParallelTrans) { - int TlocalComp = aNdbObject->pollNdb(3000, 0); - Tcomp += TlocalComp; - }//while - for (j = 0 ; j < tNoOfParallelTrans ; j++) { - aNdbObject->closeTransaction(tConArray[j]); - }//for - }//for - return true; -}//executeThread() - -static -Uint32 -getKey(Uint32 aBase, Uint32 anIndex) { - Uint32 Tfound = anIndex; - Uint64 Tkey64; - Uint32* Tkey32 = (Uint32*)&Tkey64; - Tkey32[0] = aBase; - Uint32 hash; - for (Uint32 i = anIndex; i < (anIndex + MAX_SEEK); i++) { - Tkey32[1] = (Uint32)i; - hash = md5_hash((Uint64*)&Tkey64, (Uint32)2); - hash = (hash >> 6) & (MAX_PARTS - 1); - if (hash == tLocalPart) { - Tfound = i; - break; - }//if - }//for - return Tfound; -}//getKey() - -static void -executeCallback(int result, NdbConnection* NdbObject, void* aObject) -{ - if (result == -1) { - - // Add complete error handling here - - int retCode = flexAsynchErrorData->handleErrorCommon(NdbObject->getNdbError()); - if (retCode == 1) { - if (NdbObject->getNdbError().code != 626 && NdbObject->getNdbError().code != 630){ - ndbout_c("execute: %s", NdbObject->getNdbError().message); - ndbout_c("Error code = %d", NdbObject->getNdbError().code);} - } else if (retCode == 2) { - ndbout << "4115 should not happen in flexAsynch" << endl; - } else if (retCode == 3) { - /* What can we do here? */ - ndbout_c("execute: %s", NdbObject->getNdbError().message); - }//if(retCode == 3) - - // ndbout << "Error occured in poll:" << endl; - // ndbout << NdbObject->getNdbError() << endl; - failed++ ; - return; - }//if - return; -}//executeCallback() - - - -static void -defineOperation(NdbConnection* localNdbConnection, StartType aType, - Uint32 threadBase, Uint32 aIndex) -{ - NdbOperation* localNdbOperation; - unsigned int loopCountAttributes = tNoOfAttributes; - unsigned int countAttributes; - Uint32 attrValue[MAXATTRSIZE]; - - //------------------------------------------------------- - // Set-up the attribute values for this operation. - //------------------------------------------------------- - attrValue[0] = threadBase; - attrValue[1] = aIndex; - for (int k = 2; k < loopCountAttributes; k++) { - attrValue[k] = aIndex; - }//for - localNdbOperation = localNdbConnection->getNdbOperation(tableName[0]); - if (localNdbOperation == NULL) { - error_handler(localNdbConnection->getNdbError()); - }//if - switch (aType) { - case stInsert: { // Insert case - if (theWriteFlag == 1 && theDirtyFlag == 1) { - localNdbOperation->dirtyWrite(); - } else if (theWriteFlag == 1) { - localNdbOperation->writeTuple(); - } else { - localNdbOperation->insertTuple(); - }//if - break; - }//case - case stRead: { // Read Case - if (theSimpleFlag == 1) { - localNdbOperation->simpleRead(); - } else if (theDirtyFlag == 1) { - localNdbOperation->dirtyRead(); - } else { - localNdbOperation->readTuple(); - }//if - break; - }//case - case stUpdate: { // Update Case - if (theWriteFlag == 1 && theDirtyFlag == 1) { - localNdbOperation->dirtyWrite(); - } else if (theWriteFlag == 1) { - localNdbOperation->writeTuple(); - } else if (theDirtyFlag == 1) { - localNdbOperation->dirtyUpdate(); - } else { - localNdbOperation->updateTuple(); - }//if - break; - }//case - case stDelete: { // Delete Case - localNdbOperation->deleteTuple(); - break; - }//case - default: { - error_handler(localNdbOperation->getNdbError()); - }//default - }//switch - localNdbOperation->equal((Uint32)0,(char*)&attrValue[0]); - switch (aType) { - case stInsert: // Insert case - case stUpdate: // Update Case - { - for (countAttributes = 1; - countAttributes < loopCountAttributes; countAttributes++) { - localNdbOperation->setValue(countAttributes, - (char*)&attrValue[0]); - }//for - break; - }//case - case stRead: { // Read Case - for (countAttributes = 1; - countAttributes < loopCountAttributes; countAttributes++) { - localNdbOperation->getValue(countAttributes, - (char*)&attrValue[0]); - }//for - break; - }//case - case stDelete: { // Delete Case - break; - }//case - default: { - //goto error_handler; < epaulsa - error_handler(localNdbOperation->getNdbError()); - }//default - }//switch - return; -}//defineOperation() - -static void setAttrNames() -{ - int i; - - for (i = 0; i < MAXATTR ; i++){ - snprintf(attrName[i], MAXSTRLEN, "COL%d", i); - } -} - - -static void setTableNames() -{ - // Note! Uses only uppercase letters in table name's - // so that we can look at the tables wits SQL - int i; - for (i = 0; i < MAXTABLES ; i++){ - if (theStdTableNameFlag==0){ - snprintf(tableName[i], MAXSTRLEN, "TAB%d_%d", i, - (int)(NdbTick_CurrentMillisecond()/1000)); - } else { - snprintf(tableName[i], MAXSTRLEN, "TAB%d", i); - } - } -} - -static -int -createTables(Ndb* pMyNdb){ - - NdbSchemaCon *MySchemaTransaction; - NdbSchemaOp *MySchemaOp; - int check; - - if (theTableCreateFlag == 0) { - for(int i=0; i < 1 ;i++) { - ndbout << "Creating " << tableName[i] << "..." << endl; - MySchemaTransaction = pMyNdb->startSchemaTransaction(); - - if(MySchemaTransaction == NULL && - (!error_handler(MySchemaTransaction->getNdbError()))) - return -1; - - MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); - if(MySchemaOp == NULL && - (!error_handler(MySchemaTransaction->getNdbError()))) - return -1; - - check = MySchemaOp->createTable( tableName[i] - ,8 // Table Size - ,TupleKey // Key Type - ,40 // Nr of Pages - ,All - ,6 - ,(tLoadFactor - 5) - ,(tLoadFactor) - ,1 - ,!tempTable - ); - - if (check == -1 && - (!error_handler(MySchemaTransaction->getNdbError()))) - return -1; - - check = MySchemaOp->createAttribute( (char*)attrName[0], - TupleKey, - 32, - PKSIZE, - UnSigned, - MMBased, - NotNullAttribute ); - - if (check == -1 && - (!error_handler(MySchemaTransaction->getNdbError()))) - return -1; - for (int j = 1; j < tNoOfAttributes ; j++){ - check = MySchemaOp->createAttribute( (char*)attrName[j], - NoKey, - 32, - tAttributeSize, - UnSigned, - MMBased, - NotNullAttribute ); - if (check == -1 && - (!error_handler(MySchemaTransaction->getNdbError()))) - return -1; - } - - if (MySchemaTransaction->execute() == -1 && - (!error_handler(MySchemaTransaction->getNdbError()))) - return -1; - - pMyNdb->closeSchemaTransaction(MySchemaTransaction); - } - } - - return 0; -} - -static -bool error_handler(const NdbError & err){ - ndbout << err << endl ; - switch(err.classification){ - case NdbError::TemporaryResourceError: - case NdbError::OverloadError: - case NdbError::SchemaError: - ndbout << endl << "Attempting to recover and continue now..." << endl ; - return true; - } - return false ; // return false to abort -} -static -bool error_handler(const char* error_string, int error_int) { - ndbout << error_string << endl ; - if ((4008 == error_int) || - (721 == error_int) || - (266 == error_int)){ - ndbout << endl << "Attempting to recover and continue now..." << endl ; - return true ; // return true to retry - } - return false ; // return false to abort -} - -static -int -readArguments(int argc, const char** argv){ - - int i = 1; - while (argc > 1){ - if (strcmp(argv[i], "-t") == 0){ - tNoOfThreads = atoi(argv[i+1]); - if ((tNoOfThreads < 1) || (tNoOfThreads > MAXTHREADS)){ - ndbout_c("Invalid no of threads"); - return -1; - } - } else if (strcmp(argv[i], "-p") == 0){ - tNoOfParallelTrans = atoi(argv[i+1]); - if ((tNoOfParallelTrans < 1) || (tNoOfParallelTrans > MAXPAR)){ - ndbout_c("Invalid no of parallell transactions"); - return -1; - } - } else if (strcmp(argv[i], "-load_factor") == 0){ - tLoadFactor = atoi(argv[i+1]); - if ((tLoadFactor < 40) || (tLoadFactor > 99)){ - ndbout_c("Invalid load factor"); - return -1; - } - } else if (strcmp(argv[i], "-c") == 0) { - tNoOfOpsPerTrans = atoi(argv[i+1]); - if (tNoOfOpsPerTrans < 1){ - ndbout_c("Invalid no of operations per transaction"); - return -1; - } - } else if (strcmp(argv[i], "-o") == 0) { - tNoOfTransactions = atoi(argv[i+1]); - if (tNoOfTransactions < 1){ - ndbout_c("Invalid no of transactions"); - return -1; - } - } else if (strcmp(argv[i], "-a") == 0){ - tNoOfAttributes = atoi(argv[i+1]); - if ((tNoOfAttributes < 2) || (tNoOfAttributes > MAXATTR)){ - ndbout_c("Invalid no of attributes"); - return -1; - } - } else if (strcmp(argv[i], "-n") == 0){ - theStdTableNameFlag = 1; - argc++; - i--; - } else if (strcmp(argv[i], "-l") == 0){ - tNoOfLoops = atoi(argv[i+1]); - if ((tNoOfLoops < 0) || (tNoOfLoops > 100000)){ - ndbout_c("Invalid no of loops"); - return -1; - } - } else if (strcmp(argv[i], "-s") == 0){ - tAttributeSize = atoi(argv[i+1]); - if ((tAttributeSize < 1) || (tAttributeSize > MAXATTRSIZE)){ - ndbout_c("Invalid attributes size"); - return -1; - } - } else if (strcmp(argv[i], "-local") == 0){ - tLocalPart = atoi(argv[i+1]); - tLocal = true; - startTransGuess = true; - if ((tLocalPart < 0) || (tLocalPart > MAX_PARTS)){ - ndbout_c("Invalid local part"); - return -1; - } - } else if (strcmp(argv[i], "-simple") == 0){ - theSimpleFlag = 1; - argc++; - i--; - } else if (strcmp(argv[i], "-adaptive") == 0){ - tSendForce = 0; - argc++; - i--; - } else if (strcmp(argv[i], "-force") == 0){ - tSendForce = 1; - argc++; - i--; - } else if (strcmp(argv[i], "-non_adaptive") == 0){ - tSendForce = 2; - argc++; - i--; - } else if (strcmp(argv[i], "-write") == 0){ - theWriteFlag = 1; - argc++; - i--; - } else if (strcmp(argv[i], "-dirty") == 0){ - theDirtyFlag = 1; - argc++; - i--; - } else if (strcmp(argv[i], "-test") == 0){ - theTestFlag = 1; - argc++; - i--; - } else if (strcmp(argv[i], "-no_table_create") == 0){ - theTableCreateFlag = 1; - argc++; - i--; - } else if (strcmp(argv[i], "-temp") == 0){ - tempTable = true; - argc++; - i--; - } else if (strcmp(argv[i], "-no_hint") == 0){ - startTransGuess = false; - argc++; - i--; - } else { - return -1; - } - - argc -= 2; - i = i + 2; - }//while - if (tLocal == true) { - if (tNoOfOpsPerTrans != 1) { - ndbout_c("Not valid to have more than one op per trans with local"); - }//if - if (startTransGuess == false) { - ndbout_c("Not valid to use no_hint with local"); - }//if - }//if - return 0; -} - -static -void -input_error(){ - - ndbout_c("FLEXASYNCH"); - ndbout_c(" Perform benchmark of insert, update and delete transactions"); - ndbout_c(""); - ndbout_c("Arguments:"); - ndbout_c(" -t Number of threads to start, default 1"); - ndbout_c(" -p Number of parallel transactions per thread, default 32"); - ndbout_c(" -o Number of transactions per loop, default 500"); - ndbout_c(" -l Number of loops to run, default 1, 0=infinite"); - ndbout_c(" -load_factor Number Load factor in index in percent (40 -> 99)"); - ndbout_c(" -a Number of attributes, default 25"); - ndbout_c(" -c Number of operations per transaction"); - ndbout_c(" -s Size of each attribute, default 1 "); - ndbout_c(" (PK is always of size 1, independent of this value)"); - ndbout_c(" -simple Use simple read to read from database"); - ndbout_c(" -dirty Use dirty read to read from database"); - ndbout_c(" -write Use writeTuple in insert and update"); - ndbout_c(" -n Use standard table names"); - ndbout_c(" -no_table_create Don't create tables in db"); - ndbout_c(" -temp Create table(s) without logging"); - ndbout_c(" -no_hint Don't give hint on where to execute transaction coordinator"); - ndbout_c(" -adaptive Use adaptive send algorithm (default)"); - ndbout_c(" -force Force send when communicating"); - ndbout_c(" -non_adaptive Send at a 10 millisecond interval"); - ndbout_c(" -local Number of part, only use keys in one part out of 16"); -} - - - diff --git a/ndb/test/ndbapi/flexBench.cpp b/ndb/test/ndbapi/flexBench.cpp new file mode 100644 index 00000000000..809d11086bf --- /dev/null +++ b/ndb/test/ndbapi/flexBench.cpp @@ -0,0 +1,1153 @@ +/* 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 */ + + +/* *************************************************** +FLEXBENCH +Perform benchmark of insert, update and delete transactions + +Arguments: + -t Number of threads to start, default 1 + -o Number of operations per loop, default 500 + -l Number of loops to run, default 1, 0=infinite + -a Number of attributes, default 25 + -c Number of tables, default 1 + -s Size of each attribute, default 1 (Primary Key is always of size 1, + independent of this value) + -lkn Number of long primary keys, default 1 + -lks Size of each long primary key, default 1 + -simple Use simple read to read from database + -dirty Use dirty read to read from database + -write Use writeTuple in insert and update + -stdtables Use standard table names + -no_table_create Don't create tables in db + -sleep Sleep a number of seconds before running the test, this + can be used so that another flexBench have time to create tables + -temp Use tables without logging + -verify Verify inserts, updates and deletes +#ifdef CEBIT_STAT + -statserv host:port statistics server to report to + -statfreq ops report every ops operations (default 100) +#endif + Returns: + 0 - Test passed + 1 - Test failed + 2 - Invalid arguments + +* *************************************************** */ + +#include "NdbApi.hpp" + +#include +#include +#include +#include +#include +#include + +#include + +#define MAXSTRLEN 16 +#define MAXATTR 64 +#define MAXTABLES 128 +#define MAXATTRSIZE 1000 +#define MAXNOLONGKEY 16 // Max number of long keys. +#define MAXLONGKEYTOTALSIZE 1023 // words = 4092 bytes + +extern "C" { static void* flexBenchThread(void*); } +static int readArguments(int argc, const char** argv); +static int createTables(Ndb*); +static void sleepBeforeStartingTest(int seconds); +static void input_error(); + +enum StartType { + stIdle, + stInsert, + stVerify, + stRead, + stUpdate, + stDelete, + stTryDelete, + stVerifyDelete, + stStop +}; + +struct ThreadData +{ + int threadNo; + NdbThread* threadLife; + int threadReady; + StartType threadStart; + int threadResult; +}; + +static int tNodeId = 0 ; +static char tableName[MAXTABLES][MAXSTRLEN+1]; +static char attrName[MAXATTR][MAXSTRLEN+1]; +static char** longKeyAttrName; + +// Program Parameters +static int tNoOfLoops = 1; +static int tAttributeSize = 1; +static unsigned int tNoOfThreads = 1; +static unsigned int tNoOfTables = 1; +static unsigned int tNoOfAttributes = 25; +static unsigned int tNoOfOperations = 500; +static unsigned int tSleepTime = 0; +static unsigned int tNoOfLongPK = 1; +static unsigned int tSizeOfLongPK = 1; + +//Program Flags +static int theSimpleFlag = 0; +static int theDirtyFlag = 0; +static int theWriteFlag = 0; +static int theStdTableNameFlag = 0; +static int theTableCreateFlag = 0; +static bool theTempTable = false; +static bool VerifyFlag = true; +static bool useLongKeys = false; + + +static ErrorData theErrorData; // Part of flexBench-program + +#define START_TIMER { NdbTimer timer; timer.doStart(); +#define STOP_TIMER timer.doStop(); +#define PRINT_TIMER(text, trans, opertrans) timer.printTransactionStatistics(text, trans, opertrans); }; + +#include + +#ifdef CEBIT_STAT +#include +static bool statEnable = false; +static char statHost[100]; +static int statFreq = 100; +static int statPort = 0; +static int statSock = -1; +static enum { statError = -1, statClosed, statOpen } statState; +static NdbMutex statMutex = NDB_MUTEX_INITIALIZER; +#endif + +//------------------------------------------------------------------- +// Statistical Reporting routines +//------------------------------------------------------------------- +#ifdef CEBIT_STAT +// Experimental client-side statistic for CeBIT + +static void +statReport(enum StartType st, int ops) +{ + if (!statEnable) + return; + if (NdbMutex_Lock(&statMutex) < 0) { + if (statState != statError) { + ndbout_c("stat: lock mutex failed: %s", strerror(errno)); + statState = statError; + } + return; + } + static int nodeid; + // open connection + if (statState != statOpen) { + char *p = getenv("NDB_NODEID"); // ndbnet sets NDB_NODEID + nodeid = p == 0 ? 0 : atoi(p); + if ((statSock = socket(PF_INET, SOCK_STREAM, 0)) < 0) { + if (statState != statError) { + ndbout_c("stat: create socket failed: %s", strerror(errno)); + statState = statError; + } + (void)NdbMutex_Unlock(&statMutex); + return; + } + struct sockaddr_in saddr; + memset(&saddr, 0, sizeof(saddr)); + saddr.sin_family = AF_INET; + saddr.sin_port = htons(statPort); + if (Ndb_getInAddr(&saddr.sin_addr, statHost) < 0) { + if (statState != statError) { + ndbout_c("stat: host %s not found", statHost); + statState = statError; + } + (void)close(statSock); + (void)NdbMutex_Unlock(&statMutex); + return; + } + if (connect(statSock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { + if (statState != statError) { + ndbout_c("stat: connect failed: %s", strerror(errno)); + statState = statError; + } + (void)close(statSock); + (void)NdbMutex_Unlock(&statMutex); + return; + } + statState = statOpen; + ndbout_c("stat: connection to %s:%d opened", statHost, (int)statPort); + } + const char *text; + switch (st) { + case stInsert: + text = "insert"; + break; + case stVerify: + text = "verify"; + break; + case stRead: + text = "read"; + break; + case stUpdate: + text = "update"; + break; + case stDelete: + text = "delete"; + break; + case stVerifyDelete: + text = "verifydelete"; + break; + default: + text = "unknown"; + break; + } + char buf[100]; + sprintf(buf, "%d %s %d\n", nodeid, text, ops); + int len = strlen(buf); + // assume SIGPIPE already ignored + if (write(statSock, buf, len) != len) { + if (statState != statError) { + ndbout_c("stat: write failed: %s", strerror(errno)); + statState = statError; + } + (void)close(statSock); + (void)NdbMutex_Unlock(&statMutex); + return; + } + (void)NdbMutex_Unlock(&statMutex); +} +#endif // CEBIT_STAT + +static void +resetThreads(ThreadData* pt){ + for (unsigned int i = 0; i < tNoOfThreads; i++){ + pt[i].threadReady = 0; + pt[i].threadResult = 0; + pt[i].threadStart = stIdle; + } +} + +static int +checkThreadResults(ThreadData* pt){ + for (unsigned int i = 0; i < tNoOfThreads; i++){ + if(pt[i].threadResult != 0){ + ndbout_c("Thread%d reported fatal error %d", i, pt[i].threadResult); + return -1; + } + } + return 0; +} + +static +void +waitForThreads(ThreadData* pt) +{ + int cont = 1; + while (cont){ + NdbSleep_MilliSleep(100); + cont = 0; + for (unsigned int i = 0; i < tNoOfThreads; i++){ + if (pt[i].threadReady == 0) + cont = 1; + } + } +} + +static void +tellThreads(ThreadData* pt, StartType what) +{ + for (unsigned int i = 0; i < tNoOfThreads; i++) + pt[i].threadStart = what; +} + +NDB_COMMAND(flexBench, "flexBench", "flexBench", "flexbench", 65535) +{ + ThreadData* pThreadsData; + int tLoops = 0; + int returnValue = NDBT_OK; + + if (readArguments(argc, argv) != 0){ + input_error(); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + + if(useLongKeys){ + longKeyAttrName = (char **) malloc(sizeof(char*) * tNoOfLongPK); + for (Uint32 i = 0; i < tNoOfLongPK; i++) { + longKeyAttrName[i] = (char *) malloc(strlen("KEYATTR ") + 1); + memset(longKeyAttrName[i], 0, strlen("KEYATTR ") + 1); + sprintf(longKeyAttrName[i], "KEYATTR%i", i); + } + } + + pThreadsData = new ThreadData[tNoOfThreads]; + + ndbout << endl << "FLEXBENCH - Starting normal mode" << endl; + ndbout << "Perform benchmark of insert, update and delete transactions"<< endl; + ndbout << " " << tNoOfThreads << " thread(s) " << endl; + ndbout << " " << tNoOfLoops << " iterations " << endl; + ndbout << " " << tNoOfTables << " table(s) and " << 1 << " operation(s) per transaction " <init(); + + tNodeId = pNdb->getNodeId(); + ndbout << " NdbAPI node with id = " << tNodeId << endl; + ndbout << endl; + + ndbout << "Waiting for ndb to become ready..." <waitUntilReady(2000) != 0){ + ndbout << "NDB is not ready" << endl; + ndbout << "Benchmark failed!" << endl; + returnValue = NDBT_FAILED; + } + + if(returnValue == NDBT_OK){ + if (createTables(pNdb) != 0){ + returnValue = NDBT_FAILED; + } + } + + if(returnValue == NDBT_OK){ + + sleepBeforeStartingTest(tSleepTime); + + /**************************************************************** + * Create threads. * + ****************************************************************/ + resetThreads(pThreadsData); + + for (unsigned int i = 0; i < tNoOfThreads; i++){ + pThreadsData[i].threadNo = i; + pThreadsData[i].threadLife = NdbThread_Create(flexBenchThread, + (void**)&pThreadsData[i], + 32768, + "flexBenchThread", + NDB_THREAD_PRIO_LOW); + } + + waitForThreads(pThreadsData); + + ndbout << endl << "All threads started" << endl << endl; + + /**************************************************************** + * Execute program. * + ****************************************************************/ + + for(;;){ + + int loopCount = tLoops + 1; + ndbout << endl << "Loop # " << loopCount << endl << endl; + + /**************************************************************** + * Perform inserts. * + ****************************************************************/ + // Reset and start timer + START_TIMER; + // Give insert-command to all threads + resetThreads(pThreadsData); + tellThreads(pThreadsData, stInsert); + waitForThreads(pThreadsData); + if (checkThreadResults(pThreadsData) != 0){ + ndbout << "Error: Threads failed in performing insert" << endl; + returnValue = NDBT_FAILED; + break; + } + // stop timer and print results. + STOP_TIMER; + PRINT_TIMER("insert", tNoOfOperations*tNoOfThreads, tNoOfTables); + /**************************************************************** + * Verify inserts. * + ****************************************************************/ + if (VerifyFlag) { + resetThreads(pThreadsData); + ndbout << "Verifying inserts...\t" ; + tellThreads(pThreadsData, stVerify); + waitForThreads(pThreadsData); + if (checkThreadResults(pThreadsData) != 0){ + ndbout << "Error: Threads failed while verifying inserts" << endl; + returnValue = NDBT_FAILED; + break; + }else{ + ndbout << "\t\tOK" << endl << endl ; + } + } + + /**************************************************************** + * Perform read. * + ****************************************************************/ + // Reset and start timer + START_TIMER; + // Give read-command to all threads + resetThreads(pThreadsData); + tellThreads(pThreadsData, stRead); + waitForThreads(pThreadsData); + if (checkThreadResults(pThreadsData) != 0){ + ndbout << "Error: Threads failed in performing read" << endl; + returnValue = NDBT_FAILED; + break; + } + // stop timer and print results. + STOP_TIMER; + PRINT_TIMER("read", tNoOfOperations*tNoOfThreads, tNoOfTables); + + /**************************************************************** + * Perform update. * + ****************************************************************/ + // Reset and start timer + START_TIMER; + // Give insert-command to all threads + resetThreads(pThreadsData); + tellThreads(pThreadsData, stUpdate); + waitForThreads(pThreadsData); + if (checkThreadResults(pThreadsData) != 0){ + ndbout << "Error: Threads failed in performing update" << endl; + returnValue = NDBT_FAILED; + break; + } + // stop timer and print results. + STOP_TIMER; + PRINT_TIMER("update", tNoOfOperations*tNoOfThreads, tNoOfTables); + + /**************************************************************** + * Verify updates. * + ****************************************************************/ + if (VerifyFlag) { + resetThreads(pThreadsData); + ndbout << "Verifying updates...\t" ; + tellThreads(pThreadsData, stVerify); + waitForThreads(pThreadsData); + if (checkThreadResults(pThreadsData) != 0){ + ndbout << "Error: Threads failed while verifying updates" << endl; + returnValue = NDBT_FAILED; + break; + }else{ + ndbout << "\t\tOK" << endl << endl ; + } + } + + /**************************************************************** + * Perform read. * + ****************************************************************/ + // Reset and start timer + START_TIMER; + // Give insert-command to all threads + resetThreads(pThreadsData); + tellThreads(pThreadsData, stRead); + waitForThreads(pThreadsData); + if (checkThreadResults(pThreadsData) != 0){ + ndbout << "Error: Threads failed in performing read" << endl; + returnValue = NDBT_FAILED; + break; + } + // stop timer and print results. + STOP_TIMER; + PRINT_TIMER("read", tNoOfOperations*tNoOfThreads, tNoOfTables); + + /**************************************************************** + * Perform delete. * + ****************************************************************/ + // Reset and start timer + START_TIMER; + // Give insert-command to all threads + resetThreads(pThreadsData); + tellThreads(pThreadsData, stDelete); + waitForThreads(pThreadsData); + if (checkThreadResults(pThreadsData) != 0){ + ndbout << "Error: Threads failed in performing delete" << endl; + returnValue = NDBT_FAILED; + break; + } + // stop timer and print results. + STOP_TIMER; + PRINT_TIMER("delete", tNoOfOperations*tNoOfThreads, tNoOfTables); + + /**************************************************************** + * Verify deletes. * + ****************************************************************/ + if (VerifyFlag) { + resetThreads(pThreadsData); + ndbout << "Verifying tuple deletion..." ; + tellThreads(pThreadsData, stVerifyDelete); + waitForThreads(pThreadsData); + if (checkThreadResults(pThreadsData) != 0){ + ndbout << "Error: Threads failed in verifying deletes" << endl; + returnValue = NDBT_FAILED; + break; + }else{ + ndbout << "\t\tOK" << endl << endl ; + } + } + + ndbout << "--------------------------------------------------" << endl; + + tLoops++; + + if ( 0 != tNoOfLoops && tNoOfLoops <= tLoops ) + break; + theErrorData.printErrorCounters(); + } + + resetThreads(pThreadsData); + tellThreads(pThreadsData, stStop); + waitForThreads(pThreadsData); + + void * tmp; + for(Uint32 i = 0; i> 8) & 255); + hash_value = (hash_value << 5) + hash_value + ((h_key >> 16) & 255); + hash_value = (hash_value << 5) + hash_value + ((h_key >> 24) & 255); + } + return hash_value; +} + +// End of warming up phase + + + +static void* flexBenchThread(void* pArg) +{ + ThreadData* pThreadData = (ThreadData*)pArg; + unsigned int threadNo, threadBase; + Ndb* pNdb = NULL ; + NdbConnection *pTrans = NULL ; + NdbOperation** pOps = NULL ; + StartType tType ; + StartType tSaveType ; + NdbRecAttr* tTmp = NULL ; + int* attrValue = NULL ; + int* attrRefValue = NULL ; + int check = 0 ; + int loopCountOps, loopCountTables, loopCountAttributes; + int tAttemptNo = 0; + int tRetryAttempts = 20; + int tResult = 0; + int tSpecialTrans = 0; + int nRefLocalOpOffset = 0 ; + int nReadBuffSize = + tNoOfTables * tNoOfAttributes * sizeof(int) * tAttributeSize ; + int nRefBuffSize = + tNoOfOperations * tNoOfAttributes * sizeof(int) * tAttributeSize ; + unsigned*** longKeyAttrValue; + + + threadNo = pThreadData->threadNo ; + + attrValue = (int*)malloc(nReadBuffSize) ; + attrRefValue = (int*)malloc(nRefBuffSize) ; + pOps = (NdbOperation**)malloc(tNoOfTables*sizeof(NdbOperation*)) ; + pNdb = new Ndb( "TEST_DB" ); + + if(!attrValue || !attrRefValue || !pOps || !pNdb){ + // Check allocations to make sure we got all the memory we asked for + ndbout << "One or more memory allocations failed when starting thread #"; + ndbout << threadNo << endl ; + ndbout << "Thread #" << threadNo << " will now exit" << endl ; + tResult = 13 ; + free(attrValue) ; + free(attrRefValue) ; + free(pOps) ; + delete pNdb ; + NdbThread_Exit(0) ; + } + + pNdb->init(); + pNdb->waitUntilReady(); + + // To make sure that two different threads doesn't operate on the same record + // Calculate an "unique" number to use as primary key + threadBase = (threadNo * 2000000) + (tNodeId * 260000000); + + if(useLongKeys){ + // Allocate and populate the longkey array. + longKeyAttrValue = (unsigned ***) malloc(sizeof(unsigned**) * tNoOfOperations ); + for (Uint32 n = 0; n < tNoOfOperations; n++) + longKeyAttrValue[n] = (unsigned **) malloc(sizeof(unsigned*) * tNoOfLongPK ); + for (Uint32 n = 0; n < tNoOfOperations; n++){ + for (Uint32 i = 0; i < tNoOfLongPK ; i++) { + longKeyAttrValue[n][i] = (unsigned *) malloc(sizeof(unsigned) * tSizeOfLongPK); + memset(longKeyAttrValue[n][i], 0, sizeof(unsigned) * tSizeOfLongPK); + for(Uint32 j = 0; j < tSizeOfLongPK; j++) { + // Repeat the unique value to fill up the long key. + longKeyAttrValue[n][i][j] = threadBase + n; + } + } + } + } + + int nRefOpOffset = 0 ; + //Assign reference attribute values to memory + for(Uint32 ops = 1 ; ops < tNoOfOperations ; ops++){ + // Calculate offset value before going into the next loop + nRefOpOffset = tAttributeSize*tNoOfAttributes*(ops-1) ; + for(Uint32 a = 0 ; a < tNoOfAttributes ; a++){ + *(int*)&attrRefValue[nRefOpOffset + tAttributeSize*a] = + (int)(threadBase + ops + a) ; + } + } + +#ifdef CEBIT_STAT + // ops not yet reported + int statOps = 0; +#endif + for (;;) { + pThreadData->threadResult = tResult; // Report error to main thread, + // normally tResult is set to 0 + pThreadData->threadReady = 1; + + while (pThreadData->threadStart == stIdle){ + NdbSleep_MilliSleep(100); + }//while + + // Check if signal to exit is received + if (pThreadData->threadStart == stStop){ + pThreadData->threadReady = 1; + // ndbout_c("Thread%d is stopping", threadNo); + // In order to stop this thread, the main thread has signaled + // stStop, break out of the for loop so that destructors + // and the proper exit functions are called + break; + }//if + + tType = pThreadData->threadStart; + tSaveType = tType; + pThreadData->threadStart = stIdle; + + // Start transaction, type of transaction + // is received in the array ThreadStart + loopCountOps = tNoOfOperations; + loopCountTables = tNoOfTables; + loopCountAttributes = tNoOfAttributes; + + for (int count = 1; count < loopCountOps && tResult == 0;){ + + pTrans = pNdb->startTransaction(); + if (pTrans == NULL) { + // This is a fatal error, abort program + ndbout << "Could not start transaction in thread" << threadNo; + ndbout << endl; + ndbout << pNdb->getNdbError() << endl; + tResult = 1; // Indicate fatal error + break; // Break out of for loop + } + + // Calculate the current operation offset in the reference array + nRefLocalOpOffset = tAttributeSize*tNoOfAttributes*(count - 1) ; + + for (int countTables = 0; + countTables < loopCountTables && tResult == 0; + countTables++) { + + pOps[countTables] = pTrans->getNdbOperation(tableName[countTables]); + if (pOps[countTables] == NULL) { + // This is a fatal error, abort program + ndbout << "getNdbOperation: " << pTrans->getNdbError(); + tResult = 2; // Indicate fatal error + break; + }//if + + switch (tType) { + case stInsert: // Insert case + if (theWriteFlag == 1 && theDirtyFlag == 1) + pOps[countTables]->dirtyWrite(); + else if (theWriteFlag == 1) + pOps[countTables]->writeTuple(); + else + pOps[countTables]->insertTuple(); + break; + case stRead: // Read Case + if (theSimpleFlag == 1) + pOps[countTables]->simpleRead(); + else if (theDirtyFlag == 1) + pOps[countTables]->dirtyRead(); + else + pOps[countTables]->readTuple(); + break; + case stUpdate: // Update Case + if (theWriteFlag == 1 && theDirtyFlag == 1) + pOps[countTables]->dirtyWrite(); + else if (theWriteFlag == 1) + pOps[countTables]->writeTuple(); + else if (theDirtyFlag == 1) + pOps[countTables]->dirtyUpdate(); + else + pOps[countTables]->updateTuple(); + break; + case stDelete: // Delete Case + pOps[countTables]->deleteTuple(); + break; + case stVerify: + pOps[countTables]->readTuple(); + break; + case stVerifyDelete: + pOps[countTables]->readTuple(); + break; + default: + assert(false); + }//switch + + + if(useLongKeys){ + // Loop the equal call so the complete key is send to the kernel. + for(Uint32 i = 0; i < tNoOfLongPK; i++) + pOps[countTables]->equal(longKeyAttrName[i], + (char *)longKeyAttrValue[count - 1][i], tSizeOfLongPK*4); + } + else + pOps[countTables]->equal((char*)attrName[0], + (char*)&attrRefValue[nRefLocalOpOffset]); + + if (tType == stInsert || tType == stUpdate){ + for (int ca = 1; ca < loopCountAttributes; ca++){ + pOps[countTables]->setValue((char*)attrName[ca], + (char*)&attrRefValue[nRefLocalOpOffset + tAttributeSize*ca]); + }//for + } else if (tType == stRead || stVerify == tType) { + int nTableOffset = tAttributeSize * + loopCountAttributes * + countTables ; + for (int ca = 1; ca < loopCountAttributes; ca++) { + tTmp = pOps[countTables]->getValue((char*)attrName[ca], + (char*)&attrValue[nTableOffset + tAttributeSize*ca]); + }//for + } else if (stVerifyDelete == tType) { + if(useLongKeys){ + int nTableOffset = tAttributeSize * + loopCountAttributes * + countTables ; + tTmp = pOps[countTables]->getValue(longKeyAttrName[0], + (char*)&attrValue[nTableOffset]); + } else { + int nTableOffset = tAttributeSize * + loopCountAttributes * + countTables ; + tTmp = pOps[countTables]->getValue((char*)attrName[0], + (char*)&attrValue[nTableOffset]); + } + }//if + }//for Tables loop + + if (tResult != 0) + break; + check = pTrans->execute(Commit); + + // Decide what kind of error this is + if ((tSpecialTrans == 1) && + (check == -1)) { + // -------------------------------------------------------------------- + // A special transaction have been executed, change to check = 0 in + // certain situations. + // -------------------------------------------------------------------- + switch (tType) { + case stInsert: // Insert case + if (630 == pTrans->getNdbError().code ) { + check = 0; + ndbout << "Insert with 4007 was successful" << endl; + }//if + break; + case stDelete: // Delete Case + if (626 == pTrans->getNdbError().code ) { + check = 0; + ndbout << "Delete with 4007 was successful" << endl; + }//if + break; + default: + assert(false); + }//switch + }//if + tSpecialTrans = 0; + if (check == -1) { + if ((stVerifyDelete == tType) && + (626 == pTrans->getNdbError().code)) { + // ---------------------------------------------- + // It's good news - the deleted tuple is gone, + // so reset "check" flag + // ---------------------------------------------- + check = 0 ; + } else { + int retCode = + theErrorData.handleErrorCommon(pTrans->getNdbError()); + if (retCode == 1) { + ndbout_c("execute: %d, %d, %s", count, tType, + pTrans->getNdbError().message ); + ndbout_c("Error code = %d", pTrans->getNdbError().code ); + tResult = 20; + } else if (retCode == 2) { + ndbout << "4115 should not happen in flexBench" << endl; + tResult = 20; + } else if (retCode == 3) { + // -------------------------------------------------------------------- + // We are not certain if the transaction was successful or not. + // We must reexecute but might very well find that the transaction + // actually was updated. Updates and Reads are no problem here. Inserts + // will not cause a problem if error code 630 arrives. Deletes will + // not cause a problem if 626 arrives. + // -------------------------------------------------------------------- + if ((tType == stInsert) || (tType == stDelete)) { + tSpecialTrans = 1; + }//if + }//if + }//if + }//if + // Check if retries should be made + if (check == -1 && tResult == 0) { + if (tAttemptNo < tRetryAttempts){ + tAttemptNo++; + } else { + // -------------------------------------------------------------------- + // Too many retries have been made, report error and break out of loop + // -------------------------------------------------------------------- + ndbout << "Thread" << threadNo; + ndbout << ": too many errors reported" << endl; + tResult = 10; + break; + }//if + }//if + + if (check == 0){ + // Go to the next record + count++; + tAttemptNo = 0; +#ifdef CEBIT_STAT + // report successful ops + if (statEnable) { + statOps += loopCountTables; + if (statOps >= statFreq) { + statReport(tType, statOps); + statOps = 0; + }//if + }//if +#endif + }//if + + if (stVerify == tType && 0 == check){ + int nTableOffset = 0 ; + for (int a = 1 ; a < loopCountAttributes ; a++){ + for (int tables = 0 ; tables < loopCountTables ; tables++){ + nTableOffset = tables*loopCountAttributes*tAttributeSize ; + if (*(int*)&attrValue[nTableOffset + tAttributeSize*a] != *(int*)&attrRefValue[nRefLocalOpOffset + tAttributeSize*a]){ + ndbout << "Error in verify:" << endl ; + ndbout << "attrValue[" << nTableOffset + tAttributeSize*a << "] = " << attrValue[a] << endl ; + ndbout << "attrRefValue[" << nRefLocalOpOffset + tAttributeSize*a << "]" << attrRefValue[nRefLocalOpOffset + tAttributeSize*a] << endl ; + tResult = 11 ; + break ; + }//if + }//for + }//for + }// if(stVerify ... ) + pNdb->closeTransaction(pTrans) ; + }// operations loop +#ifdef CEBIT_STAT + // report remaining successful ops + if (statEnable) { + if (statOps > 0) { + statReport(tType, statOps); + statOps = 0; + }//if + }//if +#endif + } + delete pNdb; + free(attrValue) ; + free(attrRefValue) ; + free(pOps) ; + + if (useLongKeys == true) { + // Only free these areas if they have been allocated + // Otherwise cores will occur + for (Uint32 n = 0; n < tNoOfOperations; n++){ + for (Uint32 i = 0; i < tNoOfLongPK; i++) { + free(longKeyAttrValue[n][i]); + } + free(longKeyAttrValue[n]); + } + free(longKeyAttrValue); + } // if + + NdbThread_Exit(0); + return NULL; // Just to keep compiler happy +} + + +static int readArguments(int argc, const char** argv) +{ + + int i = 1; + while (argc > 1){ + if (strcmp(argv[i], "-t") == 0){ + tNoOfThreads = atoi(argv[i+1]); + if ((tNoOfThreads < 1)) + return -1; + argc -= 1; + i++; + }else if (strcmp(argv[i], "-o") == 0){ + tNoOfOperations = atoi(argv[i+1]); + if (tNoOfOperations < 1) + return -1;; + argc -= 1; + i++; + }else if (strcmp(argv[i], "-a") == 0){ + tNoOfAttributes = atoi(argv[i+1]); + if ((tNoOfAttributes < 2) || (tNoOfAttributes > MAXATTR)) + return -1; + argc -= 1; + i++; + }else if (strcmp(argv[i], "-lkn") == 0){ + tNoOfLongPK = atoi(argv[i+1]); + useLongKeys = true; + if ((tNoOfLongPK < 1) || (tNoOfLongPK > MAXNOLONGKEY) || + (tNoOfLongPK * tSizeOfLongPK) > MAXLONGKEYTOTALSIZE){ + ndbout << "Argument -lkn is not in the proper range." << endl; + return -1; + } + argc -= 1; + i++; + }else if (strcmp(argv[i], "-lks") == 0){ + tSizeOfLongPK = atoi(argv[i+1]); + useLongKeys = true; + if ((tSizeOfLongPK < 1) || (tNoOfLongPK * tSizeOfLongPK) > MAXLONGKEYTOTALSIZE){ + ndbout << "Argument -lks is not in the proper range 1 to " << + MAXLONGKEYTOTALSIZE << endl; + return -1; + } + argc -= 1; + i++; + }else if (strcmp(argv[i], "-c") == 0){ + tNoOfTables = atoi(argv[i+1]); + if ((tNoOfTables < 1) || (tNoOfTables > MAXTABLES)) + return -1; + argc -= 1; + i++; + }else if (strcmp(argv[i], "-stdtables") == 0){ + theStdTableNameFlag = 1; + }else if (strcmp(argv[i], "-l") == 0){ + tNoOfLoops = atoi(argv[i+1]); + if ((tNoOfLoops < 0) || (tNoOfLoops > 100000)) + return -1; + argc -= 1; + i++; + }else if (strcmp(argv[i], "-s") == 0){ + tAttributeSize = atoi(argv[i+1]); + if ((tAttributeSize < 1) || (tAttributeSize > MAXATTRSIZE)) + return -1; + argc -= 1; + i++; + }else if (strcmp(argv[i], "-sleep") == 0){ + tSleepTime = atoi(argv[i+1]); + if ((tSleepTime < 1) || (tSleepTime > 3600)) + return -1; + argc -= 1; + i++; + }else if (strcmp(argv[i], "-simple") == 0){ + theSimpleFlag = 1; + }else if (strcmp(argv[i], "-write") == 0){ + theWriteFlag = 1; + }else if (strcmp(argv[i], "-dirty") == 0){ + theDirtyFlag = 1; + }else if (strcmp(argv[i], "-no_table_create") == 0){ + theTableCreateFlag = 1; + }else if (strcmp(argv[i], "-temp") == 0){ + theTempTable = true; + }else if (strcmp(argv[i], "-noverify") == 0){ + VerifyFlag = false ; + }else if (theErrorData.parseCmdLineArg(argv, i) == true){ + ; //empty, updated in errorArg(..) + }else if (strcmp(argv[i], "-verify") == 0){ + VerifyFlag = true ; +#ifdef CEBIT_STAT + }else if (strcmp(argv[i], "-statserv") == 0){ + if (! (argc > 2)) + return -1; + const char *p = argv[i+1]; + const char *q = strrchr(p, ':'); + if (q == 0) + return -1; + snprintf(statHost, sizeof(statHost), "%.*s", q-p, p); + statPort = atoi(q+1); + statEnable = true; + argc -= 1; + i++; + }else if (strcmp(argv[i], "-statfreq") == 0){ + if (! (argc > 2)) + return -1; + statFreq = atoi(argv[i+1]); + if (statFreq < 1) + return -1; + argc -= 1; + i++; +#endif + }else{ + return -1; + } + argc -= 1; + i++; + } + return 0; +} + +static void sleepBeforeStartingTest(int seconds){ + if (seconds > 0){ + ndbout << "Sleeping(" <getDictionary()->createTable(tmpTable) == -1){ + return -1; + } + ndbout << "done" << endl; + } + + return 0; +} + + +static void input_error(){ + ndbout << endl << "Invalid argument!" << endl; + ndbout << endl << "Arguments:" << endl; + ndbout << " -t Number of threads to start, default 1" << endl; + ndbout << " -o Number of operations per loop, default 500" << endl; + ndbout << " -l Number of loops to run, default 1, 0=infinite" << endl; + ndbout << " -a Number of attributes, default 25" << endl; + ndbout << " -c Number of tables, default 1" << endl; + ndbout << " -s Size of each attribute, default 1 (Primary Key is always of size 1," << endl; + ndbout << " independent of this value)" << endl; + ndbout << " -lkn Number of long primary keys, default 1" << endl; + ndbout << " -lks Size of each long primary key, default 1" << endl; + + ndbout << " -simple Use simple read to read from database" << endl; + ndbout << " -dirty Use dirty read to read from database" << endl; + ndbout << " -write Use writeTuple in insert and update" << endl; + ndbout << " -stdtables Use standard table names" << endl; + ndbout << " -no_table_create Don't create tables in db" << endl; + ndbout << " -sleep Sleep a number of seconds before running the test, this" << endl; + ndbout << " can be used so that another flexBench have time to create tables" << endl; + ndbout << " -temp Use tables without logging" << endl; + ndbout << " -verify Verify inserts, updates and deletes" << endl ; + theErrorData.printCmdLineArgs(ndbout); + ndbout << endl <<"Returns:" << endl; + ndbout << "\t 0 - Test passed" << endl; + ndbout << "\t 1 - Test failed" << endl; + ndbout << "\t 2 - Invalid arguments" << endl << endl; +} + +// vim: set sw=2: diff --git a/ndb/test/ndbapi/flexBench/Makefile.am b/ndb/test/ndbapi/flexBench/Makefile.am deleted file mode 100644 index 3b27499736a..00000000000 --- a/ndb/test/ndbapi/flexBench/Makefile.am +++ /dev/null @@ -1,14 +0,0 @@ - -bin_PROGRAMS = flexBench - -flexBench_SOURCES = flexBench.cpp - -LDADD_LOC = $(top_srcdir)/ndb/test/src/libNDBT.a \ - $(top_srcdir)/ndb/src/ndbapi/libNDB_API.la \ - $(top_srcdir)/ndb/src/mgmapi/libMGM_API.la - -include $(top_srcdir)/ndb/config/common.mk.am -include $(top_srcdir)/ndb/config/type_ndbapitest.mk.am - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/ndb/test/ndbapi/flexBench/Makefile_old b/ndb/test/ndbapi/flexBench/Makefile_old deleted file mode 100644 index bfff5cd161a..00000000000 --- a/ndb/test/ndbapi/flexBench/Makefile_old +++ /dev/null @@ -1,11 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := flexBench - -# Source files of non-templated classes (.C files) -SOURCES = flexBench.cpp - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/test/ndbapi/flexBench/flexBench.cpp b/ndb/test/ndbapi/flexBench/flexBench.cpp deleted file mode 100644 index 809d11086bf..00000000000 --- a/ndb/test/ndbapi/flexBench/flexBench.cpp +++ /dev/null @@ -1,1153 +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 */ - - -/* *************************************************** -FLEXBENCH -Perform benchmark of insert, update and delete transactions - -Arguments: - -t Number of threads to start, default 1 - -o Number of operations per loop, default 500 - -l Number of loops to run, default 1, 0=infinite - -a Number of attributes, default 25 - -c Number of tables, default 1 - -s Size of each attribute, default 1 (Primary Key is always of size 1, - independent of this value) - -lkn Number of long primary keys, default 1 - -lks Size of each long primary key, default 1 - -simple Use simple read to read from database - -dirty Use dirty read to read from database - -write Use writeTuple in insert and update - -stdtables Use standard table names - -no_table_create Don't create tables in db - -sleep Sleep a number of seconds before running the test, this - can be used so that another flexBench have time to create tables - -temp Use tables without logging - -verify Verify inserts, updates and deletes -#ifdef CEBIT_STAT - -statserv host:port statistics server to report to - -statfreq ops report every ops operations (default 100) -#endif - Returns: - 0 - Test passed - 1 - Test failed - 2 - Invalid arguments - -* *************************************************** */ - -#include "NdbApi.hpp" - -#include -#include -#include -#include -#include -#include - -#include - -#define MAXSTRLEN 16 -#define MAXATTR 64 -#define MAXTABLES 128 -#define MAXATTRSIZE 1000 -#define MAXNOLONGKEY 16 // Max number of long keys. -#define MAXLONGKEYTOTALSIZE 1023 // words = 4092 bytes - -extern "C" { static void* flexBenchThread(void*); } -static int readArguments(int argc, const char** argv); -static int createTables(Ndb*); -static void sleepBeforeStartingTest(int seconds); -static void input_error(); - -enum StartType { - stIdle, - stInsert, - stVerify, - stRead, - stUpdate, - stDelete, - stTryDelete, - stVerifyDelete, - stStop -}; - -struct ThreadData -{ - int threadNo; - NdbThread* threadLife; - int threadReady; - StartType threadStart; - int threadResult; -}; - -static int tNodeId = 0 ; -static char tableName[MAXTABLES][MAXSTRLEN+1]; -static char attrName[MAXATTR][MAXSTRLEN+1]; -static char** longKeyAttrName; - -// Program Parameters -static int tNoOfLoops = 1; -static int tAttributeSize = 1; -static unsigned int tNoOfThreads = 1; -static unsigned int tNoOfTables = 1; -static unsigned int tNoOfAttributes = 25; -static unsigned int tNoOfOperations = 500; -static unsigned int tSleepTime = 0; -static unsigned int tNoOfLongPK = 1; -static unsigned int tSizeOfLongPK = 1; - -//Program Flags -static int theSimpleFlag = 0; -static int theDirtyFlag = 0; -static int theWriteFlag = 0; -static int theStdTableNameFlag = 0; -static int theTableCreateFlag = 0; -static bool theTempTable = false; -static bool VerifyFlag = true; -static bool useLongKeys = false; - - -static ErrorData theErrorData; // Part of flexBench-program - -#define START_TIMER { NdbTimer timer; timer.doStart(); -#define STOP_TIMER timer.doStop(); -#define PRINT_TIMER(text, trans, opertrans) timer.printTransactionStatistics(text, trans, opertrans); }; - -#include - -#ifdef CEBIT_STAT -#include -static bool statEnable = false; -static char statHost[100]; -static int statFreq = 100; -static int statPort = 0; -static int statSock = -1; -static enum { statError = -1, statClosed, statOpen } statState; -static NdbMutex statMutex = NDB_MUTEX_INITIALIZER; -#endif - -//------------------------------------------------------------------- -// Statistical Reporting routines -//------------------------------------------------------------------- -#ifdef CEBIT_STAT -// Experimental client-side statistic for CeBIT - -static void -statReport(enum StartType st, int ops) -{ - if (!statEnable) - return; - if (NdbMutex_Lock(&statMutex) < 0) { - if (statState != statError) { - ndbout_c("stat: lock mutex failed: %s", strerror(errno)); - statState = statError; - } - return; - } - static int nodeid; - // open connection - if (statState != statOpen) { - char *p = getenv("NDB_NODEID"); // ndbnet sets NDB_NODEID - nodeid = p == 0 ? 0 : atoi(p); - if ((statSock = socket(PF_INET, SOCK_STREAM, 0)) < 0) { - if (statState != statError) { - ndbout_c("stat: create socket failed: %s", strerror(errno)); - statState = statError; - } - (void)NdbMutex_Unlock(&statMutex); - return; - } - struct sockaddr_in saddr; - memset(&saddr, 0, sizeof(saddr)); - saddr.sin_family = AF_INET; - saddr.sin_port = htons(statPort); - if (Ndb_getInAddr(&saddr.sin_addr, statHost) < 0) { - if (statState != statError) { - ndbout_c("stat: host %s not found", statHost); - statState = statError; - } - (void)close(statSock); - (void)NdbMutex_Unlock(&statMutex); - return; - } - if (connect(statSock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { - if (statState != statError) { - ndbout_c("stat: connect failed: %s", strerror(errno)); - statState = statError; - } - (void)close(statSock); - (void)NdbMutex_Unlock(&statMutex); - return; - } - statState = statOpen; - ndbout_c("stat: connection to %s:%d opened", statHost, (int)statPort); - } - const char *text; - switch (st) { - case stInsert: - text = "insert"; - break; - case stVerify: - text = "verify"; - break; - case stRead: - text = "read"; - break; - case stUpdate: - text = "update"; - break; - case stDelete: - text = "delete"; - break; - case stVerifyDelete: - text = "verifydelete"; - break; - default: - text = "unknown"; - break; - } - char buf[100]; - sprintf(buf, "%d %s %d\n", nodeid, text, ops); - int len = strlen(buf); - // assume SIGPIPE already ignored - if (write(statSock, buf, len) != len) { - if (statState != statError) { - ndbout_c("stat: write failed: %s", strerror(errno)); - statState = statError; - } - (void)close(statSock); - (void)NdbMutex_Unlock(&statMutex); - return; - } - (void)NdbMutex_Unlock(&statMutex); -} -#endif // CEBIT_STAT - -static void -resetThreads(ThreadData* pt){ - for (unsigned int i = 0; i < tNoOfThreads; i++){ - pt[i].threadReady = 0; - pt[i].threadResult = 0; - pt[i].threadStart = stIdle; - } -} - -static int -checkThreadResults(ThreadData* pt){ - for (unsigned int i = 0; i < tNoOfThreads; i++){ - if(pt[i].threadResult != 0){ - ndbout_c("Thread%d reported fatal error %d", i, pt[i].threadResult); - return -1; - } - } - return 0; -} - -static -void -waitForThreads(ThreadData* pt) -{ - int cont = 1; - while (cont){ - NdbSleep_MilliSleep(100); - cont = 0; - for (unsigned int i = 0; i < tNoOfThreads; i++){ - if (pt[i].threadReady == 0) - cont = 1; - } - } -} - -static void -tellThreads(ThreadData* pt, StartType what) -{ - for (unsigned int i = 0; i < tNoOfThreads; i++) - pt[i].threadStart = what; -} - -NDB_COMMAND(flexBench, "flexBench", "flexBench", "flexbench", 65535) -{ - ThreadData* pThreadsData; - int tLoops = 0; - int returnValue = NDBT_OK; - - if (readArguments(argc, argv) != 0){ - input_error(); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - - if(useLongKeys){ - longKeyAttrName = (char **) malloc(sizeof(char*) * tNoOfLongPK); - for (Uint32 i = 0; i < tNoOfLongPK; i++) { - longKeyAttrName[i] = (char *) malloc(strlen("KEYATTR ") + 1); - memset(longKeyAttrName[i], 0, strlen("KEYATTR ") + 1); - sprintf(longKeyAttrName[i], "KEYATTR%i", i); - } - } - - pThreadsData = new ThreadData[tNoOfThreads]; - - ndbout << endl << "FLEXBENCH - Starting normal mode" << endl; - ndbout << "Perform benchmark of insert, update and delete transactions"<< endl; - ndbout << " " << tNoOfThreads << " thread(s) " << endl; - ndbout << " " << tNoOfLoops << " iterations " << endl; - ndbout << " " << tNoOfTables << " table(s) and " << 1 << " operation(s) per transaction " <init(); - - tNodeId = pNdb->getNodeId(); - ndbout << " NdbAPI node with id = " << tNodeId << endl; - ndbout << endl; - - ndbout << "Waiting for ndb to become ready..." <waitUntilReady(2000) != 0){ - ndbout << "NDB is not ready" << endl; - ndbout << "Benchmark failed!" << endl; - returnValue = NDBT_FAILED; - } - - if(returnValue == NDBT_OK){ - if (createTables(pNdb) != 0){ - returnValue = NDBT_FAILED; - } - } - - if(returnValue == NDBT_OK){ - - sleepBeforeStartingTest(tSleepTime); - - /**************************************************************** - * Create threads. * - ****************************************************************/ - resetThreads(pThreadsData); - - for (unsigned int i = 0; i < tNoOfThreads; i++){ - pThreadsData[i].threadNo = i; - pThreadsData[i].threadLife = NdbThread_Create(flexBenchThread, - (void**)&pThreadsData[i], - 32768, - "flexBenchThread", - NDB_THREAD_PRIO_LOW); - } - - waitForThreads(pThreadsData); - - ndbout << endl << "All threads started" << endl << endl; - - /**************************************************************** - * Execute program. * - ****************************************************************/ - - for(;;){ - - int loopCount = tLoops + 1; - ndbout << endl << "Loop # " << loopCount << endl << endl; - - /**************************************************************** - * Perform inserts. * - ****************************************************************/ - // Reset and start timer - START_TIMER; - // Give insert-command to all threads - resetThreads(pThreadsData); - tellThreads(pThreadsData, stInsert); - waitForThreads(pThreadsData); - if (checkThreadResults(pThreadsData) != 0){ - ndbout << "Error: Threads failed in performing insert" << endl; - returnValue = NDBT_FAILED; - break; - } - // stop timer and print results. - STOP_TIMER; - PRINT_TIMER("insert", tNoOfOperations*tNoOfThreads, tNoOfTables); - /**************************************************************** - * Verify inserts. * - ****************************************************************/ - if (VerifyFlag) { - resetThreads(pThreadsData); - ndbout << "Verifying inserts...\t" ; - tellThreads(pThreadsData, stVerify); - waitForThreads(pThreadsData); - if (checkThreadResults(pThreadsData) != 0){ - ndbout << "Error: Threads failed while verifying inserts" << endl; - returnValue = NDBT_FAILED; - break; - }else{ - ndbout << "\t\tOK" << endl << endl ; - } - } - - /**************************************************************** - * Perform read. * - ****************************************************************/ - // Reset and start timer - START_TIMER; - // Give read-command to all threads - resetThreads(pThreadsData); - tellThreads(pThreadsData, stRead); - waitForThreads(pThreadsData); - if (checkThreadResults(pThreadsData) != 0){ - ndbout << "Error: Threads failed in performing read" << endl; - returnValue = NDBT_FAILED; - break; - } - // stop timer and print results. - STOP_TIMER; - PRINT_TIMER("read", tNoOfOperations*tNoOfThreads, tNoOfTables); - - /**************************************************************** - * Perform update. * - ****************************************************************/ - // Reset and start timer - START_TIMER; - // Give insert-command to all threads - resetThreads(pThreadsData); - tellThreads(pThreadsData, stUpdate); - waitForThreads(pThreadsData); - if (checkThreadResults(pThreadsData) != 0){ - ndbout << "Error: Threads failed in performing update" << endl; - returnValue = NDBT_FAILED; - break; - } - // stop timer and print results. - STOP_TIMER; - PRINT_TIMER("update", tNoOfOperations*tNoOfThreads, tNoOfTables); - - /**************************************************************** - * Verify updates. * - ****************************************************************/ - if (VerifyFlag) { - resetThreads(pThreadsData); - ndbout << "Verifying updates...\t" ; - tellThreads(pThreadsData, stVerify); - waitForThreads(pThreadsData); - if (checkThreadResults(pThreadsData) != 0){ - ndbout << "Error: Threads failed while verifying updates" << endl; - returnValue = NDBT_FAILED; - break; - }else{ - ndbout << "\t\tOK" << endl << endl ; - } - } - - /**************************************************************** - * Perform read. * - ****************************************************************/ - // Reset and start timer - START_TIMER; - // Give insert-command to all threads - resetThreads(pThreadsData); - tellThreads(pThreadsData, stRead); - waitForThreads(pThreadsData); - if (checkThreadResults(pThreadsData) != 0){ - ndbout << "Error: Threads failed in performing read" << endl; - returnValue = NDBT_FAILED; - break; - } - // stop timer and print results. - STOP_TIMER; - PRINT_TIMER("read", tNoOfOperations*tNoOfThreads, tNoOfTables); - - /**************************************************************** - * Perform delete. * - ****************************************************************/ - // Reset and start timer - START_TIMER; - // Give insert-command to all threads - resetThreads(pThreadsData); - tellThreads(pThreadsData, stDelete); - waitForThreads(pThreadsData); - if (checkThreadResults(pThreadsData) != 0){ - ndbout << "Error: Threads failed in performing delete" << endl; - returnValue = NDBT_FAILED; - break; - } - // stop timer and print results. - STOP_TIMER; - PRINT_TIMER("delete", tNoOfOperations*tNoOfThreads, tNoOfTables); - - /**************************************************************** - * Verify deletes. * - ****************************************************************/ - if (VerifyFlag) { - resetThreads(pThreadsData); - ndbout << "Verifying tuple deletion..." ; - tellThreads(pThreadsData, stVerifyDelete); - waitForThreads(pThreadsData); - if (checkThreadResults(pThreadsData) != 0){ - ndbout << "Error: Threads failed in verifying deletes" << endl; - returnValue = NDBT_FAILED; - break; - }else{ - ndbout << "\t\tOK" << endl << endl ; - } - } - - ndbout << "--------------------------------------------------" << endl; - - tLoops++; - - if ( 0 != tNoOfLoops && tNoOfLoops <= tLoops ) - break; - theErrorData.printErrorCounters(); - } - - resetThreads(pThreadsData); - tellThreads(pThreadsData, stStop); - waitForThreads(pThreadsData); - - void * tmp; - for(Uint32 i = 0; i> 8) & 255); - hash_value = (hash_value << 5) + hash_value + ((h_key >> 16) & 255); - hash_value = (hash_value << 5) + hash_value + ((h_key >> 24) & 255); - } - return hash_value; -} - -// End of warming up phase - - - -static void* flexBenchThread(void* pArg) -{ - ThreadData* pThreadData = (ThreadData*)pArg; - unsigned int threadNo, threadBase; - Ndb* pNdb = NULL ; - NdbConnection *pTrans = NULL ; - NdbOperation** pOps = NULL ; - StartType tType ; - StartType tSaveType ; - NdbRecAttr* tTmp = NULL ; - int* attrValue = NULL ; - int* attrRefValue = NULL ; - int check = 0 ; - int loopCountOps, loopCountTables, loopCountAttributes; - int tAttemptNo = 0; - int tRetryAttempts = 20; - int tResult = 0; - int tSpecialTrans = 0; - int nRefLocalOpOffset = 0 ; - int nReadBuffSize = - tNoOfTables * tNoOfAttributes * sizeof(int) * tAttributeSize ; - int nRefBuffSize = - tNoOfOperations * tNoOfAttributes * sizeof(int) * tAttributeSize ; - unsigned*** longKeyAttrValue; - - - threadNo = pThreadData->threadNo ; - - attrValue = (int*)malloc(nReadBuffSize) ; - attrRefValue = (int*)malloc(nRefBuffSize) ; - pOps = (NdbOperation**)malloc(tNoOfTables*sizeof(NdbOperation*)) ; - pNdb = new Ndb( "TEST_DB" ); - - if(!attrValue || !attrRefValue || !pOps || !pNdb){ - // Check allocations to make sure we got all the memory we asked for - ndbout << "One or more memory allocations failed when starting thread #"; - ndbout << threadNo << endl ; - ndbout << "Thread #" << threadNo << " will now exit" << endl ; - tResult = 13 ; - free(attrValue) ; - free(attrRefValue) ; - free(pOps) ; - delete pNdb ; - NdbThread_Exit(0) ; - } - - pNdb->init(); - pNdb->waitUntilReady(); - - // To make sure that two different threads doesn't operate on the same record - // Calculate an "unique" number to use as primary key - threadBase = (threadNo * 2000000) + (tNodeId * 260000000); - - if(useLongKeys){ - // Allocate and populate the longkey array. - longKeyAttrValue = (unsigned ***) malloc(sizeof(unsigned**) * tNoOfOperations ); - for (Uint32 n = 0; n < tNoOfOperations; n++) - longKeyAttrValue[n] = (unsigned **) malloc(sizeof(unsigned*) * tNoOfLongPK ); - for (Uint32 n = 0; n < tNoOfOperations; n++){ - for (Uint32 i = 0; i < tNoOfLongPK ; i++) { - longKeyAttrValue[n][i] = (unsigned *) malloc(sizeof(unsigned) * tSizeOfLongPK); - memset(longKeyAttrValue[n][i], 0, sizeof(unsigned) * tSizeOfLongPK); - for(Uint32 j = 0; j < tSizeOfLongPK; j++) { - // Repeat the unique value to fill up the long key. - longKeyAttrValue[n][i][j] = threadBase + n; - } - } - } - } - - int nRefOpOffset = 0 ; - //Assign reference attribute values to memory - for(Uint32 ops = 1 ; ops < tNoOfOperations ; ops++){ - // Calculate offset value before going into the next loop - nRefOpOffset = tAttributeSize*tNoOfAttributes*(ops-1) ; - for(Uint32 a = 0 ; a < tNoOfAttributes ; a++){ - *(int*)&attrRefValue[nRefOpOffset + tAttributeSize*a] = - (int)(threadBase + ops + a) ; - } - } - -#ifdef CEBIT_STAT - // ops not yet reported - int statOps = 0; -#endif - for (;;) { - pThreadData->threadResult = tResult; // Report error to main thread, - // normally tResult is set to 0 - pThreadData->threadReady = 1; - - while (pThreadData->threadStart == stIdle){ - NdbSleep_MilliSleep(100); - }//while - - // Check if signal to exit is received - if (pThreadData->threadStart == stStop){ - pThreadData->threadReady = 1; - // ndbout_c("Thread%d is stopping", threadNo); - // In order to stop this thread, the main thread has signaled - // stStop, break out of the for loop so that destructors - // and the proper exit functions are called - break; - }//if - - tType = pThreadData->threadStart; - tSaveType = tType; - pThreadData->threadStart = stIdle; - - // Start transaction, type of transaction - // is received in the array ThreadStart - loopCountOps = tNoOfOperations; - loopCountTables = tNoOfTables; - loopCountAttributes = tNoOfAttributes; - - for (int count = 1; count < loopCountOps && tResult == 0;){ - - pTrans = pNdb->startTransaction(); - if (pTrans == NULL) { - // This is a fatal error, abort program - ndbout << "Could not start transaction in thread" << threadNo; - ndbout << endl; - ndbout << pNdb->getNdbError() << endl; - tResult = 1; // Indicate fatal error - break; // Break out of for loop - } - - // Calculate the current operation offset in the reference array - nRefLocalOpOffset = tAttributeSize*tNoOfAttributes*(count - 1) ; - - for (int countTables = 0; - countTables < loopCountTables && tResult == 0; - countTables++) { - - pOps[countTables] = pTrans->getNdbOperation(tableName[countTables]); - if (pOps[countTables] == NULL) { - // This is a fatal error, abort program - ndbout << "getNdbOperation: " << pTrans->getNdbError(); - tResult = 2; // Indicate fatal error - break; - }//if - - switch (tType) { - case stInsert: // Insert case - if (theWriteFlag == 1 && theDirtyFlag == 1) - pOps[countTables]->dirtyWrite(); - else if (theWriteFlag == 1) - pOps[countTables]->writeTuple(); - else - pOps[countTables]->insertTuple(); - break; - case stRead: // Read Case - if (theSimpleFlag == 1) - pOps[countTables]->simpleRead(); - else if (theDirtyFlag == 1) - pOps[countTables]->dirtyRead(); - else - pOps[countTables]->readTuple(); - break; - case stUpdate: // Update Case - if (theWriteFlag == 1 && theDirtyFlag == 1) - pOps[countTables]->dirtyWrite(); - else if (theWriteFlag == 1) - pOps[countTables]->writeTuple(); - else if (theDirtyFlag == 1) - pOps[countTables]->dirtyUpdate(); - else - pOps[countTables]->updateTuple(); - break; - case stDelete: // Delete Case - pOps[countTables]->deleteTuple(); - break; - case stVerify: - pOps[countTables]->readTuple(); - break; - case stVerifyDelete: - pOps[countTables]->readTuple(); - break; - default: - assert(false); - }//switch - - - if(useLongKeys){ - // Loop the equal call so the complete key is send to the kernel. - for(Uint32 i = 0; i < tNoOfLongPK; i++) - pOps[countTables]->equal(longKeyAttrName[i], - (char *)longKeyAttrValue[count - 1][i], tSizeOfLongPK*4); - } - else - pOps[countTables]->equal((char*)attrName[0], - (char*)&attrRefValue[nRefLocalOpOffset]); - - if (tType == stInsert || tType == stUpdate){ - for (int ca = 1; ca < loopCountAttributes; ca++){ - pOps[countTables]->setValue((char*)attrName[ca], - (char*)&attrRefValue[nRefLocalOpOffset + tAttributeSize*ca]); - }//for - } else if (tType == stRead || stVerify == tType) { - int nTableOffset = tAttributeSize * - loopCountAttributes * - countTables ; - for (int ca = 1; ca < loopCountAttributes; ca++) { - tTmp = pOps[countTables]->getValue((char*)attrName[ca], - (char*)&attrValue[nTableOffset + tAttributeSize*ca]); - }//for - } else if (stVerifyDelete == tType) { - if(useLongKeys){ - int nTableOffset = tAttributeSize * - loopCountAttributes * - countTables ; - tTmp = pOps[countTables]->getValue(longKeyAttrName[0], - (char*)&attrValue[nTableOffset]); - } else { - int nTableOffset = tAttributeSize * - loopCountAttributes * - countTables ; - tTmp = pOps[countTables]->getValue((char*)attrName[0], - (char*)&attrValue[nTableOffset]); - } - }//if - }//for Tables loop - - if (tResult != 0) - break; - check = pTrans->execute(Commit); - - // Decide what kind of error this is - if ((tSpecialTrans == 1) && - (check == -1)) { - // -------------------------------------------------------------------- - // A special transaction have been executed, change to check = 0 in - // certain situations. - // -------------------------------------------------------------------- - switch (tType) { - case stInsert: // Insert case - if (630 == pTrans->getNdbError().code ) { - check = 0; - ndbout << "Insert with 4007 was successful" << endl; - }//if - break; - case stDelete: // Delete Case - if (626 == pTrans->getNdbError().code ) { - check = 0; - ndbout << "Delete with 4007 was successful" << endl; - }//if - break; - default: - assert(false); - }//switch - }//if - tSpecialTrans = 0; - if (check == -1) { - if ((stVerifyDelete == tType) && - (626 == pTrans->getNdbError().code)) { - // ---------------------------------------------- - // It's good news - the deleted tuple is gone, - // so reset "check" flag - // ---------------------------------------------- - check = 0 ; - } else { - int retCode = - theErrorData.handleErrorCommon(pTrans->getNdbError()); - if (retCode == 1) { - ndbout_c("execute: %d, %d, %s", count, tType, - pTrans->getNdbError().message ); - ndbout_c("Error code = %d", pTrans->getNdbError().code ); - tResult = 20; - } else if (retCode == 2) { - ndbout << "4115 should not happen in flexBench" << endl; - tResult = 20; - } else if (retCode == 3) { - // -------------------------------------------------------------------- - // We are not certain if the transaction was successful or not. - // We must reexecute but might very well find that the transaction - // actually was updated. Updates and Reads are no problem here. Inserts - // will not cause a problem if error code 630 arrives. Deletes will - // not cause a problem if 626 arrives. - // -------------------------------------------------------------------- - if ((tType == stInsert) || (tType == stDelete)) { - tSpecialTrans = 1; - }//if - }//if - }//if - }//if - // Check if retries should be made - if (check == -1 && tResult == 0) { - if (tAttemptNo < tRetryAttempts){ - tAttemptNo++; - } else { - // -------------------------------------------------------------------- - // Too many retries have been made, report error and break out of loop - // -------------------------------------------------------------------- - ndbout << "Thread" << threadNo; - ndbout << ": too many errors reported" << endl; - tResult = 10; - break; - }//if - }//if - - if (check == 0){ - // Go to the next record - count++; - tAttemptNo = 0; -#ifdef CEBIT_STAT - // report successful ops - if (statEnable) { - statOps += loopCountTables; - if (statOps >= statFreq) { - statReport(tType, statOps); - statOps = 0; - }//if - }//if -#endif - }//if - - if (stVerify == tType && 0 == check){ - int nTableOffset = 0 ; - for (int a = 1 ; a < loopCountAttributes ; a++){ - for (int tables = 0 ; tables < loopCountTables ; tables++){ - nTableOffset = tables*loopCountAttributes*tAttributeSize ; - if (*(int*)&attrValue[nTableOffset + tAttributeSize*a] != *(int*)&attrRefValue[nRefLocalOpOffset + tAttributeSize*a]){ - ndbout << "Error in verify:" << endl ; - ndbout << "attrValue[" << nTableOffset + tAttributeSize*a << "] = " << attrValue[a] << endl ; - ndbout << "attrRefValue[" << nRefLocalOpOffset + tAttributeSize*a << "]" << attrRefValue[nRefLocalOpOffset + tAttributeSize*a] << endl ; - tResult = 11 ; - break ; - }//if - }//for - }//for - }// if(stVerify ... ) - pNdb->closeTransaction(pTrans) ; - }// operations loop -#ifdef CEBIT_STAT - // report remaining successful ops - if (statEnable) { - if (statOps > 0) { - statReport(tType, statOps); - statOps = 0; - }//if - }//if -#endif - } - delete pNdb; - free(attrValue) ; - free(attrRefValue) ; - free(pOps) ; - - if (useLongKeys == true) { - // Only free these areas if they have been allocated - // Otherwise cores will occur - for (Uint32 n = 0; n < tNoOfOperations; n++){ - for (Uint32 i = 0; i < tNoOfLongPK; i++) { - free(longKeyAttrValue[n][i]); - } - free(longKeyAttrValue[n]); - } - free(longKeyAttrValue); - } // if - - NdbThread_Exit(0); - return NULL; // Just to keep compiler happy -} - - -static int readArguments(int argc, const char** argv) -{ - - int i = 1; - while (argc > 1){ - if (strcmp(argv[i], "-t") == 0){ - tNoOfThreads = atoi(argv[i+1]); - if ((tNoOfThreads < 1)) - return -1; - argc -= 1; - i++; - }else if (strcmp(argv[i], "-o") == 0){ - tNoOfOperations = atoi(argv[i+1]); - if (tNoOfOperations < 1) - return -1;; - argc -= 1; - i++; - }else if (strcmp(argv[i], "-a") == 0){ - tNoOfAttributes = atoi(argv[i+1]); - if ((tNoOfAttributes < 2) || (tNoOfAttributes > MAXATTR)) - return -1; - argc -= 1; - i++; - }else if (strcmp(argv[i], "-lkn") == 0){ - tNoOfLongPK = atoi(argv[i+1]); - useLongKeys = true; - if ((tNoOfLongPK < 1) || (tNoOfLongPK > MAXNOLONGKEY) || - (tNoOfLongPK * tSizeOfLongPK) > MAXLONGKEYTOTALSIZE){ - ndbout << "Argument -lkn is not in the proper range." << endl; - return -1; - } - argc -= 1; - i++; - }else if (strcmp(argv[i], "-lks") == 0){ - tSizeOfLongPK = atoi(argv[i+1]); - useLongKeys = true; - if ((tSizeOfLongPK < 1) || (tNoOfLongPK * tSizeOfLongPK) > MAXLONGKEYTOTALSIZE){ - ndbout << "Argument -lks is not in the proper range 1 to " << - MAXLONGKEYTOTALSIZE << endl; - return -1; - } - argc -= 1; - i++; - }else if (strcmp(argv[i], "-c") == 0){ - tNoOfTables = atoi(argv[i+1]); - if ((tNoOfTables < 1) || (tNoOfTables > MAXTABLES)) - return -1; - argc -= 1; - i++; - }else if (strcmp(argv[i], "-stdtables") == 0){ - theStdTableNameFlag = 1; - }else if (strcmp(argv[i], "-l") == 0){ - tNoOfLoops = atoi(argv[i+1]); - if ((tNoOfLoops < 0) || (tNoOfLoops > 100000)) - return -1; - argc -= 1; - i++; - }else if (strcmp(argv[i], "-s") == 0){ - tAttributeSize = atoi(argv[i+1]); - if ((tAttributeSize < 1) || (tAttributeSize > MAXATTRSIZE)) - return -1; - argc -= 1; - i++; - }else if (strcmp(argv[i], "-sleep") == 0){ - tSleepTime = atoi(argv[i+1]); - if ((tSleepTime < 1) || (tSleepTime > 3600)) - return -1; - argc -= 1; - i++; - }else if (strcmp(argv[i], "-simple") == 0){ - theSimpleFlag = 1; - }else if (strcmp(argv[i], "-write") == 0){ - theWriteFlag = 1; - }else if (strcmp(argv[i], "-dirty") == 0){ - theDirtyFlag = 1; - }else if (strcmp(argv[i], "-no_table_create") == 0){ - theTableCreateFlag = 1; - }else if (strcmp(argv[i], "-temp") == 0){ - theTempTable = true; - }else if (strcmp(argv[i], "-noverify") == 0){ - VerifyFlag = false ; - }else if (theErrorData.parseCmdLineArg(argv, i) == true){ - ; //empty, updated in errorArg(..) - }else if (strcmp(argv[i], "-verify") == 0){ - VerifyFlag = true ; -#ifdef CEBIT_STAT - }else if (strcmp(argv[i], "-statserv") == 0){ - if (! (argc > 2)) - return -1; - const char *p = argv[i+1]; - const char *q = strrchr(p, ':'); - if (q == 0) - return -1; - snprintf(statHost, sizeof(statHost), "%.*s", q-p, p); - statPort = atoi(q+1); - statEnable = true; - argc -= 1; - i++; - }else if (strcmp(argv[i], "-statfreq") == 0){ - if (! (argc > 2)) - return -1; - statFreq = atoi(argv[i+1]); - if (statFreq < 1) - return -1; - argc -= 1; - i++; -#endif - }else{ - return -1; - } - argc -= 1; - i++; - } - return 0; -} - -static void sleepBeforeStartingTest(int seconds){ - if (seconds > 0){ - ndbout << "Sleeping(" <getDictionary()->createTable(tmpTable) == -1){ - return -1; - } - ndbout << "done" << endl; - } - - return 0; -} - - -static void input_error(){ - ndbout << endl << "Invalid argument!" << endl; - ndbout << endl << "Arguments:" << endl; - ndbout << " -t Number of threads to start, default 1" << endl; - ndbout << " -o Number of operations per loop, default 500" << endl; - ndbout << " -l Number of loops to run, default 1, 0=infinite" << endl; - ndbout << " -a Number of attributes, default 25" << endl; - ndbout << " -c Number of tables, default 1" << endl; - ndbout << " -s Size of each attribute, default 1 (Primary Key is always of size 1," << endl; - ndbout << " independent of this value)" << endl; - ndbout << " -lkn Number of long primary keys, default 1" << endl; - ndbout << " -lks Size of each long primary key, default 1" << endl; - - ndbout << " -simple Use simple read to read from database" << endl; - ndbout << " -dirty Use dirty read to read from database" << endl; - ndbout << " -write Use writeTuple in insert and update" << endl; - ndbout << " -stdtables Use standard table names" << endl; - ndbout << " -no_table_create Don't create tables in db" << endl; - ndbout << " -sleep Sleep a number of seconds before running the test, this" << endl; - ndbout << " can be used so that another flexBench have time to create tables" << endl; - ndbout << " -temp Use tables without logging" << endl; - ndbout << " -verify Verify inserts, updates and deletes" << endl ; - theErrorData.printCmdLineArgs(ndbout); - ndbout << endl <<"Returns:" << endl; - ndbout << "\t 0 - Test passed" << endl; - ndbout << "\t 1 - Test failed" << endl; - ndbout << "\t 2 - Invalid arguments" << endl << endl; -} - -// vim: set sw=2: diff --git a/ndb/test/ndbapi/flexBench/ndbplot.pl b/ndb/test/ndbapi/flexBench/ndbplot.pl deleted file mode 100755 index b16f6d5897d..00000000000 --- a/ndb/test/ndbapi/flexBench/ndbplot.pl +++ /dev/null @@ -1,305 +0,0 @@ -#! /usr/bin/perl - -use strict; -use Getopt::Long; -use Symbol; -use Socket; - -my $progname = $0; -$progname =~ s!^.*/|\.pl$!!g; -my $defaultport = 27127; -my $defaulttotal = 120; -my $defaultsample = 5; -my $defaultrange = 5000; - -sub printhelp { - print < \$helpflag, - 'debug' => \$debug, - 'port=i' => \$serverport, - 'total=i' => \$totaltime, - 'sample=i' => \$sampletime, - 'range=i' => \$range, - 'nopct' => \$nopct, - 'z=s' => \@zopts, -) or die "try: $progname -h\n"; -$helpflag && printhelp(); - -# calculate number of data points -my $samplecnt; -$samplecnt = int($totaltime / $sampletime) + 1; -$totaltime = ($samplecnt - 1) * $sampletime; -warn "total time = $totaltime sec, sample time = $sampletime sec\n"; - -# open gnuplot -my $plotfile; -sub openplot { - $plotfile = gensym(); - if (! open($plotfile, "| gnuplot @zopts")) { - die "open plot: $!\n"; - } - my $sav = select($plotfile); - $| = 1; - select($sav); - print $plotfile "clear\n"; -} - -# samples -my @sample; # samples 0..$samplecnt in time order -my $sampleready = 0; # samples 1..$samplecnt are ready (true/false) - -@sample = map({ start => 0 }, 0..$samplecnt); - -sub adddata { - my($node, $type, $value) = @_; - my $now = time; - my $s = $sample[0]; - if ($now - $s->{start} >= $sampletime) { - unshift(@sample, { - start => $now, - total => 0, - }); - $s = $sample[0]; - pop(@sample); # delete oldest - $sampleready = 1; - } - # if no type then this is just a time tick - if ($type) { - $s->{$type} += $value; - $s->{total} += $value; - } -} - -# data file name -my $datadir; -if ($ENV{NDB_BASE}) { - $datadir = "$ENV{NDB_BASE}/var/plot"; -} else { - $datadir = "/var/tmp"; -} -(-d $datadir || mkdir($datadir, 0777)) - or die "mkdir $datadir failed: $!\n"; -my $datafile = "$datadir/plot$$.dat"; -warn "writing plot data to $datafile\n"; - -# refresh the plot -sub plotsample { - my $fh = gensym(); - if (! open($fh, ">$datafile")) { - die "$datafile: $!\n"; - } - # sample 0 is never ready - my $currops = ""; - my $currpct = {}; - for (my $i = @sample; $i >= 1; $i--) { - my $s = $sample[$i]; - if (! $s->{start}) { # initial empty sample - next; - } - printf $fh "%d", -($i - 1) * $sampletime; - printf $fh " %.0f", 1.01 * $s->{"total"} / $sampletime; - for my $k (qw(insert update select delete)) { - printf $fh " %.0f", $s->{$k} / $sampletime; - } - printf $fh "\n"; - if ($i == 1) { - $currops = sprintf("%.0f", $s->{"total"} / $sampletime); - if (! $nopct && $currops > 0) { - $currpct->{"total"} = sprintf("%5s", ""); - for my $k (qw(insert update select delete)) { - $currpct->{$k} = sprintf(" %3.0f%%", - 100.0 * $s->{$k} / $s->{"total"}); - } - } - } - } - close($fh); - print $plotfile <{insert}" \\ - with lines lt 2, \\ - '$datafile' \\ - using 1:4 \\ - title "update$currpct->{update}" \\ - with lines lt 3, \\ - '$datafile' \\ - using 1:5 \\ - title "select$currpct->{select}" \\ - with lines lt 4, \\ - '$datafile' \\ - using 1:6 \\ - title "delete$currpct->{delete}" \\ - with lines lt 5, \\ - '$datafile' \\ - using 1:2 \\ - title "total$currpct->{total}" \\ - with lines lt 1 lw 2 -END -} - -# set up server socket -my $sock = gensym(); -if (! socket($sock, PF_INET, SOCK_STREAM, getprotobyname("tcp"))) { - die "socket: $!\n"; -} -if (! setsockopt($sock, SOL_SOCKET, SO_REUSEADDR, pack("l*", 1))) { - die "setsockopt: $!\n"; -} -if (! bind($sock, pack_sockaddr_in($serverport, INADDR_ANY))) { - die "bind: $!\n"; -} -if (! listen($sock, SOMAXCONN)) { - die "listen: $!\n"; -} - -# bit vectors for select on server socket and clients -my $readin = ''; -vec($readin, fileno($sock), 1) = 1; - -# clients -my @client = (); -my $clientid = 0; -sub addclient { - my($conn) = @_; - my $c = { - conn => $conn, - data => "", - name => "client " . ++$clientid, - }; - push(@client, $c); - vec($readin, fileno($c->{conn}), 1) = 1; - if (1 || $debug) { - warn "added $c->{name}\n"; - } -} -sub deleteclient { - my($c) = @_; - @client = grep($_ ne $c, @client); - vec($readin, fileno($c->{conn}), 1) = 0; - shutdown($c->{conn}, 2); - if (1 || $debug) { - warn "deleted $c->{name}\n"; - } -} -sub readclient { - my($c) = @_; - my $data; - my $n; - eval { - local $SIG{ALRM} = sub { die "timeout\n" }; - alarm(5); - $n = sysread($c->{conn}, $data, 512); - alarm(0); - }; - if ($@) { - chomp($@); - warn "$c->{name}: read: $@\n"; - return undef; - } - if (!defined($n)) { - warn "$c->{name}: read: $!\n"; - return undef; - } - $c->{data} .= $data; - if ($debug) { - warn "$c->{name}: read @{[ length($data) ]} bytes\n"; - } - return $n; -} -sub processclient { - my($c) = @_; - my $i; - while (($i = index($c->{data}, "\n")) >= 0) { - my $line = substr($c->{data}, 0, $i); - $c->{data} = substr($c->{data}, $i+1); - my($node, $type, $value) = split(' ', $line); - if ($node !~ /^\d+$/) { - warn "$c->{name}: $line: bad node id\n"; - next; - } - if ($type !~ /^(insert|update|read|delete|verify|verifydelete)$/) { - warn "$c->{name}: $line: bad type\n"; - next; - } - if ($value !~ /^\d+$/) { - warn "$c->{name}: $line: bad value\n"; - next; - } - if ($type eq "read") { - $type = "select"; - } - adddata($node, $type, $value); - } -} - -# main loop -openplot(); -while (1) { - my $readout = ''; - my $ret = select($readout = $readin, undef, undef, 1.0); - if (vec($readout, fileno($sock), 1)) { - my $conn = gensym(); - if (! accept($conn, $sock)) { - warn "accept failed: $!\n"; - } else { - addclient($conn); - } - } - for my $c (@client) { - if (vec($readout, fileno($c->{conn}), 1)) { - my $n = readclient($c); - if (! defined($n)) { - deleteclient($c); - } else { - processclient($c); - if ($n == 0) { # end of file - deleteclient($c); - } - } - } - } - adddata(); # keep clock ticking - if ($sampleready) { - if ($debug) { - warn "sample ready\n"; - } - plotsample(); - $sampleready = 0; - } -} -# vim: set sw=4: diff --git a/ndb/test/ndbapi/flexHammer.cpp b/ndb/test/ndbapi/flexHammer.cpp new file mode 100644 index 00000000000..057efb31e74 --- /dev/null +++ b/ndb/test/ndbapi/flexHammer.cpp @@ -0,0 +1,889 @@ +/* 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 */ + +/* *************************************************** + FLEXHAMMER + Hammer ndb with read, insert, update and delete transactions. + + Arguments: + -t Number of threads to start, default 1 + -o Number of operations per hammering-round, default 500 + -l Number of loops to run, default 1, 0=infinite + -a Number of attributes, default 25 + -c Number of tables, default 1 + -s Size of each attribute, default 1 + -simple Use simple read to read from database + -dirty Use dirty read to read from database + -write Use writeTuple to write to db + -r Number of records to Hammer + -no_table_create Don't create tables in db + -regulate To be able to regulate the load flexHammer produces. + -stdtables Use standard table names + -sleep Sleep a number of seconds before running the test, this + can be used so that another flexProgram have tome to create tables + + Returns: + 0 - Test passed + -1 - Test failed + 1 - Invalid arguments + +Revision history: + 1.7 020208 epesson: Adapted to use NDBT + 1.10 020222 epesson: Finalised handling of thread results + 1.11 020222 epesson: Bug in checking results during delete fixed + + * *************************************************** */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +ErrorData * flexHammerErrorData; + +#if defined NDB_OSE || defined NDB_SOFTOSE +#include +#endif + +#define MAXSTRLEN 16 +#define MAXATTR 64 +#define MAXTABLES 64 +#define MAXTHREADS 256 +#define MAXATTRSIZE 100 +// Max number of retries if something fails +#define MaxNoOfAttemptsC 10 + +enum StartType { + stIdle, + stHammer, + stStop, + stLast}; + +enum MyOpType { + otInsert, + otRead, + otDelete, + otUpdate, + otLast}; + +struct ThreadNdb { + int threadNo; + NdbThread* threadLife; + int threadReady; + StartType threadStart; + int threadResult;}; + +extern "C" void* flexHammerThread(void*); +static int setAttrNames(void); +static int setTableNames(void); +static int readArguments(int, const char**); +static int createTables(Ndb*); +static void sleepBeforeStartingTest(int seconds); +static int checkThreadResults(ThreadNdb *threadArrayP, char* phase); + +//enum OperationType { +// otInsert, +// otRead, +// otUpdate, +// otDelete, +// otVerifyDelete, +// otLast }; + +enum ReadyType { + stReady, + stRunning +} ; +static int tNoOfThreads; +static int tNoOfAttributes; +static int tNoOfTables; +static int tNoOfBackups; +static int tAttributeSize; +static int tNoOfOperations; +static int tNoOfRecords; +static int tNoOfLoops; +static ReadyType ThreadReady[MAXTHREADS]; +static StartType ThreadStart[MAXTHREADS]; +static char tableName[MAXTABLES][MAXSTRLEN]; +static char attrName[MAXATTR][MAXSTRLEN]; +static int theSimpleFlag = 0; +static int theWriteFlag = 0; +static int theDirtyFlag = 0; +static int theTableCreateFlag = 0; +static int theStandardTableNameFlag = 0; +static unsigned int tSleepTime = 0; + +#define START_TIMER { NdbTimer timer; timer.doStart(); +#define STOP_TIMER timer.doStop(); +#define PRINT_TIMER(text, trans, opertrans) timer.printTransactionStatistics(text, trans, opertrans); }; + + +// Initialise thread data +void +resetThreads(ThreadNdb *threadArrayP) { + + for (int i = 0; i < tNoOfThreads ; i++) + { + threadArrayP[i].threadReady = 0; + threadArrayP[i].threadResult = 0; + threadArrayP[i].threadStart = stIdle; + } +} // resetThreads + +void +waitForThreads(ThreadNdb *threadArrayP) +{ + int cont = 1; + + while (cont) { + NdbSleep_MilliSleep(100); + cont = 0; + for (int i = 0; i < tNoOfThreads ; i++) { + if (threadArrayP[i].threadReady == 0) { + cont = 1; + } // if + } // for + } // while +} // waitForThreads + +void +tellThreads(ThreadNdb* threadArrayP, const StartType what) +{ + for (int i = 0; i < tNoOfThreads ; i++) + { + threadArrayP[i].threadStart = what; + } // for +} // tellThreads + +NDB_COMMAND(flexHammer, "flexHammer", "flexHammer", "flexHammer", 65535) +//main(int argc, const char** argv) +{ + ThreadNdb* pThreads = NULL; // Pointer to thread data array + Ndb* pMyNdb = NULL; // Pointer to Ndb object + int tLoops = 0; + int returnValue = 0; + int check = 0; + + flexHammerErrorData = new ErrorData; + + flexHammerErrorData->resetErrorCounters(); + + if (readArguments(argc, argv) != 0) { + ndbout << "Wrong arguments to flexHammer" << endl; + return NDBT_ProgramExit(NDBT_WRONGARGS); + } // if + + /* print Setting */ + flexHammerErrorData->printSettings(ndbout); + + check = setAttrNames(); + if (check == -1) { + ndbout << "Couldn't set attribute names" << endl; + return NDBT_ProgramExit(NDBT_FAILED); + } // if + check = setTableNames(); + if (check == -1) { + ndbout << "Couldn't set table names" << endl; + return NDBT_ProgramExit(NDBT_FAILED); + } // if + + // Create thread data array + pThreads = new ThreadNdb[tNoOfThreads]; + // NdbThread_SetConcurrencyLevel(tNoOfThreads + 2); + + // Create and init Ndb object + pMyNdb = new Ndb("TEST_DB"); + pMyNdb->init(); + + // Wait for Ndb to become ready + if (pMyNdb->waitUntilReady(10000) != 0) { + ndbout << "NDB is not ready" << endl << "Benchmark failed" << endl; + returnValue = NDBT_FAILED; + } + + else { + check = createTables(pMyNdb); + if (check != 0) { + returnValue = NDBT_FAILED; + } // if + else { + sleepBeforeStartingTest(tSleepTime); + + // Create threads. * + resetThreads(pThreads); + for (int i = 0; i < tNoOfThreads ; i++) { + pThreads[i].threadNo = i; + pThreads[i].threadLife = NdbThread_Create(flexHammerThread, + (void**)&pThreads[i], + 65535, + "flexHammerThread", + NDB_THREAD_PRIO_LOW); + } // for + + // And wait until they are ready + waitForThreads(pThreads); + if (checkThreadResults(pThreads, "init") != 0) { + returnValue = NDBT_FAILED; + } // if + + + if (returnValue == NDBT_OK) { + ndbout << endl << "All threads started" << endl << endl; + + for(;;) { + + // Check if it's time to exit program + if((tNoOfLoops != 0) && (tNoOfLoops <= tLoops)) + break; + + // Tell all threads to start hammer + ndbout << "Hammering..." << endl; + + resetThreads(pThreads); + + START_TIMER; + tellThreads(pThreads, stHammer); + + waitForThreads(pThreads); + ndbout << "Threads ready to continue..." << endl; + STOP_TIMER; + + // Check here if anything went wrong + if (checkThreadResults(pThreads, "hammer") != 0) { + ndbout << "Thread(s) failed." << endl; + returnValue = NDBT_FAILED; + } // if + + PRINT_TIMER("hammer", tNoOfOperations*tNoOfThreads, tNoOfTables*6); + + ndbout << endl; + + tLoops++; + + } // for + } // if + + // Signaling threads to stop + resetThreads(pThreads); + tellThreads(pThreads, stStop); + + // Wait for threads to stop + waitForThreads(pThreads); + + ndbout << "----------------------------------------------" << endl << endl; + ndbout << "Benchmark completed" << endl; + } // else + } // else + // Clean up + + flexHammerErrorData->printErrorCounters(ndbout); + + // Kill them all! + void* tmp; + for(int i = 0; i < tNoOfThreads; i++){ + NdbThread_WaitFor(pThreads[i].threadLife, &tmp); + NdbThread_Destroy(&pThreads[i].threadLife); + } + delete flexHammerErrorData; + delete [] pThreads; + delete pMyNdb; + + // Exit via NDBT + return NDBT_ProgramExit(returnValue); + +} //main + +extern "C" +void* +flexHammerThread(void* pArg) +{ + ThreadNdb* pThreadData = (ThreadNdb*)pArg; + unsigned int threadNo = pThreadData->threadNo; + Ndb* pMyNdb = NULL ; + NdbConnection *pMyTransaction = NULL ; + // NdbOperation* pMyOperation[MAXTABLES] = {NULL}; + NdbOperation* pMyOperation[MAXTABLES]; + int check = 0; + int loop_count_ops = 0; + int loop_count_tables = 0; + int loop_count_attributes = 0; + int count_round = 0; + int count = 0; + int count_tables = 0; + int count_attributes = 0; + int i = 0; + int j = 0; + int tThreadResult = 0; + MyOpType tMyOpType = otLast; + int pkValue = 0; + int readValue[MAXATTR][MAXATTRSIZE] = {0}; + int attrValue[MAXATTRSIZE]; + NdbRecAttr* tTmp = NULL; + int tNoOfAttempts = 0; + + for (i = 0; i < MAXATTRSIZE; i++) + attrValue[i] = 0; + // Ndb object for each thread + pMyNdb = new Ndb( "TEST_DB" ); + pMyNdb->init(); + if (pMyNdb->waitUntilReady(10000) != 0) { + // Error, NDB is not ready + tThreadResult = 99; + // Go to idle directly + pThreadData->threadStart = stIdle; + } // if + + for(;;) { + pThreadData->threadResult = tThreadResult; + pThreadData->threadReady = 1; // Signalling ready to main + + // If Idle just wait to be stopped from main + while (pThreadData->threadStart == stIdle) { + NdbSleep_MilliSleep(100); + } // while + + // Check if signal to exit is received + if (pThreadData->threadStart == stStop) { + pThreadData->threadReady = 1; + // break out of eternal loop + break; + } // if + + // Set to Idle to prepare for possible error break + pThreadData->threadStart = stIdle; + + // Prepare transaction + loop_count_ops = tNoOfOperations; + loop_count_tables = tNoOfTables; + loop_count_attributes = tNoOfAttributes; + + for (count=0 ; count < loop_count_ops ; count++) { + + //pkValue = (int)(count + thread_base); + // This limits the number of records used in this test + pkValue = count % tNoOfRecords; + + for (count_round = 0; count_round < 5; ) { + switch (count_round) { + case 0: // Insert + tMyOpType = otInsert; + // Increase attrValues + for (i=0; i < MAXATTRSIZE; i ++) { + attrValue[i]++; + } + break; + case 1: + case 3: // Read and verify + tMyOpType = otRead; + break; + case 2: // Update + // Increase attrValues + for(i=0; i < MAXATTRSIZE; i ++) { + attrValue[i]++; + } + tMyOpType = otUpdate; + break; + case 4: // Delete + tMyOpType = otDelete; + break; + default: + assert(false); + break; + } // switch + + // Get transaction object + pMyTransaction = pMyNdb->startTransaction(); + if (pMyTransaction == NULL) { + // Fatal error + tThreadResult = 1; + // break out of for count_round loop waiting to be stopped by main + break; + } // if + + for (count_tables = 0; count_tables < loop_count_tables; + count_tables++) { + pMyOperation[count_tables] = + pMyTransaction->getNdbOperation(tableName[count_tables]); + if (pMyOperation[count_tables] == NULL) { + //Fatal error + tThreadResult = 2; + // break out of inner for count_tables loop + break; + } // if + + switch (tMyOpType) { + case otInsert: // Insert case + if (theWriteFlag == 1 && theDirtyFlag == 1) { + check = pMyOperation[count_tables]->dirtyWrite(); + } else if (theWriteFlag == 1) { + check = pMyOperation[count_tables]->writeTuple(); + } else { + check = pMyOperation[count_tables]->insertTuple(); + } // if else + break; + case otRead: // Read Case + if (theSimpleFlag == 1) { + check = pMyOperation[count_tables]->simpleRead(); + } else if (theDirtyFlag == 1) { + check = pMyOperation[count_tables]->dirtyRead(); + } else { + check = pMyOperation[count_tables]->readTuple(); + } // if else + break; + case otUpdate: // Update Case + if (theWriteFlag == 1 && theDirtyFlag == 1) { + check = pMyOperation[count_tables]->dirtyWrite(); + } else if (theWriteFlag == 1) { + check = pMyOperation[count_tables]->writeTuple(); + } else if (theDirtyFlag == 1) { + check = pMyOperation[count_tables]->dirtyUpdate(); + } else { + check = pMyOperation[count_tables]->updateTuple(); + } // if else + break; + case otDelete: // Delete Case + check = pMyOperation[count_tables]->deleteTuple(); + break; + default: + assert(false); + break; + } // switch + if (check == -1) { + // Fatal error + tThreadResult = 3; + // break out of inner for count_tables loop + break; + } // if + + check = pMyOperation[count_tables]->equal( (char*)attrName[0], + (char*)&pkValue ); + + if (check == -1) { + // Fatal error + tThreadResult = 4; + ndbout << "pMyOperation equal failed" << endl; + // break out of inner for count_tables loop + break; + } // if + + check = -1; + tTmp = NULL; + switch (tMyOpType) { + case otInsert: // Insert case + case otUpdate: // Update Case + for (count_attributes = 1; count_attributes < loop_count_attributes; + count_attributes++) { + check = + pMyOperation[count_tables]->setValue((char*)attrName[count_attributes], (char*)&attrValue[0]); + } // for + break; + case otRead: // Read Case + for (count_attributes = 1; count_attributes < loop_count_attributes; + count_attributes++) { + tTmp = pMyOperation[count_tables]-> + getValue( (char*)attrName[count_attributes], + (char*)&readValue[count_attributes][0] ); + } // for + break; + case otDelete: // Delete Case + break; + default: + assert(false); + break; + } // switch + if (check == -1 && tTmp == NULL && tMyOpType != otDelete) { + // Fatal error + tThreadResult = 5; + break; + } // if + } // for count_tables + + // Only execute if everything is OK + if (tThreadResult != 0) { + // Close transaction (below) + // and continue with next count_round + count_round++; + tNoOfAttempts = 0; + } // if + else { + check = pMyTransaction->execute(Commit); + if (check == -1 ) { + const NdbError & err = pMyTransaction->getNdbError(); + + // Add complete error handling here + + int retCode = flexHammerErrorData->handleErrorCommon(pMyTransaction->getNdbError()); + if (retCode == 1) { + //if (strcmp(pMyTransaction->getNdbError().message, "Tuple did not exist") != 0 && strcmp(pMyTransaction->getNdbError().message,"Tuple already existed when attempting to insert") != 0) ndbout_c("execute: %s", pMyTransaction->getNdbError().message); + + if (pMyTransaction->getNdbError().code != 626 && pMyTransaction->getNdbError().code != 630){ + ndbout_c("Error code = %d", pMyTransaction->getNdbError().code); + ndbout_c("execute: %s", pMyTransaction->getNdbError().message);} + + } else if (retCode == 2) { + ndbout << "4115 should not happen in flexHammer" << endl; + } else if (retCode == 3) { +// -------------------------------------------------------------------- +// We are not certain if the transaction was successful or not. +// We must reexecute but might very well find that the transaction +// actually was updated. Updates and Reads are no problem here. Inserts +// will not cause a problem if error code 630 arrives. Deletes will +// not cause a problem if 626 arrives. +// -------------------------------------------------------------------- + /* What can we do here? */ + ndbout_c("execute: %s", pMyTransaction->getNdbError().message); + }//if(retCode == 3) + // End of adding complete error handling + + switch( err.classification) { + case NdbError::ConstraintViolation: // Tuple already existed + count_round++; + tNoOfAttempts = 0; + break; + case NdbError::TimeoutExpired: + case NdbError::NodeRecoveryError: + case NdbError::TemporaryResourceError: + case NdbError::OverloadError: + if (tNoOfAttempts <= MaxNoOfAttemptsC) { + // Retry + tNoOfAttempts++; + } else { + // Too many retries, continue with next + count_round++; + tNoOfAttempts = 0; + } // else if + break; + // Fatal, just continue + default: + count_round++; + tNoOfAttempts = 0; + break; + } // switch + } // if + else { + // Execute commit was OK + // This is verifying read values + //switch (tMyOpType) { + //case otRead: // Read case + //for (j = 0; j < tNoOfAttributes; j++) { + //for(i = 1; i < tAttributeSize; i++) { + //if ( readValue[j][i] != attrValue[i]) { + //ndbout << "pkValue = " << pkValue << endl; + //ndbout << "readValue != attrValue" << endl; + //ndbout << readValue[j][i] << " != " << attrValue[i] << endl; + //} // if + // } // for + //} // for + //break; + //} // switch + count_round++; + tNoOfAttempts = 0; + } // else if + } // else if + pMyNdb->closeTransaction(pMyTransaction); + } // for count_round + } // for count + } // for (;;) + + // Clean up + delete pMyNdb; + pMyNdb = NULL; + + flexHammerErrorData->resetErrorCounters(); + + // And exit using NDBT + NdbThread_Exit(0); + + return NULL; + +} // flexHammerThread + + +int +readArguments (int argc, const char** argv) +{ + int i = 1; + + tNoOfThreads = 5; // Default Value + tNoOfOperations = 500; // Default Value + tNoOfRecords = 1; // Default Value + tNoOfLoops = 1; // Default Value + tNoOfAttributes = 25; // Default Value + tNoOfTables = 1; // Default Value + tNoOfBackups = 0; // Default Value + tAttributeSize = 1; // Default Value + theTableCreateFlag = 0; + + while (argc > 1) { + if (strcmp(argv[i], "-t") == 0) { + tNoOfThreads = atoi(argv[i+1]); + if ((tNoOfThreads < 1) || (tNoOfThreads > MAXTHREADS)) + return(1); + } + else if (strcmp(argv[i], "-o") == 0) { + tNoOfOperations = atoi(argv[i+1]); + if (tNoOfOperations < 1) + return(1); + } + else if (strcmp(argv[i], "-r") == 0) { + tNoOfRecords = atoi(argv[i+1]); + if (tNoOfRecords < 1) + return(1); + } + else if (strcmp(argv[i], "-a") == 0) { + tNoOfAttributes = atoi(argv[i+1]); + if ((tNoOfAttributes < 2) || (tNoOfAttributes > MAXATTR)) + return(1); + } + else if (strcmp(argv[i], "-c") == 0) { + tNoOfTables = atoi(argv[i+1]); + if ((tNoOfTables < 1) || (tNoOfTables > MAXTABLES)) + return(1); + } + else if (strcmp(argv[i], "-l") == 0) { + tNoOfLoops = atoi(argv[i+1]); + if ((tNoOfLoops < 0) || (tNoOfLoops > 100000)) + return(1); + } + else if (strcmp(argv[i], "-s") == 0) { + tAttributeSize = atoi(argv[i+1]); + if ((tAttributeSize < 1) || (tAttributeSize > MAXATTRSIZE)) + return(1); + } + else if (strcmp(argv[i], "-sleep") == 0) { + tSleepTime = atoi(argv[i+1]); + if ((tSleepTime < 1) || (tSleepTime > 3600)) + exit(-1); + } + else if (strcmp(argv[i], "-simple") == 0) { + theSimpleFlag = 1; + argc++; + i--; + } + else if (strcmp(argv[i], "-write") == 0) { + theWriteFlag = 1; + argc++; + i--; + } + else if (strcmp(argv[i], "-dirty") == 0) { + theDirtyFlag = 1; + argc++; + i--; + } + else if (strcmp(argv[i], "-no_table_create") == 0) { + theTableCreateFlag = 1; + argc++; + i--; + } + else if (strcmp(argv[i], "-stdtables") == 0) { + theStandardTableNameFlag = 1; + argc++; + i--; + } // if + else { + return(1); + } + + argc -= 2; + i = i + 2; + } // while + + ndbout << endl << "FLEXHAMMER - Starting normal mode" << endl; + ndbout << "Hammer ndb with read, insert, update and delete transactions"<< endl << endl; + + ndbout << " " << tNoOfThreads << " thread(s) " << endl; + ndbout << " " << tNoOfLoops << " iterations " << endl; + ndbout << " " << tNoOfTables << " table(s) and " << 1 << " operation(s) per transaction " << endl; + ndbout << " " << tNoOfRecords << " records to hammer(limit this with the -r option)" << endl; + ndbout << " " << tNoOfAttributes << " attributes per table " << endl; + ndbout << " " << tNoOfOperations << " transaction(s) per thread and round " << endl; + ndbout << " " << tAttributeSize << " is the number of 32 bit words per attribute " << endl << endl; + return 0; +} // readArguments + + +void sleepBeforeStartingTest(int seconds) +{ + if (seconds > 0) { + ndbout << "Sleeping(" << seconds << ")..."; + NdbSleep_SecSleep(seconds); + ndbout << " done!" << endl; + } // if +} // sleepBeforeStartingTest + +static int +createTables(Ndb* pMyNdb) +{ + int i = 0; + int j = 0; + int check = 0; + NdbSchemaCon *MySchemaTransaction = NULL; + NdbSchemaOp *MySchemaOp = NULL; + + // Create Table and Attributes. + if (theTableCreateFlag == 0) { + + for (i = 0; i < tNoOfTables; i++) { + + ndbout << "Creating " << tableName[i] << "..."; + // Check if table exists already + const void * p = pMyNdb->getDictionary()->getTable(tableName[i]); + if (p != 0) { + ndbout << " already exists." << endl; + // Continue with next table at once + continue; + } // if + ndbout << endl; + + MySchemaTransaction = pMyNdb->startSchemaTransaction(); + if (MySchemaTransaction == NULL) { + return(-1); + } // if + + MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); + if (MySchemaOp == NULL) { + // Clean up opened schema transaction + pMyNdb->closeSchemaTransaction(MySchemaTransaction); + return(-1); + } // if + + // Create tables, rest of parameters are default right now +#if defined NDB_OSE || defined NDB_SOFTOSE + check = MySchemaOp->createTable(tableName[i], + 8, // Table Size + TupleKey, // Key Type + 40, // Nr of Pages + All, + 6, + 78, + 80, + 1, + false); + +#else + check = MySchemaOp->createTable(tableName[i], + 8, // Table Size + TupleKey, // Key Type + 40); // Nr of Pages +#endif + if (check == -1) { + // Clean up opened schema transaction + pMyNdb->closeSchemaTransaction(MySchemaTransaction); + return(-1); + } // if + + // Primary key + //ndbout << " pk " << (char*)&attrName[0] << "..." << endl; + check = MySchemaOp->createAttribute( (char*)attrName[0], TupleKey, 32, + 1, UnSigned, MMBased, + NotNullAttribute ); + if (check == -1) { + // Clean up opened schema transaction + pMyNdb->closeSchemaTransaction(MySchemaTransaction); + return(-1); + } // if + + // Rest of attributes + for (j = 1; j < tNoOfAttributes ; j++) { + //ndbout << " " << (char*)attrName[j] << "..." << endl; + check = MySchemaOp->createAttribute( (char*)attrName[j], NoKey, 32, + tAttributeSize, UnSigned, MMBased, + NotNullAttribute ); + if (check == -1) { + // Clean up opened schema transaction + pMyNdb->closeSchemaTransaction(MySchemaTransaction); + return(-1); + } // if + } // for + + // Execute creation + check = MySchemaTransaction->execute(); + if (check == -1) { + // Clean up opened schema transaction + pMyNdb->closeSchemaTransaction(MySchemaTransaction); + return(-1); + } // if + + pMyNdb->closeSchemaTransaction(MySchemaTransaction); + } // for + } // if + + return(0); + +} // createTables + + +static int setAttrNames() +{ + int i = 0; + int retVal = 0; + + for (i = 0; i < MAXATTR ; i++) { + retVal = snprintf(attrName[i], MAXSTRLEN, "COL%d", i); + if (retVal < 0) { + // Error in conversion + return(-1); + } // if + } // for + + return (0); +} // setAttrNames + +static int setTableNames() +{ + // Note! Uses only uppercase letters in table name's + // so that we can look at the tables wits SQL + int i = 0; + int retVal = 0; + + for (i = 0; i < MAXTABLES ; i++) { + if (theStandardTableNameFlag == 0) { + retVal = snprintf(tableName[i], MAXSTRLEN, "TAB%d_%d", i, + NdbTick_CurrentMillisecond()/1000); + } // if + else { + retVal = snprintf(tableName[i], MAXSTRLEN, "TAB%d", i); + } // else + if (retVal < 0) { + // Error in conversion + return(-1); + } // if + } // for + + return(0); +} // setTableNames + +static int checkThreadResults(ThreadNdb *threadArrayP, char* phase) +{ + int i = 0; + + for (i = 0; i < tNoOfThreads; i++) { + if (threadArrayP[i].threadResult != 0) { + ndbout << "Thread " << i << " reported fatal error " + << threadArrayP[i].threadResult << " during " << phase << endl; + return(-1); + } // if + } // for + + return(0); +} + diff --git a/ndb/test/ndbapi/flexHammer/Makefile b/ndb/test/ndbapi/flexHammer/Makefile deleted file mode 100644 index c8e436fb7f5..00000000000 --- a/ndb/test/ndbapi/flexHammer/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := flexHammer - -SOURCES := flexHammer.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/flexHammer/README b/ndb/test/ndbapi/flexHammer/README deleted file mode 100644 index 556582aab96..00000000000 --- a/ndb/test/ndbapi/flexHammer/README +++ /dev/null @@ -1,67 +0,0 @@ - -Executing flexHammer-tests automatically -======================================== - - -It is possible to execute almost al the flexHammer-tests -automatically. The procedure contains three steps: -- increase the number of tabels (flexHammer -c number) -- increase the number of threads (flexHammer -t number) -- increase the number of records (flexHammer -r number) -- increase the number of tabels and threads alternately - -Each of these steps are performed by the scripts test1.sh, -test2.sh, test3.sh and test4.sh. Each test will start Ndb, -execute the test and close Ndb again in order to execute -each test in a 'clean' Ndb-environment. So make sure that -there is no Ndb running when you start the test. - - -1. Setup - -To perform the tests automatically, the following issues -have to be taken care of: - -- be sure that you have a directory bin in your home-directory. - In this directory, you need to have a link 'runndb' to the - ndb executable. You can do this by executing a shell-command like: - ln -s ndb/Emulator/Main/ndb runndb - The script is not yet so far that it performs checks, so if - you forget about this, things will get messy. -- In this directory you need a Ndb.cfg for a server-configuration. - - -2. Command - -I assume you have Ndb and the API compiled or you use the -'released' version. Compile flexHammer as usual with 'make'. -Now you can start the tests by typing 'make test'. The -execution of the test will take a while. - - -3. Results - -The scripts will write their results in the file report.txt. -The scripts will start with a short summary on the test. Then -it will add 1 line documenting each run of flexHammer that is -ececuted. Finally, it will print highest 'score'. The file -report.txt is probably good enough to check in directly as -testprotocol in ndb/test/docs/testprotocols. - - -4. Log files. - -To make it possible to investigate errors, the output from -the flexScan-run where the error occurred is stored in -test1.log, test2.log, test3.log or test4.log respectively. -They are overwritten each time you start 'make test'. - - -HINT - -The number of iterations in each test-script is not directly -limited by the number of attributes or the size of the -attributes but by the number of tables that you are allowed -to create. Probably this will be the error that occurs if -you execute the test. You migh adjust the begin-values and -the step-size in the individual scripts if you want. diff --git a/ndb/test/ndbapi/flexHammer/flexHammer.cpp b/ndb/test/ndbapi/flexHammer/flexHammer.cpp deleted file mode 100644 index 057efb31e74..00000000000 --- a/ndb/test/ndbapi/flexHammer/flexHammer.cpp +++ /dev/null @@ -1,889 +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 */ - -/* *************************************************** - FLEXHAMMER - Hammer ndb with read, insert, update and delete transactions. - - Arguments: - -t Number of threads to start, default 1 - -o Number of operations per hammering-round, default 500 - -l Number of loops to run, default 1, 0=infinite - -a Number of attributes, default 25 - -c Number of tables, default 1 - -s Size of each attribute, default 1 - -simple Use simple read to read from database - -dirty Use dirty read to read from database - -write Use writeTuple to write to db - -r Number of records to Hammer - -no_table_create Don't create tables in db - -regulate To be able to regulate the load flexHammer produces. - -stdtables Use standard table names - -sleep Sleep a number of seconds before running the test, this - can be used so that another flexProgram have tome to create tables - - Returns: - 0 - Test passed - -1 - Test failed - 1 - Invalid arguments - -Revision history: - 1.7 020208 epesson: Adapted to use NDBT - 1.10 020222 epesson: Finalised handling of thread results - 1.11 020222 epesson: Bug in checking results during delete fixed - - * *************************************************** */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -ErrorData * flexHammerErrorData; - -#if defined NDB_OSE || defined NDB_SOFTOSE -#include -#endif - -#define MAXSTRLEN 16 -#define MAXATTR 64 -#define MAXTABLES 64 -#define MAXTHREADS 256 -#define MAXATTRSIZE 100 -// Max number of retries if something fails -#define MaxNoOfAttemptsC 10 - -enum StartType { - stIdle, - stHammer, - stStop, - stLast}; - -enum MyOpType { - otInsert, - otRead, - otDelete, - otUpdate, - otLast}; - -struct ThreadNdb { - int threadNo; - NdbThread* threadLife; - int threadReady; - StartType threadStart; - int threadResult;}; - -extern "C" void* flexHammerThread(void*); -static int setAttrNames(void); -static int setTableNames(void); -static int readArguments(int, const char**); -static int createTables(Ndb*); -static void sleepBeforeStartingTest(int seconds); -static int checkThreadResults(ThreadNdb *threadArrayP, char* phase); - -//enum OperationType { -// otInsert, -// otRead, -// otUpdate, -// otDelete, -// otVerifyDelete, -// otLast }; - -enum ReadyType { - stReady, - stRunning -} ; -static int tNoOfThreads; -static int tNoOfAttributes; -static int tNoOfTables; -static int tNoOfBackups; -static int tAttributeSize; -static int tNoOfOperations; -static int tNoOfRecords; -static int tNoOfLoops; -static ReadyType ThreadReady[MAXTHREADS]; -static StartType ThreadStart[MAXTHREADS]; -static char tableName[MAXTABLES][MAXSTRLEN]; -static char attrName[MAXATTR][MAXSTRLEN]; -static int theSimpleFlag = 0; -static int theWriteFlag = 0; -static int theDirtyFlag = 0; -static int theTableCreateFlag = 0; -static int theStandardTableNameFlag = 0; -static unsigned int tSleepTime = 0; - -#define START_TIMER { NdbTimer timer; timer.doStart(); -#define STOP_TIMER timer.doStop(); -#define PRINT_TIMER(text, trans, opertrans) timer.printTransactionStatistics(text, trans, opertrans); }; - - -// Initialise thread data -void -resetThreads(ThreadNdb *threadArrayP) { - - for (int i = 0; i < tNoOfThreads ; i++) - { - threadArrayP[i].threadReady = 0; - threadArrayP[i].threadResult = 0; - threadArrayP[i].threadStart = stIdle; - } -} // resetThreads - -void -waitForThreads(ThreadNdb *threadArrayP) -{ - int cont = 1; - - while (cont) { - NdbSleep_MilliSleep(100); - cont = 0; - for (int i = 0; i < tNoOfThreads ; i++) { - if (threadArrayP[i].threadReady == 0) { - cont = 1; - } // if - } // for - } // while -} // waitForThreads - -void -tellThreads(ThreadNdb* threadArrayP, const StartType what) -{ - for (int i = 0; i < tNoOfThreads ; i++) - { - threadArrayP[i].threadStart = what; - } // for -} // tellThreads - -NDB_COMMAND(flexHammer, "flexHammer", "flexHammer", "flexHammer", 65535) -//main(int argc, const char** argv) -{ - ThreadNdb* pThreads = NULL; // Pointer to thread data array - Ndb* pMyNdb = NULL; // Pointer to Ndb object - int tLoops = 0; - int returnValue = 0; - int check = 0; - - flexHammerErrorData = new ErrorData; - - flexHammerErrorData->resetErrorCounters(); - - if (readArguments(argc, argv) != 0) { - ndbout << "Wrong arguments to flexHammer" << endl; - return NDBT_ProgramExit(NDBT_WRONGARGS); - } // if - - /* print Setting */ - flexHammerErrorData->printSettings(ndbout); - - check = setAttrNames(); - if (check == -1) { - ndbout << "Couldn't set attribute names" << endl; - return NDBT_ProgramExit(NDBT_FAILED); - } // if - check = setTableNames(); - if (check == -1) { - ndbout << "Couldn't set table names" << endl; - return NDBT_ProgramExit(NDBT_FAILED); - } // if - - // Create thread data array - pThreads = new ThreadNdb[tNoOfThreads]; - // NdbThread_SetConcurrencyLevel(tNoOfThreads + 2); - - // Create and init Ndb object - pMyNdb = new Ndb("TEST_DB"); - pMyNdb->init(); - - // Wait for Ndb to become ready - if (pMyNdb->waitUntilReady(10000) != 0) { - ndbout << "NDB is not ready" << endl << "Benchmark failed" << endl; - returnValue = NDBT_FAILED; - } - - else { - check = createTables(pMyNdb); - if (check != 0) { - returnValue = NDBT_FAILED; - } // if - else { - sleepBeforeStartingTest(tSleepTime); - - // Create threads. * - resetThreads(pThreads); - for (int i = 0; i < tNoOfThreads ; i++) { - pThreads[i].threadNo = i; - pThreads[i].threadLife = NdbThread_Create(flexHammerThread, - (void**)&pThreads[i], - 65535, - "flexHammerThread", - NDB_THREAD_PRIO_LOW); - } // for - - // And wait until they are ready - waitForThreads(pThreads); - if (checkThreadResults(pThreads, "init") != 0) { - returnValue = NDBT_FAILED; - } // if - - - if (returnValue == NDBT_OK) { - ndbout << endl << "All threads started" << endl << endl; - - for(;;) { - - // Check if it's time to exit program - if((tNoOfLoops != 0) && (tNoOfLoops <= tLoops)) - break; - - // Tell all threads to start hammer - ndbout << "Hammering..." << endl; - - resetThreads(pThreads); - - START_TIMER; - tellThreads(pThreads, stHammer); - - waitForThreads(pThreads); - ndbout << "Threads ready to continue..." << endl; - STOP_TIMER; - - // Check here if anything went wrong - if (checkThreadResults(pThreads, "hammer") != 0) { - ndbout << "Thread(s) failed." << endl; - returnValue = NDBT_FAILED; - } // if - - PRINT_TIMER("hammer", tNoOfOperations*tNoOfThreads, tNoOfTables*6); - - ndbout << endl; - - tLoops++; - - } // for - } // if - - // Signaling threads to stop - resetThreads(pThreads); - tellThreads(pThreads, stStop); - - // Wait for threads to stop - waitForThreads(pThreads); - - ndbout << "----------------------------------------------" << endl << endl; - ndbout << "Benchmark completed" << endl; - } // else - } // else - // Clean up - - flexHammerErrorData->printErrorCounters(ndbout); - - // Kill them all! - void* tmp; - for(int i = 0; i < tNoOfThreads; i++){ - NdbThread_WaitFor(pThreads[i].threadLife, &tmp); - NdbThread_Destroy(&pThreads[i].threadLife); - } - delete flexHammerErrorData; - delete [] pThreads; - delete pMyNdb; - - // Exit via NDBT - return NDBT_ProgramExit(returnValue); - -} //main - -extern "C" -void* -flexHammerThread(void* pArg) -{ - ThreadNdb* pThreadData = (ThreadNdb*)pArg; - unsigned int threadNo = pThreadData->threadNo; - Ndb* pMyNdb = NULL ; - NdbConnection *pMyTransaction = NULL ; - // NdbOperation* pMyOperation[MAXTABLES] = {NULL}; - NdbOperation* pMyOperation[MAXTABLES]; - int check = 0; - int loop_count_ops = 0; - int loop_count_tables = 0; - int loop_count_attributes = 0; - int count_round = 0; - int count = 0; - int count_tables = 0; - int count_attributes = 0; - int i = 0; - int j = 0; - int tThreadResult = 0; - MyOpType tMyOpType = otLast; - int pkValue = 0; - int readValue[MAXATTR][MAXATTRSIZE] = {0}; - int attrValue[MAXATTRSIZE]; - NdbRecAttr* tTmp = NULL; - int tNoOfAttempts = 0; - - for (i = 0; i < MAXATTRSIZE; i++) - attrValue[i] = 0; - // Ndb object for each thread - pMyNdb = new Ndb( "TEST_DB" ); - pMyNdb->init(); - if (pMyNdb->waitUntilReady(10000) != 0) { - // Error, NDB is not ready - tThreadResult = 99; - // Go to idle directly - pThreadData->threadStart = stIdle; - } // if - - for(;;) { - pThreadData->threadResult = tThreadResult; - pThreadData->threadReady = 1; // Signalling ready to main - - // If Idle just wait to be stopped from main - while (pThreadData->threadStart == stIdle) { - NdbSleep_MilliSleep(100); - } // while - - // Check if signal to exit is received - if (pThreadData->threadStart == stStop) { - pThreadData->threadReady = 1; - // break out of eternal loop - break; - } // if - - // Set to Idle to prepare for possible error break - pThreadData->threadStart = stIdle; - - // Prepare transaction - loop_count_ops = tNoOfOperations; - loop_count_tables = tNoOfTables; - loop_count_attributes = tNoOfAttributes; - - for (count=0 ; count < loop_count_ops ; count++) { - - //pkValue = (int)(count + thread_base); - // This limits the number of records used in this test - pkValue = count % tNoOfRecords; - - for (count_round = 0; count_round < 5; ) { - switch (count_round) { - case 0: // Insert - tMyOpType = otInsert; - // Increase attrValues - for (i=0; i < MAXATTRSIZE; i ++) { - attrValue[i]++; - } - break; - case 1: - case 3: // Read and verify - tMyOpType = otRead; - break; - case 2: // Update - // Increase attrValues - for(i=0; i < MAXATTRSIZE; i ++) { - attrValue[i]++; - } - tMyOpType = otUpdate; - break; - case 4: // Delete - tMyOpType = otDelete; - break; - default: - assert(false); - break; - } // switch - - // Get transaction object - pMyTransaction = pMyNdb->startTransaction(); - if (pMyTransaction == NULL) { - // Fatal error - tThreadResult = 1; - // break out of for count_round loop waiting to be stopped by main - break; - } // if - - for (count_tables = 0; count_tables < loop_count_tables; - count_tables++) { - pMyOperation[count_tables] = - pMyTransaction->getNdbOperation(tableName[count_tables]); - if (pMyOperation[count_tables] == NULL) { - //Fatal error - tThreadResult = 2; - // break out of inner for count_tables loop - break; - } // if - - switch (tMyOpType) { - case otInsert: // Insert case - if (theWriteFlag == 1 && theDirtyFlag == 1) { - check = pMyOperation[count_tables]->dirtyWrite(); - } else if (theWriteFlag == 1) { - check = pMyOperation[count_tables]->writeTuple(); - } else { - check = pMyOperation[count_tables]->insertTuple(); - } // if else - break; - case otRead: // Read Case - if (theSimpleFlag == 1) { - check = pMyOperation[count_tables]->simpleRead(); - } else if (theDirtyFlag == 1) { - check = pMyOperation[count_tables]->dirtyRead(); - } else { - check = pMyOperation[count_tables]->readTuple(); - } // if else - break; - case otUpdate: // Update Case - if (theWriteFlag == 1 && theDirtyFlag == 1) { - check = pMyOperation[count_tables]->dirtyWrite(); - } else if (theWriteFlag == 1) { - check = pMyOperation[count_tables]->writeTuple(); - } else if (theDirtyFlag == 1) { - check = pMyOperation[count_tables]->dirtyUpdate(); - } else { - check = pMyOperation[count_tables]->updateTuple(); - } // if else - break; - case otDelete: // Delete Case - check = pMyOperation[count_tables]->deleteTuple(); - break; - default: - assert(false); - break; - } // switch - if (check == -1) { - // Fatal error - tThreadResult = 3; - // break out of inner for count_tables loop - break; - } // if - - check = pMyOperation[count_tables]->equal( (char*)attrName[0], - (char*)&pkValue ); - - if (check == -1) { - // Fatal error - tThreadResult = 4; - ndbout << "pMyOperation equal failed" << endl; - // break out of inner for count_tables loop - break; - } // if - - check = -1; - tTmp = NULL; - switch (tMyOpType) { - case otInsert: // Insert case - case otUpdate: // Update Case - for (count_attributes = 1; count_attributes < loop_count_attributes; - count_attributes++) { - check = - pMyOperation[count_tables]->setValue((char*)attrName[count_attributes], (char*)&attrValue[0]); - } // for - break; - case otRead: // Read Case - for (count_attributes = 1; count_attributes < loop_count_attributes; - count_attributes++) { - tTmp = pMyOperation[count_tables]-> - getValue( (char*)attrName[count_attributes], - (char*)&readValue[count_attributes][0] ); - } // for - break; - case otDelete: // Delete Case - break; - default: - assert(false); - break; - } // switch - if (check == -1 && tTmp == NULL && tMyOpType != otDelete) { - // Fatal error - tThreadResult = 5; - break; - } // if - } // for count_tables - - // Only execute if everything is OK - if (tThreadResult != 0) { - // Close transaction (below) - // and continue with next count_round - count_round++; - tNoOfAttempts = 0; - } // if - else { - check = pMyTransaction->execute(Commit); - if (check == -1 ) { - const NdbError & err = pMyTransaction->getNdbError(); - - // Add complete error handling here - - int retCode = flexHammerErrorData->handleErrorCommon(pMyTransaction->getNdbError()); - if (retCode == 1) { - //if (strcmp(pMyTransaction->getNdbError().message, "Tuple did not exist") != 0 && strcmp(pMyTransaction->getNdbError().message,"Tuple already existed when attempting to insert") != 0) ndbout_c("execute: %s", pMyTransaction->getNdbError().message); - - if (pMyTransaction->getNdbError().code != 626 && pMyTransaction->getNdbError().code != 630){ - ndbout_c("Error code = %d", pMyTransaction->getNdbError().code); - ndbout_c("execute: %s", pMyTransaction->getNdbError().message);} - - } else if (retCode == 2) { - ndbout << "4115 should not happen in flexHammer" << endl; - } else if (retCode == 3) { -// -------------------------------------------------------------------- -// We are not certain if the transaction was successful or not. -// We must reexecute but might very well find that the transaction -// actually was updated. Updates and Reads are no problem here. Inserts -// will not cause a problem if error code 630 arrives. Deletes will -// not cause a problem if 626 arrives. -// -------------------------------------------------------------------- - /* What can we do here? */ - ndbout_c("execute: %s", pMyTransaction->getNdbError().message); - }//if(retCode == 3) - // End of adding complete error handling - - switch( err.classification) { - case NdbError::ConstraintViolation: // Tuple already existed - count_round++; - tNoOfAttempts = 0; - break; - case NdbError::TimeoutExpired: - case NdbError::NodeRecoveryError: - case NdbError::TemporaryResourceError: - case NdbError::OverloadError: - if (tNoOfAttempts <= MaxNoOfAttemptsC) { - // Retry - tNoOfAttempts++; - } else { - // Too many retries, continue with next - count_round++; - tNoOfAttempts = 0; - } // else if - break; - // Fatal, just continue - default: - count_round++; - tNoOfAttempts = 0; - break; - } // switch - } // if - else { - // Execute commit was OK - // This is verifying read values - //switch (tMyOpType) { - //case otRead: // Read case - //for (j = 0; j < tNoOfAttributes; j++) { - //for(i = 1; i < tAttributeSize; i++) { - //if ( readValue[j][i] != attrValue[i]) { - //ndbout << "pkValue = " << pkValue << endl; - //ndbout << "readValue != attrValue" << endl; - //ndbout << readValue[j][i] << " != " << attrValue[i] << endl; - //} // if - // } // for - //} // for - //break; - //} // switch - count_round++; - tNoOfAttempts = 0; - } // else if - } // else if - pMyNdb->closeTransaction(pMyTransaction); - } // for count_round - } // for count - } // for (;;) - - // Clean up - delete pMyNdb; - pMyNdb = NULL; - - flexHammerErrorData->resetErrorCounters(); - - // And exit using NDBT - NdbThread_Exit(0); - - return NULL; - -} // flexHammerThread - - -int -readArguments (int argc, const char** argv) -{ - int i = 1; - - tNoOfThreads = 5; // Default Value - tNoOfOperations = 500; // Default Value - tNoOfRecords = 1; // Default Value - tNoOfLoops = 1; // Default Value - tNoOfAttributes = 25; // Default Value - tNoOfTables = 1; // Default Value - tNoOfBackups = 0; // Default Value - tAttributeSize = 1; // Default Value - theTableCreateFlag = 0; - - while (argc > 1) { - if (strcmp(argv[i], "-t") == 0) { - tNoOfThreads = atoi(argv[i+1]); - if ((tNoOfThreads < 1) || (tNoOfThreads > MAXTHREADS)) - return(1); - } - else if (strcmp(argv[i], "-o") == 0) { - tNoOfOperations = atoi(argv[i+1]); - if (tNoOfOperations < 1) - return(1); - } - else if (strcmp(argv[i], "-r") == 0) { - tNoOfRecords = atoi(argv[i+1]); - if (tNoOfRecords < 1) - return(1); - } - else if (strcmp(argv[i], "-a") == 0) { - tNoOfAttributes = atoi(argv[i+1]); - if ((tNoOfAttributes < 2) || (tNoOfAttributes > MAXATTR)) - return(1); - } - else if (strcmp(argv[i], "-c") == 0) { - tNoOfTables = atoi(argv[i+1]); - if ((tNoOfTables < 1) || (tNoOfTables > MAXTABLES)) - return(1); - } - else if (strcmp(argv[i], "-l") == 0) { - tNoOfLoops = atoi(argv[i+1]); - if ((tNoOfLoops < 0) || (tNoOfLoops > 100000)) - return(1); - } - else if (strcmp(argv[i], "-s") == 0) { - tAttributeSize = atoi(argv[i+1]); - if ((tAttributeSize < 1) || (tAttributeSize > MAXATTRSIZE)) - return(1); - } - else if (strcmp(argv[i], "-sleep") == 0) { - tSleepTime = atoi(argv[i+1]); - if ((tSleepTime < 1) || (tSleepTime > 3600)) - exit(-1); - } - else if (strcmp(argv[i], "-simple") == 0) { - theSimpleFlag = 1; - argc++; - i--; - } - else if (strcmp(argv[i], "-write") == 0) { - theWriteFlag = 1; - argc++; - i--; - } - else if (strcmp(argv[i], "-dirty") == 0) { - theDirtyFlag = 1; - argc++; - i--; - } - else if (strcmp(argv[i], "-no_table_create") == 0) { - theTableCreateFlag = 1; - argc++; - i--; - } - else if (strcmp(argv[i], "-stdtables") == 0) { - theStandardTableNameFlag = 1; - argc++; - i--; - } // if - else { - return(1); - } - - argc -= 2; - i = i + 2; - } // while - - ndbout << endl << "FLEXHAMMER - Starting normal mode" << endl; - ndbout << "Hammer ndb with read, insert, update and delete transactions"<< endl << endl; - - ndbout << " " << tNoOfThreads << " thread(s) " << endl; - ndbout << " " << tNoOfLoops << " iterations " << endl; - ndbout << " " << tNoOfTables << " table(s) and " << 1 << " operation(s) per transaction " << endl; - ndbout << " " << tNoOfRecords << " records to hammer(limit this with the -r option)" << endl; - ndbout << " " << tNoOfAttributes << " attributes per table " << endl; - ndbout << " " << tNoOfOperations << " transaction(s) per thread and round " << endl; - ndbout << " " << tAttributeSize << " is the number of 32 bit words per attribute " << endl << endl; - return 0; -} // readArguments - - -void sleepBeforeStartingTest(int seconds) -{ - if (seconds > 0) { - ndbout << "Sleeping(" << seconds << ")..."; - NdbSleep_SecSleep(seconds); - ndbout << " done!" << endl; - } // if -} // sleepBeforeStartingTest - -static int -createTables(Ndb* pMyNdb) -{ - int i = 0; - int j = 0; - int check = 0; - NdbSchemaCon *MySchemaTransaction = NULL; - NdbSchemaOp *MySchemaOp = NULL; - - // Create Table and Attributes. - if (theTableCreateFlag == 0) { - - for (i = 0; i < tNoOfTables; i++) { - - ndbout << "Creating " << tableName[i] << "..."; - // Check if table exists already - const void * p = pMyNdb->getDictionary()->getTable(tableName[i]); - if (p != 0) { - ndbout << " already exists." << endl; - // Continue with next table at once - continue; - } // if - ndbout << endl; - - MySchemaTransaction = pMyNdb->startSchemaTransaction(); - if (MySchemaTransaction == NULL) { - return(-1); - } // if - - MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); - if (MySchemaOp == NULL) { - // Clean up opened schema transaction - pMyNdb->closeSchemaTransaction(MySchemaTransaction); - return(-1); - } // if - - // Create tables, rest of parameters are default right now -#if defined NDB_OSE || defined NDB_SOFTOSE - check = MySchemaOp->createTable(tableName[i], - 8, // Table Size - TupleKey, // Key Type - 40, // Nr of Pages - All, - 6, - 78, - 80, - 1, - false); - -#else - check = MySchemaOp->createTable(tableName[i], - 8, // Table Size - TupleKey, // Key Type - 40); // Nr of Pages -#endif - if (check == -1) { - // Clean up opened schema transaction - pMyNdb->closeSchemaTransaction(MySchemaTransaction); - return(-1); - } // if - - // Primary key - //ndbout << " pk " << (char*)&attrName[0] << "..." << endl; - check = MySchemaOp->createAttribute( (char*)attrName[0], TupleKey, 32, - 1, UnSigned, MMBased, - NotNullAttribute ); - if (check == -1) { - // Clean up opened schema transaction - pMyNdb->closeSchemaTransaction(MySchemaTransaction); - return(-1); - } // if - - // Rest of attributes - for (j = 1; j < tNoOfAttributes ; j++) { - //ndbout << " " << (char*)attrName[j] << "..." << endl; - check = MySchemaOp->createAttribute( (char*)attrName[j], NoKey, 32, - tAttributeSize, UnSigned, MMBased, - NotNullAttribute ); - if (check == -1) { - // Clean up opened schema transaction - pMyNdb->closeSchemaTransaction(MySchemaTransaction); - return(-1); - } // if - } // for - - // Execute creation - check = MySchemaTransaction->execute(); - if (check == -1) { - // Clean up opened schema transaction - pMyNdb->closeSchemaTransaction(MySchemaTransaction); - return(-1); - } // if - - pMyNdb->closeSchemaTransaction(MySchemaTransaction); - } // for - } // if - - return(0); - -} // createTables - - -static int setAttrNames() -{ - int i = 0; - int retVal = 0; - - for (i = 0; i < MAXATTR ; i++) { - retVal = snprintf(attrName[i], MAXSTRLEN, "COL%d", i); - if (retVal < 0) { - // Error in conversion - return(-1); - } // if - } // for - - return (0); -} // setAttrNames - -static int setTableNames() -{ - // Note! Uses only uppercase letters in table name's - // so that we can look at the tables wits SQL - int i = 0; - int retVal = 0; - - for (i = 0; i < MAXTABLES ; i++) { - if (theStandardTableNameFlag == 0) { - retVal = snprintf(tableName[i], MAXSTRLEN, "TAB%d_%d", i, - NdbTick_CurrentMillisecond()/1000); - } // if - else { - retVal = snprintf(tableName[i], MAXSTRLEN, "TAB%d", i); - } // else - if (retVal < 0) { - // Error in conversion - return(-1); - } // if - } // for - - return(0); -} // setTableNames - -static int checkThreadResults(ThreadNdb *threadArrayP, char* phase) -{ - int i = 0; - - for (i = 0; i < tNoOfThreads; i++) { - if (threadArrayP[i].threadResult != 0) { - ndbout << "Thread " << i << " reported fatal error " - << threadArrayP[i].threadResult << " during " << phase << endl; - return(-1); - } // if - } // for - - return(0); -} - diff --git a/ndb/test/ndbapi/flexScan.cpp b/ndb/test/ndbapi/flexScan.cpp new file mode 100644 index 00000000000..19fb6dc5ab0 --- /dev/null +++ b/ndb/test/ndbapi/flexScan.cpp @@ -0,0 +1,1674 @@ +/* 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 */ + +/* *************************************************** + FLEXSCAN + Perform benchmark of: + insert + read + scan read + update + scan update + read + scan delete + verify delete + + Arguments: + -f Location of Ndb.cfg file, default Ndb.cfg + -t Number of threads to start, default 1 + -o Number of operations per loop, default 500 -l Number of loops to run, default 1, 0=infinite + -a Number of attributes, default 25 + -c Number of tables, default 1 + -s Size of each attribute, default 1 + -stdtables Use standard table names + -no_table_create Don't create tables in db + -sleep Sleep a number of seconds before running the test, this + can be used so that another flexBench hav etome to create tables + -p Parallellism to use 1-32, default:1 + -abort Test scan abort after a number of tuples + -h Print help text + -no_scan_update Don't do scan updates + -no_scan_delete Don't do scan deletes + + Returns: + NDBT_OK - Test passed + NDBT_FAILED - Test failed + + Revision history: + 1.12 020222 epesson: Rewritten to use NDBT. Major bugs fixed + + * *************************************************** */ + +#include "NdbApi.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +#define PKSIZE 1 +#define FOREVER 1 +#define MAXSTRLEN 16 +#define MAXATTR 64 +#define MAXTABLES 64 +#define MAXTHREADS 256 +#define MAXATTRSIZE 64 + +enum StartType { + stIdle, + stInsert, + stRead, + stScanRead, + stUpdate, + stScanUpdate, + stDelete, + stVerifyDelete, + stScanDelete, + stStop, + stLast} ; + + +struct ThreadNdb +{ + int ThreadNo; + NdbThread* threadLife; + StartType threadStart; + int threadResult; + int threadReady; +}; + +extern "C" void* flexScanThread(void*); +static int setAttrNames(void); +static int setTableNames(void); +static int createTables(Ndb* pMyNdb); +static void sleepBeforeStartingTest(int seconds); +static int readArguments(int argc, const char** argv); +static void setAttrValues(int* attrValue, + int* readValue, + int Offset); +static int insertRows(Ndb* pNdb, int* pkValue, int* attrValue, StartType tType); +static int readRows(Ndb* pNdb, int* pkValue, int* readValue); +static int deleteRows(Ndb* pNdb, int* pkValue); +static int scanReadRows(Ndb* pNdb, int* readValue); +static int scanUpdateRows(Ndb* pNdb, int* readValue, int* attrValue); +static int scanDeleteRows(Ndb* pNdb, int* readValue); +static int verifyDeleteRows(Ndb* pNdb, int* pkValue, int* readValue); +static void Compare(int* attrValue, int* readValue); +static void UpdateArray(int *attrValue); + +static int tNoOfThreads = 1; +static int tNoOfAttributes = 25; +static int tNoOfTables = 1; +static int tAttributeSize = 1; +static int tNodeId = 0; +static int tNoOfOperations = 500; +static int tNoOfLoops = 1; +static int tAbortAfter = 0; +static int tParallellism = 1; + +static char tableName[MAXTABLES][MAXSTRLEN]; +static char attrName[MAXATTR][MAXSTRLEN]; + +static unsigned int tSleepTime = 0; + +static int theStdTableNameFlag = 0; +static int theTableCreateFlag = 0; +static int theScanAbortTestFlag = 0; +static int theNoScanUpdateFlag = 0; +static int theNoScanDeleteFlag = 0; + +//flexScanErrorData = new ErrorData; +ErrorData * flexScanErrorData; +NdbError * anerror; + +//static errorData theErrorData; +//static unsigned int tErrorCounter[6000]; + +#define START_TIMER { NdbTimer timer; timer.doStart(); +#define STOP_TIMER timer.doStop(); +#define PRINT_TIMER(text, trans, opertrans) timer.printTransactionStatistics(text, trans, opertrans); }; + +static void UpdateArray(int *attrValue) +{ + int tableCount = 0; + int attrCount = 0; + int opCount = 0; + int sizeCount = 0; + int Index = 0; + int* pValue = attrValue; + + for (tableCount = 0; tableCount < tNoOfTables; tableCount++) { + for (attrCount = 0; attrCount < tNoOfAttributes-1; attrCount++) { + for (opCount = 0; opCount < tNoOfOperations; opCount++) { + for (sizeCount = 0; sizeCount < tAttributeSize; sizeCount++) { + // Update value in array + (*pValue)++; + //ndbout << "attrValue[" << tableCount*tNoOfAttributes*tNoOfOperations*tAttributeSize + + //attrCount*tNoOfOperations*tAttributeSize + opCount*tAttributeSize + sizeCount << + //"] = " << attrValue[tableCount*tNoOfAttributes*tNoOfOperations*tAttributeSize + + //attrCount*tNoOfOperations*tAttributeSize + opCount*tAttributeSize + sizeCount] << endl; + // Increment pointer + pValue++; + } // sizeCount + } // for opCount + } // for attrCount + } // for tableCount + +} // Update + +static void Compare(int* attrValue, int* readValue) +{ + int tableCount = 0; + int attrCount = 0; + int OpCount = 0; + int first = 0; + int sizeCount = 0; + + for (tableCount = 0; tableCount < tNoOfTables; tableCount++) { + for (attrCount = 0; attrCount < tNoOfAttributes-1; attrCount++) { + for (OpCount = 0; OpCount < tNoOfOperations; OpCount++) { + if (memcmp(&(attrValue[tableCount*(tNoOfAttributes-1)*tNoOfOperations + + attrCount*tNoOfOperations + OpCount]), + &(readValue[tableCount*(tNoOfAttributes-1)*tNoOfOperations + + attrCount*tNoOfOperations + OpCount]), + tAttributeSize) != 0) { + // Values mismatch + if (first == 0) { + //ndbout << "Read and set values differ for:" << endl; + first = 1; + ndbout << "Mismatch found."; + } // if + // Comparision of values after scan update is meaningless right now + //ndbout << " table " << tableName[tableCount] << + //" - attr " << attrName[attrCount+1]; + //for (sizeCount = 0; sizeCount < tAttributeSize; sizeCount++) { + //ndbout << ": set " << + //attrValue[tableCount*(tNoOfAttributes-1)*tNoOfOperations*tAttributeSize + + //attrCount*tNoOfOperations*tAttributeSize + + //tNoOfOperations*tAttributeSize + sizeCount] << " read " << + //readValue[tableCount*(tNoOfAttributes-1)*tNoOfOperations*tAttributeSize + + //attrCount*tNoOfOperations*tAttributeSize + + //tNoOfOperations*tAttributeSize + sizeCount] << endl; + //} // for + } // if + } // for OpCount + } // for attrCount + } // for tableCount + + // A final pretty-print + if (first == 1) { + ndbout << endl; + } // if +} // Compare + +static void printInfo() +{ + ndbout << endl << "FLEXSCAN - Starting normal mode" << endl; + ndbout << "Perform benchmark of insert, update and delete transactions"<< endl; + ndbout << " NdbAPI node with id = " << tNodeId << endl; + ndbout << " " << tNoOfThreads << " thread(s) " << endl; + ndbout << " " << tNoOfLoops << " iterations " << endl; + ndbout << " " << tNoOfTables << " table(s) and " << 1 << " operation(s) per transaction " + << endl; + ndbout << " " << tNoOfAttributes << " attributes per table incl. pk" << endl; + ndbout << " " << tNoOfOperations << " transaction(s) per thread and round " << endl; + if (theScanAbortTestFlag == 1) { + ndbout << " Scan abort test after " << tAbortAfter << " tuples" << endl; + } // if + ndbout << " " << tParallellism << " parallellism in scans" << endl; + ndbout << " " << tAttributeSize << " is the number of 32 bit words per attribute " << + endl << endl; + +} // printInfo + +static void tellThreads(ThreadNdb *threadArrayP, StartType what) +{ + int i = 0; + + for (i = 0; i < tNoOfThreads ; i++) + threadArrayP[i].threadStart = what; +} // tellThreads + +static void waitForThreads(ThreadNdb *threadArrayP) +{ + int i = 0; + int cont = 1; + + while (cont == 1){ + + NdbSleep_MilliSleep(10); + cont = 0; + + for (i = 0; i < tNoOfThreads ; i++) { + if (threadArrayP[i].threadReady == 0) { +// ndbout << "Main is reporting thread " << i << " not ready" << endl; + cont = 1; + } // if + } // for + } // while +} // waitForThreads + + +static void resetThreads(ThreadNdb *threadArrayP) +{ + int i = 0; + + for (i = 0; i < tNoOfThreads ; i++) { + threadArrayP[i].threadReady = 0; + threadArrayP[i].threadResult = 0; + threadArrayP[i].threadStart = stIdle; + //ndbout << "threadStart[" << i << "]=" << + //threadArrayP[i].threadStart << endl; + } // for +} // resetThreads + +static int checkThreadResults(ThreadNdb *threadArrayP, char *action) +{ + int i = 0; + int retValue = 0; + + for (i = 0; i < tNoOfThreads; i++) { + if (threadArrayP[i].threadResult != 0) { + ndbout << "Thread " << i << " reported fatal error " + << threadArrayP[i].threadResult << " during " << action << endl; + retValue = -1; + break; + } // if + } // for + + return(retValue); +} // checkThreadResults + +NDB_COMMAND(flexScan, "flexScan", "flexScan", "flexScan", 65535) +{ + ThreadNdb* pThreads = NULL; + Ndb* pMyNdb = NULL; + int tLoops = 0; + int check = 0; + int returnValue = NDBT_OK; + int every2ndScanDelete = 0; // Switch between scan delete and normal delete + + flexScanErrorData = new ErrorData; + + flexScanErrorData->resetErrorCounters(); + + if (readArguments(argc, argv) != 0) { + ndbout << "Wrong arguments to flexScan" << endl; + return NDBT_ProgramExit(NDBT_WRONGARGS); + } // if + + /* print Setting */ + flexScanErrorData->printSettings(ndbout); + + check = setAttrNames(); + if (check != 0) { + ndbout << "Couldn't set attribute names" << endl; + return NDBT_ProgramExit(NDBT_FAILED); + } // if + check = setTableNames(); + if (check != 0) { + ndbout << "Couldn't set table names" << endl; + return NDBT_ProgramExit(NDBT_FAILED); + } // if + + pMyNdb = new Ndb ("TEST_DB"); + pMyNdb->init(); + tNodeId = pMyNdb->getNodeId(); + + printInfo(); + + NdbThread_SetConcurrencyLevel(tNoOfThreads + 2); + //NdbThread_SetConcurrencyLevel(tNoOfThreads + 8); + + pThreads = new ThreadNdb[tNoOfThreads]; + + if (pMyNdb->waitUntilReady(10000) != 0) { + ndbout << "NDB is not ready" << endl << "Benchmark failed" << endl; + returnValue = NDBT_FAILED; + } // if + + else { + + if (createTables(pMyNdb) != 0) { + ndbout << "Could not create tables" << endl; + returnValue = NDBT_FAILED; + } // if + else { + sleepBeforeStartingTest(tSleepTime); + + resetThreads(pThreads); + // Create threads + for (int i = 0; i < tNoOfThreads ; i++){ + pThreads[i].ThreadNo = i; + // Ignore the case that thread creation may fail + pThreads[i].threadLife = NdbThread_Create(flexScanThread, + (void**)&pThreads[i], + 327680, + "flexScanThread", NDB_THREAD_PRIO_LOW); + if (pThreads[i].threadLife == NULL) { + ndbout << "Could not create thread " << i << endl; + returnValue = NDBT_FAILED; + // Use the number of threads that were actually created + tNoOfThreads = i; + break; // break for loop + } // if + } // for + + waitForThreads(pThreads); + if (checkThreadResults(pThreads, "init") != 0) { + returnValue = NDBT_FAILED; + } // if + + if (returnValue == NDBT_OK) { + ndbout << "All threads started" << endl; + + while (FOREVER) { + + resetThreads(pThreads); + + if ((tNoOfLoops != 0) && (tNoOfLoops <= tLoops)) { + break; + } // if + + // Insert + START_TIMER; + + tellThreads(pThreads, stInsert); + waitForThreads(pThreads); + + STOP_TIMER; + if (checkThreadResults(pThreads, "insert") != 0) { + returnValue = NDBT_FAILED; + break; + } // if + PRINT_TIMER("insert", tNoOfOperations*tNoOfThreads, tNoOfTables); + + resetThreads(pThreads); + + // Read + START_TIMER; + + tellThreads(pThreads, stRead); + waitForThreads(pThreads); + + STOP_TIMER; + if (checkThreadResults(pThreads, "read") != 0) { + returnValue = NDBT_FAILED; + break; + } // if + PRINT_TIMER("read", tNoOfOperations*tNoOfThreads, tNoOfTables); + + resetThreads(pThreads); + + // Update + START_TIMER; + + tellThreads(pThreads, stUpdate); + waitForThreads(pThreads); + + STOP_TIMER; + if (checkThreadResults(pThreads, "update") != 0) { + returnValue = NDBT_FAILED; + break; + } // if + PRINT_TIMER("update", tNoOfOperations*tNoOfThreads, tNoOfTables); + + resetThreads(pThreads); + + // Scan read + START_TIMER; + + tellThreads(pThreads, stScanRead); + waitForThreads(pThreads); + + STOP_TIMER; + if (checkThreadResults(pThreads, "scanread") != 0) { + returnValue = NDBT_FAILED; + break; + } // if + PRINT_TIMER("scanread", tNoOfTables*tNoOfThreads, 1); + + resetThreads(pThreads); + + // Update + START_TIMER; + + tellThreads(pThreads, stUpdate); + waitForThreads(pThreads); + + STOP_TIMER; + if (checkThreadResults(pThreads, "update") != 0) { + returnValue = NDBT_FAILED; + break; + } // if + PRINT_TIMER("update", tNoOfOperations*tNoOfThreads, tNoOfTables); + + resetThreads(pThreads); + + // Read + START_TIMER; + + tellThreads(pThreads, stRead); + waitForThreads(pThreads); + + STOP_TIMER; + if (checkThreadResults(pThreads, "read") != 0) { + returnValue = NDBT_FAILED; + break; + } // if + PRINT_TIMER("read", tNoOfOperations*tNoOfThreads, tNoOfTables); + + resetThreads(pThreads); + + // Only do scan update if told to do so + if (theNoScanUpdateFlag == 0) { + // Scan update + START_TIMER; + + tellThreads(pThreads, stScanUpdate); + waitForThreads(pThreads); + + STOP_TIMER; + if (checkThreadResults(pThreads, "scanupdate") != 0) { + returnValue = NDBT_FAILED; + break; + } // if + PRINT_TIMER("scanupdate", tNoOfTables*tNoOfThreads, 1); + + resetThreads(pThreads); + + // Read + START_TIMER; + + tellThreads(pThreads, stRead); + // tellThreads(pThreads, stScanRead); + waitForThreads(pThreads); + + STOP_TIMER; + if (checkThreadResults(pThreads, "read") != 0) { + returnValue = NDBT_FAILED; + break; + } // if + PRINT_TIMER("read", tNoOfOperations*tNoOfThreads, tNoOfTables); + + resetThreads(pThreads); + } // if theNoScanUpdateFlag + + // Shift between delete and scan delete + if ((every2ndScanDelete % 2 == 0) || (theNoScanDeleteFlag == 1)){ + // Delete + START_TIMER; + tellThreads(pThreads, stDelete); + waitForThreads(pThreads); + + STOP_TIMER; + if (checkThreadResults(pThreads, "delete") != 0) { + returnValue = NDBT_FAILED; + break; + } // if + PRINT_TIMER("delete", tNoOfOperations*tNoOfThreads, tNoOfTables); + resetThreads(pThreads); + } // if + else { + resetThreads(pThreads); // Scan delete + START_TIMER; + tellThreads(pThreads, stScanDelete); + waitForThreads(pThreads); + + STOP_TIMER; + if (checkThreadResults(pThreads, "scandelete") != 0) { + returnValue = NDBT_FAILED; + break; + } // if + PRINT_TIMER("scandelete", tNoOfTables*tNoOfThreads, 1); + + resetThreads(pThreads); + } // else + every2ndScanDelete++; + + resetThreads(pThreads); // Verify delete + START_TIMER; + tellThreads(pThreads, stVerifyDelete); + waitForThreads(pThreads); + + STOP_TIMER; + if (checkThreadResults(pThreads, "verifydelete") != 0) { + returnValue = NDBT_FAILED; + break; + } // if + PRINT_TIMER("verifydelete", tNoOfOperations*tNoOfThreads*tNoOfTables, 1); + + resetThreads(pThreads); + + ndbout << "--------------------------------------------------" << endl; + tLoops++; + + } // while + } // if + } // else + } // else + + // Stop threads in a nice way + tellThreads(pThreads, stStop); + waitForThreads(pThreads); + + // Clean up + delete [] pThreads; + delete pMyNdb; + + flexScanErrorData->printErrorCounters(ndbout); + + if (returnValue == NDBT_OK) { + ndbout << endl << "Benchmark completed successfully" << endl; + } // if + else { + ndbout << endl << "Benchmark failed" << endl; + } // else + + // Exit via NDBT + return NDBT_ProgramExit(returnValue);; +} // main + +void* +flexScanThread(void* ThreadData) +{ + ThreadNdb* pThreadData = (ThreadNdb*)ThreadData; + unsigned int thread_no = pThreadData->ThreadNo; + unsigned int thread_base = (thread_no * 2000000) + (tNodeId * 26000); + int NrOfScannedRecords = 0; + int tThreadResult = 0; + Ndb* MyNdb = NULL; + NdbConnection *MyTransaction = NULL; + NdbOperation* MyOperation[MAXTABLES]; + int check = 0; + StartType tType = stLast; + int* pkValue = NULL; + int* attrValue = NULL; + int* readValue = NULL; + int AllocSize = 0; + NdbRecAttr* tTmp = NULL; + OperationType opType; + + AllocSize = tNoOfTables * (tNoOfAttributes-1) * tNoOfOperations * + tAttributeSize * sizeof(int); + attrValue = (int*)malloc(AllocSize); + readValue = (int*)malloc(AllocSize); + pkValue = (int*)malloc(tNoOfOperations * sizeof(int)); + if ((attrValue == NULL) || (readValue == NULL) || (pkValue == NULL)) { + tThreadResult = 98; + pThreadData->threadStart = stIdle; + } // if + + setAttrValues(attrValue, readValue, thread_base); + + MyNdb = new Ndb( "TEST_DB" ); + MyNdb->init(); + if (MyNdb->waitUntilReady(10000) != 0) { + tThreadResult = 99; + pThreadData->threadStart = stIdle; + } // if + + // Set primary key value, same for all tables + for (int c = 0; c < tNoOfOperations; c++) { + pkValue[c] = (int)(c + thread_base); + } // for + + while (FOREVER) { + pThreadData->threadResult = tThreadResult; + pThreadData->threadReady = 1; + + while (pThreadData->threadStart == stIdle) { + NdbSleep_MilliSleep(10); + } // while + + // Check if signal to exit is received + if (pThreadData->threadStart >= stStop){ + pThreadData->threadReady = 1; + break; + } // if + tType = pThreadData->threadStart; + pThreadData->threadStart = stIdle; + + switch (tType) { + case stInsert: + check = insertRows(MyNdb, pkValue, attrValue, tType); + break; + case stRead: + check = readRows(MyNdb, pkValue, readValue); + Compare(attrValue, readValue); + break; + case stUpdate: + UpdateArray(attrValue); + check = insertRows(MyNdb, pkValue, attrValue, tType); + break; + case stScanRead: + //check = readRows(MyNdb, pkValue, readValue); + check = scanReadRows(MyNdb, readValue); + Compare(attrValue, readValue); + break; + case stScanUpdate: + UpdateArray(attrValue); + //tType = stUpdate; + //check = insertRows(MyNdb, pkValue, attrValue, tType); + check = scanUpdateRows(MyNdb, readValue, attrValue); + break; + case stDelete: + check = deleteRows(MyNdb, pkValue); + break; + case stScanDelete: + check = scanDeleteRows(MyNdb, readValue); + break; + case stVerifyDelete: + check = verifyDeleteRows(MyNdb, pkValue, readValue); + break; + default: + ndbout << "tType is " << tType << endl; + assert(false); + break; + } // switch + + tThreadResult = check; + + if (tThreadResult != 0) { + // Check if error is fatak or not + } // if + else { + continue; + } // else + } // while + + // Clean up + delete MyNdb; + if (attrValue != NULL) { + free(attrValue); + } //if + if (readValue != NULL) { + free(readValue); + } // if + if (pkValue != NULL) { + free(pkValue); + } // if + + NdbThread_Exit(0); + return NULL; + +} // flexScanThread + + +static int setAttrNames() +{ + int i = 0; + int retVal = 0; + + for (i = 0; i < MAXATTR ; i++) { + retVal = snprintf(attrName[i], MAXSTRLEN, "COL%d", i); + if (retVal < 0) { + return(-1); + } // if + } // for + + return(0); +} // setAttrNames + + +static int setTableNames() +{ + // Note! Uses only uppercase letters in table name's + // so that we can look at the tables with SQL + int i = 0; + int retVal = 0; + + for (i = 0; i < MAXTABLES ; i++) { + + if (theStdTableNameFlag == 0) { + retVal = snprintf(tableName[i], MAXSTRLEN, "TAB%d_%d", i, + (int)(NdbTick_CurrentMillisecond() / 1000)); + } // if + else { + retVal = snprintf(tableName[i], MAXSTRLEN, "TAB%d", i); + } // if else + + if (retVal < 0) { + return(-1); + } // if + } // for + + return(0); +} // setTableNames + + +// Create Table and Attributes. +static int createTables(Ndb* pMyNdb) +{ + + NdbSchemaCon *MySchemaTransaction = NULL; + NdbSchemaOp *MySchemaOp = NULL; + int i = 0; + int j = 0; + int check = 0; + + if (theTableCreateFlag == 0) { + + i = 0; + do { + i++; + ndbout << endl << "Creating " << tableName[i - 1] << "..." << endl; + + MySchemaTransaction = pMyNdb->startSchemaTransaction(); + if( MySchemaTransaction == NULL ) { + return (-1); + } // if + + MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); + if( MySchemaOp == NULL ) { + pMyNdb->closeSchemaTransaction(MySchemaTransaction); + return (-1); + } // if + +#if defined NDB_OSE || defined NDB_SOFTOSE + check = MySchemaOp->createTable(tableName[i - 1], + 8, // Table Size + TupleKey, // Key Type + 40, // Nr of Pages + All, + 6, + 78, + 80, + 1, + false); +#else + check = MySchemaOp->createTable(tableName[i - 1] + ,8 // Table Size + ,TupleKey // Key Type + ,40); // Nr of Pages +#endif + if (check == -1) { + pMyNdb->closeSchemaTransaction(MySchemaTransaction); + return -1; + } // if + + check = MySchemaOp->createAttribute( (char*)attrName[0], TupleKey, 32, PKSIZE, + UnSigned, MMBased, NotNullAttribute ); + if (check == -1) { + pMyNdb->closeSchemaTransaction(MySchemaTransaction); + return -1; + } // if + + for (j = 1; j < tNoOfAttributes ; j++) { + check = MySchemaOp->createAttribute( (char*)attrName[j], NoKey, 32, tAttributeSize, + UnSigned, MMBased, NotNullAttribute ); + if (check == -1) { + pMyNdb->closeSchemaTransaction(MySchemaTransaction); + return -1; + } // if + } // for + + if (MySchemaTransaction->execute() == -1) { + ndbout << MySchemaTransaction->getNdbError().message << endl; + ndbout << "Probably, " << tableName[i - 1] << " already exist" << endl; + } // if + + pMyNdb->closeSchemaTransaction(MySchemaTransaction); + } while (tNoOfTables > i); + } + + return 0; +} // createTables + +static void printUsage() +{ + ndbout << "Usage of flexScan:" << endl; + ndbout << "-f Location of Ndb.cfg file, default: Ndb.cfg" << endl; + ndbout << "-t Number of threads to start, default 1" << endl; + ndbout << "-o Number of operations per loop, default 500" << endl; + ndbout << "-l Number of loops to run, default 1, 0=infinite" << endl; + ndbout << "-a Number of attributes, default 25" << endl; + ndbout << "-c Number of tables, default 1" << endl; + ndbout << "-s Size of each attribute, default 1" << endl; + ndbout << "-stdtables Use standard table names" << endl; + ndbout << "-no_table_create Don't create tables in db" << endl; + ndbout << "-sleep Sleep a number of seconds before running the test" << endl; + ndbout << "-p Parallellism to use 1-32, default:1" << endl; + ndbout << "-abort Test scan abort after a number of tuples" << endl; + ndbout << "-no_scan_update Don't do scan updates" << endl; + ndbout << "-no_scan_delete Don't do scan deletes" << endl; + ndbout << "-h Print this text" << endl; + // inputErrorArg(); + flexScanErrorData->printCmdLineArgs(ndbout); +} + +static int readArguments(int argc, const char** argv) +{ + int i = 1; + int retValue = 0; + int printFlag = 0; + + tNoOfThreads = 1; // Set default Value + tNoOfTables = 1; // Default Value + + while (argc > 1) { + if (strcmp(argv[i], "-t") == 0) { + if (argv[i + 1] != NULL) { + tNoOfThreads = atoi(argv[i + 1]); + if ((tNoOfThreads < 1) || (tNoOfThreads > MAXTHREADS)) { + retValue = -1; + } // if + } // if + else { + retValue = -1; + } // else + } // if + else if (strcmp(argv[i], "-o") == 0) { + if (argv[i + 1] != NULL) { + tNoOfOperations = atoi(argv[i + 1]); + if (tNoOfOperations < 1) { + retValue = -1; + } // if + } // if + else { + retValue = -1; + } // else + } // else if + else if (strcmp(argv[i], "-a") == 0) { + if (argv[i + 1] != NULL) { + tNoOfAttributes = atoi(argv[i + 1]); + if ((tNoOfAttributes < 2) || (tNoOfAttributes > MAXATTR)) { + retValue = -1; + } // if + } // if + else { + retValue = -1; + } // else + } // else if + else if (strcmp(argv[i], "-c") == 0) { + if (argv[i + 1] != NULL) { + tNoOfTables = atoi(argv[i+1]); + if ((tNoOfTables < 1) || (tNoOfTables > MAXTABLES)) { + retValue = -1; + } // if + } // if + else { + retValue = -1; + } // else + } // else if + else if (strcmp(argv[i], "-l") == 0) { + if (argv[i + 1] != NULL) { + tNoOfLoops = atoi(argv[i+1]); + if ((tNoOfLoops < 0) || (tNoOfLoops > 100000)) { + retValue = -1; + } // if + } // if + else { + retValue = -1; + } // else + } // else if + else if (strcmp(argv[i], "-s") == 0) { + if (argv[i + 1] != NULL) { + tAttributeSize = atoi(argv[i+1]); + if ((tAttributeSize < 1) || (tAttributeSize > MAXATTRSIZE)) { + retValue = -1; + } // if + } // if + else { + retValue = -1; + } // else + } // else if + else if (strcmp(argv[i], "-no_table_create") == 0) { + theTableCreateFlag = 1; + argc++; + i--; + } // else if + else if (strcmp(argv[i], "-stdtables") == 0) { + theStdTableNameFlag = 1; + argc++; + i--; + } // else if + else if (strcmp(argv[i], "-sleep") == 0) { + if (argv[i + 1] != NULL) { + tSleepTime = atoi(argv[i+1]); + if ((tSleepTime < 1) || (tSleepTime > 3600)) { + retValue = -1; + } // if + } // if + else { + retValue = -1; + } // else + } // else if + else if (strcmp(argv[i], "-abort") == 0) { + // Test scan abort after a number of tuples + theScanAbortTestFlag = 1; + if (argv[i + 1] != NULL) { + tAbortAfter = atoi(argv[i + 1]); + } // if + else { + retValue = -1; + } // else + } // else if + else if (strcmp(argv[i], "-p") == 0) { + if (argv[i + 1] != NULL) { + tParallellism = atoi(argv[i + 1]); + if ((tParallellism < 1) || (tParallellism > 32)) { + retValue = -1; + } // if + } // if + else { + retValue = -1; + } // else + } // else if + else if (strcmp(argv[i], "-h") == 0) { + printFlag = 1; + argc++; + i--; + } // else if + else if (strcmp(argv[i], "-no_scan_update") == 0) { + theNoScanUpdateFlag = 1; + argc++; + i--; + } // else if + else if (strcmp(argv[i], "-no_scan_delete") == 0) { + theNoScanDeleteFlag = 1; + argc++; + i--; + } // else if + else { + retValue = -1; + } // else + + argc -= 2; + i = i + 2; + } + + if ((retValue != 0) || (printFlag == 1)) { + printUsage(); + } // if + + return(retValue); + +} // readArguments + +static void sleepBeforeStartingTest(int seconds) +{ + if (seconds > 0) { + ndbout << "Sleeping(" <getNdbError().message); + ndbout_c("Error code = %d", MyTransaction->getNdbError().code);} + tResult = 20; + } else if (retCode == 2) { + ndbout << "4115 should not happen in flexBench" << endl; + tResult = 20; + } else if (retCode == 3) { +// -------------------------------------------------------------------- +// We are not certain if the transaction was successful or not. +// We must reexecute but might very well find that the transaction +// actually was updated. Updates and Reads are no problem here. Inserts +// will not cause a problem if error code 630 arrives. Deletes will +// not cause a problem if 626 arrives. +// -------------------------------------------------------------------- + /* What can we do here? */ + ndbout_c("execute: %s", MyTransaction->getNdbError().message); + }//if(retCode == 3) + + } // if(check == -1) + + pNdb->closeTransaction(MyTransaction); + } // else + } // for opCount + + return(tResult); +} // insertRows + +static int readRows(Ndb* pNdb, + int* pkValue, + int* readValue) +{ + int tResult = 0; + int tableCount = 0; + int attrCount = 0; + int check = 0; + NdbConnection* MyTransaction = NULL; + NdbOperation* MyOperations[MAXTABLES] = {NULL}; + NdbRecAttr* tmp = NULL; + int Value = 0; + int Index = 0; + int opCount = 0; + + for (opCount = 0; opCount < tNoOfOperations; opCount++) { + MyTransaction = pNdb->startTransaction(); + if (MyTransaction == NULL) { + tResult = 1; + } // if + else { + for (tableCount = 0; tableCount < tNoOfTables; tableCount++) { + + MyOperations[tableCount] = + MyTransaction->getNdbOperation(tableName[tableCount]); + if (MyOperations[tableCount] == NULL) { + tResult = 2; + // Break for tableCount loop + break; + } // if + + check = MyOperations[tableCount]->readTuple(); + if (check == -1) { + tResult = 3; + break; + } // if + + check = MyOperations[tableCount]-> + equal((char*)attrName[0], (char*)&(pkValue[opCount])); + if (check == -1) { + tResult = 7; + break; + } // if + + for (int attrCount = 0; attrCount < tNoOfAttributes - 1; attrCount++) { + Index = tableCount * (tNoOfAttributes - 1) * tNoOfOperations * tAttributeSize + + attrCount * tNoOfOperations * tAttributeSize + opCount * tAttributeSize; + tmp = MyOperations[tableCount]-> + getValue((char*)attrName[attrCount + 1], (char*)&(readValue[Index])); + + if (tmp == NULL) { + tResult = 9; + break; + } // if + } // for attrCount + } // for tableCount + // Execute transaction reading one tuple in every table + check = MyTransaction->execute(Commit); + if (check == -1) { + ndbout << MyTransaction->getNdbError().message << endl; + + // Add complete error handling here + + int retCode = flexScanErrorData->handleErrorCommon(MyTransaction->getNdbError()); + if (retCode == 1) { + if (MyTransaction->getNdbError().code != 626 && MyTransaction->getNdbError().code != 630){ + ndbout_c("execute: %d, %s", opCount, MyTransaction ->getNdbError().message ); + ndbout_c("Error code = %d", MyTransaction->getNdbError().code );} + tResult = 20; + } else if (retCode == 2) { + ndbout << "4115 should not happen in flexBench" << endl; + tResult = 20; + } else if (retCode == 3) { +// -------------------------------------------------------------------- +// We are not certain if the transaction was successful or not. +// We must reexecute but might very well find that the transaction +// actually was updated. Updates and Reads are no problem here. Inserts +// will not cause a problem if error code 630 arrives. Deletes will +// not cause a problem if 626 arrives. +// -------------------------------------------------------------------- + /* What can we do here? */ + ndbout_c("execute: %s", MyTransaction ->getNdbError().message ); + }//if(retCode == 3) + + } // if + + pNdb->closeTransaction(MyTransaction); + } // else + } // for opCount + + return(tResult); +} // readRows + +static int scanReadRows(Ndb* pNdb, int* readValue) +{ + int tResult = 0; + int tableCount = 0; + int attrCount = 0; + int check = 0; + int countAbort = 0; // Counts loops until scan abort if requested + NdbConnection* MyTransaction = NULL; + NdbOperation* MyOperation = NULL; + NdbRecAttr* tmp = NULL; + + + for (tableCount = 0; tableCount < tNoOfTables; tableCount++) { + MyTransaction = pNdb->startTransaction(); + if (MyTransaction == NULL) { + tResult = 1; + break; + } // if + MyOperation = MyTransaction->getNdbOperation(tableName[tableCount]); + if (MyOperation == NULL) { + tResult = 2; + break; + } // if + + check = MyOperation->openScanRead(tParallellism); + if (check == -1) { + tResult = 10; + break; + } // if + + for (int attrCount = 0; attrCount < tNoOfAttributes-1; attrCount++) { + // Get all attributes + tmp = MyOperation-> + getValue((char*)attrName[attrCount+1], + (char*)&(readValue[tableCount*(tNoOfAttributes-1)*tNoOfOperations*tAttributeSize + + attrCount*tNoOfOperations*tAttributeSize])); + if (tmp == NULL) { + tResult = 9; + break; + } // if + } // for attrCount + + check = MyTransaction->executeScan(); + if (check == -1) { + tResult = 12; + break; + } // if + + check = MyTransaction->nextScanResult(); + while (check == 0) { + // Check if scan abort is requested + if (theScanAbortTestFlag == 1) { + if (countAbort == tAbortAfter) { + MyTransaction->stopScan(); + ndbout << "scanread aborted on request after " << countAbort*tParallellism << + " tuples" << endl; + break; // break while loop + } // if + countAbort++; + } // if + check = MyTransaction->nextScanResult(); + } // while + + pNdb->closeTransaction(MyTransaction); + } // for tableCount + + return(tResult); +} // scanReadRows + +static int scanUpdateRows(Ndb* pNdb, + int* readValue, + int* attrValue) +{ + int tResult = 0; + int tableCount = 0; + int attrCount = 0; + int check = 0; + int opCount = 0; + NdbConnection* MyTransaction = NULL; + NdbOperation* MyOperation = NULL; + NdbConnection* MyTakeOverTrans = NULL; + NdbOperation* MyTakeOverOp = NULL; + NdbRecAttr* tTmp = NULL; + + for (tableCount = 0; tableCount < tNoOfTables; tableCount++) { + MyTransaction = pNdb->startTransaction(); + if (MyTransaction == NULL) { + tResult = 1; + break; // break tableCount for loop + } // if + MyOperation = MyTransaction->getNdbOperation(tableName[tableCount]); + if (MyOperation == NULL) { + tResult = 2; + break; + } // if + + check = MyOperation->openScanExclusive(tParallellism); + if (check == -1) { + tResult = 11; + break; + } // if + + MyOperation->interpret_exit_ok(); + // Fetch all attributes + for (int attrCount = 0; attrCount < tNoOfAttributes-1; attrCount++) { + tTmp = MyOperation-> + getValue((char*)attrName[attrCount+1], + (char*)&(readValue[tableCount*(tNoOfAttributes-1)*tNoOfOperations*tAttributeSize + + attrCount*tNoOfOperations*tAttributeSize])); + if (tTmp == NULL) { + tResult = 9; + break; // break for loop + } // if + } // for + if (tResult != 0) { + break; // break while loop also + } // if + + check = MyTransaction->executeScan(); + if (check == -1) { + tResult = 12; + break; + } // if + check = MyTransaction->nextScanResult(); + opCount = 0; + while (check == 0) { + MyTakeOverTrans = pNdb->startTransaction(); + MyTakeOverOp = MyOperation->takeOverForUpdate(MyTakeOverTrans); + for (attrCount = 0; attrCount < tNoOfAttributes-1; attrCount++) { + check = MyTakeOverOp->setValue((char*)attrName[attrCount+1], + (char*)&(attrValue[tableCount*(tNoOfAttributes-1)*tNoOfOperations*tAttributeSize + + attrCount*tNoOfOperations*tAttributeSize + opCount*tAttributeSize])); + } // for + + check = MyTakeOverTrans->execute(Commit); + if (check == 0) { + check = MyTransaction->nextScanResult(); + opCount++; + } // if + else { + tResult = 95; + + /* MyTransaction, MyTakeOverTrans, Which one? */ + + // Any further error handling? + int retCode = flexScanErrorData->handleErrorCommon(MyTakeOverTrans->getNdbError()); + if (retCode == 1) { + if (MyTakeOverTrans->getNdbError().code != 626 && MyTakeOverTrans->getNdbError().code != 630){ + ndbout_c("execute: %s", MyTakeOverTrans->getNdbError().message); + ndbout_c("Error code = %d", MyTakeOverTrans->getNdbError().code);} + tResult = 20; + } else if (retCode == 2) { + ndbout << "4115 should not happen in flexBench" << endl; + tResult = 20; + } else if (retCode == 3) { + // -------------------------------------------------------------------- + // We are not certain if the transaction was successful or not. + // We must reexecute but might very well find that the transaction + // actually was updated. Updates and Reads are no problem here. Inserts + // will not cause a problem if error code 630 arrives. Deletes will + // not cause a problem if 626 arrives. + // -------------------------------------------------------------------- + /* What can we do here? */ + ndbout_c("execute: %s", MyTakeOverTrans->getNdbError().message); + }//if(retCode == 3) + + } // else + pNdb->closeTransaction(MyTakeOverTrans); + } // while + + pNdb->closeTransaction(MyTransaction); + } // for + + return(tResult); +} // scanUpdateRows + +static int scanDeleteRows(Ndb* pNdb, int* readValue) +{ + int tResult = 0; + int tableCount = 0; + int attrCount = 0; + int check = 0; + NdbRecAttr* tTmp = NULL; + NdbConnection* MyTransaction = NULL; + NdbOperation* MyOperation = NULL; + NdbConnection* MyTakeOverTrans = NULL; + NdbOperation* MyTakeOverOp = NULL; + + for (tableCount = 0; tableCount < tNoOfTables; tableCount++) { + MyTransaction = pNdb->startTransaction(); + if (MyTransaction == NULL) { + tResult = 1; + break; // break tableCount for loop + } // if + + MyOperation = MyTransaction->getNdbOperation(tableName[tableCount]); + if (MyOperation == NULL) { + tResult = 2; + break; + } // if + + check = MyOperation->openScanExclusive(tParallellism); + if (check == -1) { + tResult = 11; + break; + } // if + + MyOperation->interpret_exit_ok(); + for (int attrCount = 0; attrCount < tNoOfAttributes-1; attrCount++) { + tTmp = MyOperation-> + getValue((char*)attrName[attrCount+1], + (char*)&(readValue[tableCount*(tNoOfAttributes-1)*tNoOfOperations + + attrCount*tNoOfOperations])); + if (tTmp == NULL) { + tResult = 9; + break; + } // if + } // for + + check = MyTransaction->executeScan(); + if (check == -1) { + tResult = 12; + break; + } // if + check = MyTransaction->nextScanResult(); + while (check == 0) { + MyTakeOverTrans = pNdb->startTransaction(); + MyTakeOverOp = MyOperation->takeOverForDelete(MyTakeOverTrans); + check = MyTakeOverOp->deleteTuple(); + + check = MyTakeOverTrans->execute(Commit); + + //Error handling here + + int retCode =flexScanErrorData->handleErrorCommon(MyTakeOverTrans->getNdbError()); + if (retCode == 1) { + if (MyTakeOverTrans->getNdbError().code != 626 && MyTakeOverTrans->getNdbError().code != 630){ + ndbout_c("execute: %s", MyTakeOverTrans->getNdbError().message ); + ndbout_c("Error code = %d", MyTakeOverTrans->getNdbError().code );} + tResult = 20; + } else if (retCode == 2) { + ndbout << "4115 should not happen in flexBench" << endl; + tResult = 20; + } else if (retCode == 3) { +// -------------------------------------------------------------------- +// We are not certain if the transaction was successful or not. +// We must reexecute but might very well find that the transaction +// actually was updated. Updates and Reads are no problem here. Inserts +// will not cause a problem if error code 630 arrives. Deletes will +// not cause a problem if 626 arrives. +// -------------------------------------------------------------------- + /* What can we do here? */ + ndbout_c("execute: %s", MyTakeOverTrans->getNdbError().message ); + }//if(retCode == 3) End of error handling + + pNdb->closeTransaction(MyTakeOverTrans); + check = MyTransaction->nextScanResult(); + } // while + pNdb->closeTransaction(MyTransaction); + } // for tableCount + return(tResult); +} // scanDeleteRows + +static int deleteRows(Ndb* pNdb, + int* pkValue) +{ + int tResult = 0; + NdbConnection* MyTransaction = NULL; + int tableCount = 0; + int opCount = 0; + int check = 0; + NdbOperation* MyOperations[MAXTABLES] = {NULL}; + + for (opCount = 0; opCount < tNoOfOperations; opCount++) { + MyTransaction = pNdb->startTransaction(); + if (MyTransaction == NULL) { + tResult = 1; + } // if + else { + for (tableCount = 0; tableCount < tNoOfTables; tableCount++) { + + MyOperations[tableCount] = + MyTransaction->getNdbOperation(tableName[tableCount]); + if (MyOperations[tableCount] == NULL) { + tResult = 2; + // Break for tableCount loop + break; + } // if + + check = MyOperations[tableCount]->deleteTuple(); + if (check == -1) { + tResult = 3; + break; + } // if + + check = MyOperations[tableCount]-> + equal((char*)attrName[0], (char*)&(pkValue[opCount])); + if (check == -1) { + tResult = 7; + break; + } // if + + } // for tableCount + + // Execute transaction deleting one tuple in every table + check = MyTransaction->execute(Commit); + if (check == -1) { + ndbout << MyTransaction->getNdbError().message << endl; + // Add complete error handling here + + int retCode = flexScanErrorData->handleErrorCommon(MyTransaction->getNdbError()); + if (retCode == 1) { + if (MyTransaction->getNdbError().code != 626 && MyTransaction->getNdbError().code != 630){ + ndbout_c("execute: %d, %s", opCount, MyTransaction->getNdbError().message ); + ndbout_c("Error code = %d", MyTransaction->getNdbError().code );} + tResult = 20; + } else if (retCode == 2) { + ndbout << "4115 should not happen in flexBench" << endl; + tResult = 20; + } else if (retCode == 3) { +// -------------------------------------------------------------------- +// We are not certain if the transaction was successful or not. +// We must reexecute but might very well find that the transaction +// actually was updated. Updates and Reads are no problem here. Inserts +// will not cause a problem if error code 630 arrives. Deletes will +// not cause a problem if 626 arrives. +// -------------------------------------------------------------------- + /* What can we do here? */ + ndbout_c("execute: %s", MyTransaction->getNdbError().message ); + }//if(retCode == 3) + + } // if + + pNdb->closeTransaction(MyTransaction); + } // else + } // for opCount + + return(tResult); + +} // deleteRows + +//////////////////////////////////////// +// +// Name: verifyDeleteRows +// +// Purpose: Verifies that all tables are empty by reading every tuple +// No deletions made here +// +// Returns: 'Standard' error codes +// +///////////////////////////////////// +static int verifyDeleteRows(Ndb* pNdb, + int* pkValue, + int* readValue) +{ + int tResult = 0; + int tableCount = 0; + int attrCount = 0; + int check = 0; + NdbConnection* MyTransaction = NULL; + NdbOperation* MyOperations = NULL; + NdbRecAttr* tmp = NULL; + int Value = 0; + int Index = 0; + int opCount = 0; + + for (opCount = 0; opCount < tNoOfOperations; opCount++) { + for (tableCount = 0; tableCount < tNoOfTables; tableCount++) { + MyTransaction = pNdb->startTransaction(); + if (MyTransaction == NULL) { + tResult = 1; + } // if + else { + + MyOperations = + MyTransaction->getNdbOperation(tableName[tableCount]); + if (MyOperations == NULL) { + tResult = 2; + // Break for tableCount loop + break; + } // if + + check = MyOperations->readTuple(); + if (check == -1) { + tResult = 3; + break; + } // if + + check = MyOperations-> + equal((char*)attrName[0], (char*)&(pkValue[opCount])); + if (check == -1) { + tResult = 7; + break; + } // if + + for (int attrCount = 0; attrCount < tNoOfAttributes - 1; attrCount++) { + Index = tableCount * (tNoOfAttributes - 1) * tNoOfOperations * tAttributeSize + + attrCount * tNoOfOperations * tAttributeSize + opCount * tAttributeSize; + tmp = MyOperations-> + getValue((char*)attrName[attrCount + 1], (char*)&(readValue[Index])); + + if (tmp == NULL) { + tResult = 9; + break; + } // if + } // for attrCount + // Execute transaction reading one tuple in every table + check = MyTransaction->execute(Commit); + if ((check == -1) && (MyTransaction->getNdbError().code == 626)){ + // This is expected because everything should be deleted + } // if + else if (check == 0) { + // We have found a tuple that should have been deleted + ndbout << "tuple " << tableName[tableCount] << ":" << + opCount << " was never deleted" << endl; + tResult = 97; + } // else if + else { + // Unexpected error + ndbout << "Unexpected error during delete" << endl; + assert(false); + } // else + + pNdb->closeTransaction(MyTransaction); + + } // else + } // for tableCount + } // for opCount + + return(tResult); +} // verifyDeleteRows diff --git a/ndb/test/ndbapi/flexScan/Makefile b/ndb/test/ndbapi/flexScan/Makefile deleted file mode 100644 index 78f9d481063..00000000000 --- a/ndb/test/ndbapi/flexScan/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := flexScan - -SOURCES := flexScan.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/flexScan/README b/ndb/test/ndbapi/flexScan/README deleted file mode 100644 index cddbdea5336..00000000000 --- a/ndb/test/ndbapi/flexScan/README +++ /dev/null @@ -1,66 +0,0 @@ - -Executing flexScan-tests automatically -====================================== - - -It is possible to execute almost al the flexBench-tests -automatically. The procedure contains three steps: -- increase the number of attributes (flexScan -a number) -- increase the size of attributes (flexScan -s number) -- increase the number of threads (flexScan -t number) - -Each of these steps are performed by the scripts test1.sh -test2.sh and test3.sh. Each test will start Ndb, execute -the test and close Ndb again in order to execute each test -in a 'clean' Ndb-environment. So make sure that there is -no Ndb running when you start the test. - - -1. Setup - -To perform the tests automatically, the following issues -have to be taken care of: - -- be sure that you have a directory bin in your home-directory. - In this directory, you need to have a link 'runndb' to the - ndb executable. You can do this by executing a shell-command like: - ln -s ndb/Emulator/Main/ndb runndb - The script is not yet so far that it performs checks, so if - you forget about this, things will get messy. -- In this directory you need a Ndb.cfg for a server-configuration. - - -2. Command - -I assume you have Ndb and the API compiled or you use the -'released' version. Compile flexScan as usual with 'make'. -Now you can start the tests by typing 'make test'. The -execution of the test will take a while. - - -3. Results - -The scripts will write their results in the file report.txt. -The scripts will start with a short summary on the test. Then -it will add 1 line documenting each run of flexScan that is -ececuted. Finally, it will print highest 'score'. The file -report.txt is probably good enough to check in directly as -testprotocol in ndb/test/docs/testprotocols. - - -4. Log files. - -To make it possible to investigate errors, the output from -the flexScan-run where the error occurred is stored in -test1.log, test2.log or test3.log respectively. They are -overwritten each time you start 'make test'. - - -HINT - -The number of iterations in each test-script is not directly -limited by the number of attributes or the size of the -attributes but by the number of tables that you are allowed -to create. Probably this will be the error that occurs if -you execute the test. You migh adjust the begin-values and -the step-size in the individual scripts if you want. diff --git a/ndb/test/ndbapi/flexScan/flexScan.cpp b/ndb/test/ndbapi/flexScan/flexScan.cpp deleted file mode 100644 index 19fb6dc5ab0..00000000000 --- a/ndb/test/ndbapi/flexScan/flexScan.cpp +++ /dev/null @@ -1,1674 +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 */ - -/* *************************************************** - FLEXSCAN - Perform benchmark of: - insert - read - scan read - update - scan update - read - scan delete - verify delete - - Arguments: - -f Location of Ndb.cfg file, default Ndb.cfg - -t Number of threads to start, default 1 - -o Number of operations per loop, default 500 -l Number of loops to run, default 1, 0=infinite - -a Number of attributes, default 25 - -c Number of tables, default 1 - -s Size of each attribute, default 1 - -stdtables Use standard table names - -no_table_create Don't create tables in db - -sleep Sleep a number of seconds before running the test, this - can be used so that another flexBench hav etome to create tables - -p Parallellism to use 1-32, default:1 - -abort Test scan abort after a number of tuples - -h Print help text - -no_scan_update Don't do scan updates - -no_scan_delete Don't do scan deletes - - Returns: - NDBT_OK - Test passed - NDBT_FAILED - Test failed - - Revision history: - 1.12 020222 epesson: Rewritten to use NDBT. Major bugs fixed - - * *************************************************** */ - -#include "NdbApi.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include - -#define PKSIZE 1 -#define FOREVER 1 -#define MAXSTRLEN 16 -#define MAXATTR 64 -#define MAXTABLES 64 -#define MAXTHREADS 256 -#define MAXATTRSIZE 64 - -enum StartType { - stIdle, - stInsert, - stRead, - stScanRead, - stUpdate, - stScanUpdate, - stDelete, - stVerifyDelete, - stScanDelete, - stStop, - stLast} ; - - -struct ThreadNdb -{ - int ThreadNo; - NdbThread* threadLife; - StartType threadStart; - int threadResult; - int threadReady; -}; - -extern "C" void* flexScanThread(void*); -static int setAttrNames(void); -static int setTableNames(void); -static int createTables(Ndb* pMyNdb); -static void sleepBeforeStartingTest(int seconds); -static int readArguments(int argc, const char** argv); -static void setAttrValues(int* attrValue, - int* readValue, - int Offset); -static int insertRows(Ndb* pNdb, int* pkValue, int* attrValue, StartType tType); -static int readRows(Ndb* pNdb, int* pkValue, int* readValue); -static int deleteRows(Ndb* pNdb, int* pkValue); -static int scanReadRows(Ndb* pNdb, int* readValue); -static int scanUpdateRows(Ndb* pNdb, int* readValue, int* attrValue); -static int scanDeleteRows(Ndb* pNdb, int* readValue); -static int verifyDeleteRows(Ndb* pNdb, int* pkValue, int* readValue); -static void Compare(int* attrValue, int* readValue); -static void UpdateArray(int *attrValue); - -static int tNoOfThreads = 1; -static int tNoOfAttributes = 25; -static int tNoOfTables = 1; -static int tAttributeSize = 1; -static int tNodeId = 0; -static int tNoOfOperations = 500; -static int tNoOfLoops = 1; -static int tAbortAfter = 0; -static int tParallellism = 1; - -static char tableName[MAXTABLES][MAXSTRLEN]; -static char attrName[MAXATTR][MAXSTRLEN]; - -static unsigned int tSleepTime = 0; - -static int theStdTableNameFlag = 0; -static int theTableCreateFlag = 0; -static int theScanAbortTestFlag = 0; -static int theNoScanUpdateFlag = 0; -static int theNoScanDeleteFlag = 0; - -//flexScanErrorData = new ErrorData; -ErrorData * flexScanErrorData; -NdbError * anerror; - -//static errorData theErrorData; -//static unsigned int tErrorCounter[6000]; - -#define START_TIMER { NdbTimer timer; timer.doStart(); -#define STOP_TIMER timer.doStop(); -#define PRINT_TIMER(text, trans, opertrans) timer.printTransactionStatistics(text, trans, opertrans); }; - -static void UpdateArray(int *attrValue) -{ - int tableCount = 0; - int attrCount = 0; - int opCount = 0; - int sizeCount = 0; - int Index = 0; - int* pValue = attrValue; - - for (tableCount = 0; tableCount < tNoOfTables; tableCount++) { - for (attrCount = 0; attrCount < tNoOfAttributes-1; attrCount++) { - for (opCount = 0; opCount < tNoOfOperations; opCount++) { - for (sizeCount = 0; sizeCount < tAttributeSize; sizeCount++) { - // Update value in array - (*pValue)++; - //ndbout << "attrValue[" << tableCount*tNoOfAttributes*tNoOfOperations*tAttributeSize + - //attrCount*tNoOfOperations*tAttributeSize + opCount*tAttributeSize + sizeCount << - //"] = " << attrValue[tableCount*tNoOfAttributes*tNoOfOperations*tAttributeSize + - //attrCount*tNoOfOperations*tAttributeSize + opCount*tAttributeSize + sizeCount] << endl; - // Increment pointer - pValue++; - } // sizeCount - } // for opCount - } // for attrCount - } // for tableCount - -} // Update - -static void Compare(int* attrValue, int* readValue) -{ - int tableCount = 0; - int attrCount = 0; - int OpCount = 0; - int first = 0; - int sizeCount = 0; - - for (tableCount = 0; tableCount < tNoOfTables; tableCount++) { - for (attrCount = 0; attrCount < tNoOfAttributes-1; attrCount++) { - for (OpCount = 0; OpCount < tNoOfOperations; OpCount++) { - if (memcmp(&(attrValue[tableCount*(tNoOfAttributes-1)*tNoOfOperations + - attrCount*tNoOfOperations + OpCount]), - &(readValue[tableCount*(tNoOfAttributes-1)*tNoOfOperations + - attrCount*tNoOfOperations + OpCount]), - tAttributeSize) != 0) { - // Values mismatch - if (first == 0) { - //ndbout << "Read and set values differ for:" << endl; - first = 1; - ndbout << "Mismatch found."; - } // if - // Comparision of values after scan update is meaningless right now - //ndbout << " table " << tableName[tableCount] << - //" - attr " << attrName[attrCount+1]; - //for (sizeCount = 0; sizeCount < tAttributeSize; sizeCount++) { - //ndbout << ": set " << - //attrValue[tableCount*(tNoOfAttributes-1)*tNoOfOperations*tAttributeSize + - //attrCount*tNoOfOperations*tAttributeSize + - //tNoOfOperations*tAttributeSize + sizeCount] << " read " << - //readValue[tableCount*(tNoOfAttributes-1)*tNoOfOperations*tAttributeSize + - //attrCount*tNoOfOperations*tAttributeSize + - //tNoOfOperations*tAttributeSize + sizeCount] << endl; - //} // for - } // if - } // for OpCount - } // for attrCount - } // for tableCount - - // A final pretty-print - if (first == 1) { - ndbout << endl; - } // if -} // Compare - -static void printInfo() -{ - ndbout << endl << "FLEXSCAN - Starting normal mode" << endl; - ndbout << "Perform benchmark of insert, update and delete transactions"<< endl; - ndbout << " NdbAPI node with id = " << tNodeId << endl; - ndbout << " " << tNoOfThreads << " thread(s) " << endl; - ndbout << " " << tNoOfLoops << " iterations " << endl; - ndbout << " " << tNoOfTables << " table(s) and " << 1 << " operation(s) per transaction " - << endl; - ndbout << " " << tNoOfAttributes << " attributes per table incl. pk" << endl; - ndbout << " " << tNoOfOperations << " transaction(s) per thread and round " << endl; - if (theScanAbortTestFlag == 1) { - ndbout << " Scan abort test after " << tAbortAfter << " tuples" << endl; - } // if - ndbout << " " << tParallellism << " parallellism in scans" << endl; - ndbout << " " << tAttributeSize << " is the number of 32 bit words per attribute " << - endl << endl; - -} // printInfo - -static void tellThreads(ThreadNdb *threadArrayP, StartType what) -{ - int i = 0; - - for (i = 0; i < tNoOfThreads ; i++) - threadArrayP[i].threadStart = what; -} // tellThreads - -static void waitForThreads(ThreadNdb *threadArrayP) -{ - int i = 0; - int cont = 1; - - while (cont == 1){ - - NdbSleep_MilliSleep(10); - cont = 0; - - for (i = 0; i < tNoOfThreads ; i++) { - if (threadArrayP[i].threadReady == 0) { -// ndbout << "Main is reporting thread " << i << " not ready" << endl; - cont = 1; - } // if - } // for - } // while -} // waitForThreads - - -static void resetThreads(ThreadNdb *threadArrayP) -{ - int i = 0; - - for (i = 0; i < tNoOfThreads ; i++) { - threadArrayP[i].threadReady = 0; - threadArrayP[i].threadResult = 0; - threadArrayP[i].threadStart = stIdle; - //ndbout << "threadStart[" << i << "]=" << - //threadArrayP[i].threadStart << endl; - } // for -} // resetThreads - -static int checkThreadResults(ThreadNdb *threadArrayP, char *action) -{ - int i = 0; - int retValue = 0; - - for (i = 0; i < tNoOfThreads; i++) { - if (threadArrayP[i].threadResult != 0) { - ndbout << "Thread " << i << " reported fatal error " - << threadArrayP[i].threadResult << " during " << action << endl; - retValue = -1; - break; - } // if - } // for - - return(retValue); -} // checkThreadResults - -NDB_COMMAND(flexScan, "flexScan", "flexScan", "flexScan", 65535) -{ - ThreadNdb* pThreads = NULL; - Ndb* pMyNdb = NULL; - int tLoops = 0; - int check = 0; - int returnValue = NDBT_OK; - int every2ndScanDelete = 0; // Switch between scan delete and normal delete - - flexScanErrorData = new ErrorData; - - flexScanErrorData->resetErrorCounters(); - - if (readArguments(argc, argv) != 0) { - ndbout << "Wrong arguments to flexScan" << endl; - return NDBT_ProgramExit(NDBT_WRONGARGS); - } // if - - /* print Setting */ - flexScanErrorData->printSettings(ndbout); - - check = setAttrNames(); - if (check != 0) { - ndbout << "Couldn't set attribute names" << endl; - return NDBT_ProgramExit(NDBT_FAILED); - } // if - check = setTableNames(); - if (check != 0) { - ndbout << "Couldn't set table names" << endl; - return NDBT_ProgramExit(NDBT_FAILED); - } // if - - pMyNdb = new Ndb ("TEST_DB"); - pMyNdb->init(); - tNodeId = pMyNdb->getNodeId(); - - printInfo(); - - NdbThread_SetConcurrencyLevel(tNoOfThreads + 2); - //NdbThread_SetConcurrencyLevel(tNoOfThreads + 8); - - pThreads = new ThreadNdb[tNoOfThreads]; - - if (pMyNdb->waitUntilReady(10000) != 0) { - ndbout << "NDB is not ready" << endl << "Benchmark failed" << endl; - returnValue = NDBT_FAILED; - } // if - - else { - - if (createTables(pMyNdb) != 0) { - ndbout << "Could not create tables" << endl; - returnValue = NDBT_FAILED; - } // if - else { - sleepBeforeStartingTest(tSleepTime); - - resetThreads(pThreads); - // Create threads - for (int i = 0; i < tNoOfThreads ; i++){ - pThreads[i].ThreadNo = i; - // Ignore the case that thread creation may fail - pThreads[i].threadLife = NdbThread_Create(flexScanThread, - (void**)&pThreads[i], - 327680, - "flexScanThread", NDB_THREAD_PRIO_LOW); - if (pThreads[i].threadLife == NULL) { - ndbout << "Could not create thread " << i << endl; - returnValue = NDBT_FAILED; - // Use the number of threads that were actually created - tNoOfThreads = i; - break; // break for loop - } // if - } // for - - waitForThreads(pThreads); - if (checkThreadResults(pThreads, "init") != 0) { - returnValue = NDBT_FAILED; - } // if - - if (returnValue == NDBT_OK) { - ndbout << "All threads started" << endl; - - while (FOREVER) { - - resetThreads(pThreads); - - if ((tNoOfLoops != 0) && (tNoOfLoops <= tLoops)) { - break; - } // if - - // Insert - START_TIMER; - - tellThreads(pThreads, stInsert); - waitForThreads(pThreads); - - STOP_TIMER; - if (checkThreadResults(pThreads, "insert") != 0) { - returnValue = NDBT_FAILED; - break; - } // if - PRINT_TIMER("insert", tNoOfOperations*tNoOfThreads, tNoOfTables); - - resetThreads(pThreads); - - // Read - START_TIMER; - - tellThreads(pThreads, stRead); - waitForThreads(pThreads); - - STOP_TIMER; - if (checkThreadResults(pThreads, "read") != 0) { - returnValue = NDBT_FAILED; - break; - } // if - PRINT_TIMER("read", tNoOfOperations*tNoOfThreads, tNoOfTables); - - resetThreads(pThreads); - - // Update - START_TIMER; - - tellThreads(pThreads, stUpdate); - waitForThreads(pThreads); - - STOP_TIMER; - if (checkThreadResults(pThreads, "update") != 0) { - returnValue = NDBT_FAILED; - break; - } // if - PRINT_TIMER("update", tNoOfOperations*tNoOfThreads, tNoOfTables); - - resetThreads(pThreads); - - // Scan read - START_TIMER; - - tellThreads(pThreads, stScanRead); - waitForThreads(pThreads); - - STOP_TIMER; - if (checkThreadResults(pThreads, "scanread") != 0) { - returnValue = NDBT_FAILED; - break; - } // if - PRINT_TIMER("scanread", tNoOfTables*tNoOfThreads, 1); - - resetThreads(pThreads); - - // Update - START_TIMER; - - tellThreads(pThreads, stUpdate); - waitForThreads(pThreads); - - STOP_TIMER; - if (checkThreadResults(pThreads, "update") != 0) { - returnValue = NDBT_FAILED; - break; - } // if - PRINT_TIMER("update", tNoOfOperations*tNoOfThreads, tNoOfTables); - - resetThreads(pThreads); - - // Read - START_TIMER; - - tellThreads(pThreads, stRead); - waitForThreads(pThreads); - - STOP_TIMER; - if (checkThreadResults(pThreads, "read") != 0) { - returnValue = NDBT_FAILED; - break; - } // if - PRINT_TIMER("read", tNoOfOperations*tNoOfThreads, tNoOfTables); - - resetThreads(pThreads); - - // Only do scan update if told to do so - if (theNoScanUpdateFlag == 0) { - // Scan update - START_TIMER; - - tellThreads(pThreads, stScanUpdate); - waitForThreads(pThreads); - - STOP_TIMER; - if (checkThreadResults(pThreads, "scanupdate") != 0) { - returnValue = NDBT_FAILED; - break; - } // if - PRINT_TIMER("scanupdate", tNoOfTables*tNoOfThreads, 1); - - resetThreads(pThreads); - - // Read - START_TIMER; - - tellThreads(pThreads, stRead); - // tellThreads(pThreads, stScanRead); - waitForThreads(pThreads); - - STOP_TIMER; - if (checkThreadResults(pThreads, "read") != 0) { - returnValue = NDBT_FAILED; - break; - } // if - PRINT_TIMER("read", tNoOfOperations*tNoOfThreads, tNoOfTables); - - resetThreads(pThreads); - } // if theNoScanUpdateFlag - - // Shift between delete and scan delete - if ((every2ndScanDelete % 2 == 0) || (theNoScanDeleteFlag == 1)){ - // Delete - START_TIMER; - tellThreads(pThreads, stDelete); - waitForThreads(pThreads); - - STOP_TIMER; - if (checkThreadResults(pThreads, "delete") != 0) { - returnValue = NDBT_FAILED; - break; - } // if - PRINT_TIMER("delete", tNoOfOperations*tNoOfThreads, tNoOfTables); - resetThreads(pThreads); - } // if - else { - resetThreads(pThreads); // Scan delete - START_TIMER; - tellThreads(pThreads, stScanDelete); - waitForThreads(pThreads); - - STOP_TIMER; - if (checkThreadResults(pThreads, "scandelete") != 0) { - returnValue = NDBT_FAILED; - break; - } // if - PRINT_TIMER("scandelete", tNoOfTables*tNoOfThreads, 1); - - resetThreads(pThreads); - } // else - every2ndScanDelete++; - - resetThreads(pThreads); // Verify delete - START_TIMER; - tellThreads(pThreads, stVerifyDelete); - waitForThreads(pThreads); - - STOP_TIMER; - if (checkThreadResults(pThreads, "verifydelete") != 0) { - returnValue = NDBT_FAILED; - break; - } // if - PRINT_TIMER("verifydelete", tNoOfOperations*tNoOfThreads*tNoOfTables, 1); - - resetThreads(pThreads); - - ndbout << "--------------------------------------------------" << endl; - tLoops++; - - } // while - } // if - } // else - } // else - - // Stop threads in a nice way - tellThreads(pThreads, stStop); - waitForThreads(pThreads); - - // Clean up - delete [] pThreads; - delete pMyNdb; - - flexScanErrorData->printErrorCounters(ndbout); - - if (returnValue == NDBT_OK) { - ndbout << endl << "Benchmark completed successfully" << endl; - } // if - else { - ndbout << endl << "Benchmark failed" << endl; - } // else - - // Exit via NDBT - return NDBT_ProgramExit(returnValue);; -} // main - -void* -flexScanThread(void* ThreadData) -{ - ThreadNdb* pThreadData = (ThreadNdb*)ThreadData; - unsigned int thread_no = pThreadData->ThreadNo; - unsigned int thread_base = (thread_no * 2000000) + (tNodeId * 26000); - int NrOfScannedRecords = 0; - int tThreadResult = 0; - Ndb* MyNdb = NULL; - NdbConnection *MyTransaction = NULL; - NdbOperation* MyOperation[MAXTABLES]; - int check = 0; - StartType tType = stLast; - int* pkValue = NULL; - int* attrValue = NULL; - int* readValue = NULL; - int AllocSize = 0; - NdbRecAttr* tTmp = NULL; - OperationType opType; - - AllocSize = tNoOfTables * (tNoOfAttributes-1) * tNoOfOperations * - tAttributeSize * sizeof(int); - attrValue = (int*)malloc(AllocSize); - readValue = (int*)malloc(AllocSize); - pkValue = (int*)malloc(tNoOfOperations * sizeof(int)); - if ((attrValue == NULL) || (readValue == NULL) || (pkValue == NULL)) { - tThreadResult = 98; - pThreadData->threadStart = stIdle; - } // if - - setAttrValues(attrValue, readValue, thread_base); - - MyNdb = new Ndb( "TEST_DB" ); - MyNdb->init(); - if (MyNdb->waitUntilReady(10000) != 0) { - tThreadResult = 99; - pThreadData->threadStart = stIdle; - } // if - - // Set primary key value, same for all tables - for (int c = 0; c < tNoOfOperations; c++) { - pkValue[c] = (int)(c + thread_base); - } // for - - while (FOREVER) { - pThreadData->threadResult = tThreadResult; - pThreadData->threadReady = 1; - - while (pThreadData->threadStart == stIdle) { - NdbSleep_MilliSleep(10); - } // while - - // Check if signal to exit is received - if (pThreadData->threadStart >= stStop){ - pThreadData->threadReady = 1; - break; - } // if - tType = pThreadData->threadStart; - pThreadData->threadStart = stIdle; - - switch (tType) { - case stInsert: - check = insertRows(MyNdb, pkValue, attrValue, tType); - break; - case stRead: - check = readRows(MyNdb, pkValue, readValue); - Compare(attrValue, readValue); - break; - case stUpdate: - UpdateArray(attrValue); - check = insertRows(MyNdb, pkValue, attrValue, tType); - break; - case stScanRead: - //check = readRows(MyNdb, pkValue, readValue); - check = scanReadRows(MyNdb, readValue); - Compare(attrValue, readValue); - break; - case stScanUpdate: - UpdateArray(attrValue); - //tType = stUpdate; - //check = insertRows(MyNdb, pkValue, attrValue, tType); - check = scanUpdateRows(MyNdb, readValue, attrValue); - break; - case stDelete: - check = deleteRows(MyNdb, pkValue); - break; - case stScanDelete: - check = scanDeleteRows(MyNdb, readValue); - break; - case stVerifyDelete: - check = verifyDeleteRows(MyNdb, pkValue, readValue); - break; - default: - ndbout << "tType is " << tType << endl; - assert(false); - break; - } // switch - - tThreadResult = check; - - if (tThreadResult != 0) { - // Check if error is fatak or not - } // if - else { - continue; - } // else - } // while - - // Clean up - delete MyNdb; - if (attrValue != NULL) { - free(attrValue); - } //if - if (readValue != NULL) { - free(readValue); - } // if - if (pkValue != NULL) { - free(pkValue); - } // if - - NdbThread_Exit(0); - return NULL; - -} // flexScanThread - - -static int setAttrNames() -{ - int i = 0; - int retVal = 0; - - for (i = 0; i < MAXATTR ; i++) { - retVal = snprintf(attrName[i], MAXSTRLEN, "COL%d", i); - if (retVal < 0) { - return(-1); - } // if - } // for - - return(0); -} // setAttrNames - - -static int setTableNames() -{ - // Note! Uses only uppercase letters in table name's - // so that we can look at the tables with SQL - int i = 0; - int retVal = 0; - - for (i = 0; i < MAXTABLES ; i++) { - - if (theStdTableNameFlag == 0) { - retVal = snprintf(tableName[i], MAXSTRLEN, "TAB%d_%d", i, - (int)(NdbTick_CurrentMillisecond() / 1000)); - } // if - else { - retVal = snprintf(tableName[i], MAXSTRLEN, "TAB%d", i); - } // if else - - if (retVal < 0) { - return(-1); - } // if - } // for - - return(0); -} // setTableNames - - -// Create Table and Attributes. -static int createTables(Ndb* pMyNdb) -{ - - NdbSchemaCon *MySchemaTransaction = NULL; - NdbSchemaOp *MySchemaOp = NULL; - int i = 0; - int j = 0; - int check = 0; - - if (theTableCreateFlag == 0) { - - i = 0; - do { - i++; - ndbout << endl << "Creating " << tableName[i - 1] << "..." << endl; - - MySchemaTransaction = pMyNdb->startSchemaTransaction(); - if( MySchemaTransaction == NULL ) { - return (-1); - } // if - - MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); - if( MySchemaOp == NULL ) { - pMyNdb->closeSchemaTransaction(MySchemaTransaction); - return (-1); - } // if - -#if defined NDB_OSE || defined NDB_SOFTOSE - check = MySchemaOp->createTable(tableName[i - 1], - 8, // Table Size - TupleKey, // Key Type - 40, // Nr of Pages - All, - 6, - 78, - 80, - 1, - false); -#else - check = MySchemaOp->createTable(tableName[i - 1] - ,8 // Table Size - ,TupleKey // Key Type - ,40); // Nr of Pages -#endif - if (check == -1) { - pMyNdb->closeSchemaTransaction(MySchemaTransaction); - return -1; - } // if - - check = MySchemaOp->createAttribute( (char*)attrName[0], TupleKey, 32, PKSIZE, - UnSigned, MMBased, NotNullAttribute ); - if (check == -1) { - pMyNdb->closeSchemaTransaction(MySchemaTransaction); - return -1; - } // if - - for (j = 1; j < tNoOfAttributes ; j++) { - check = MySchemaOp->createAttribute( (char*)attrName[j], NoKey, 32, tAttributeSize, - UnSigned, MMBased, NotNullAttribute ); - if (check == -1) { - pMyNdb->closeSchemaTransaction(MySchemaTransaction); - return -1; - } // if - } // for - - if (MySchemaTransaction->execute() == -1) { - ndbout << MySchemaTransaction->getNdbError().message << endl; - ndbout << "Probably, " << tableName[i - 1] << " already exist" << endl; - } // if - - pMyNdb->closeSchemaTransaction(MySchemaTransaction); - } while (tNoOfTables > i); - } - - return 0; -} // createTables - -static void printUsage() -{ - ndbout << "Usage of flexScan:" << endl; - ndbout << "-f Location of Ndb.cfg file, default: Ndb.cfg" << endl; - ndbout << "-t Number of threads to start, default 1" << endl; - ndbout << "-o Number of operations per loop, default 500" << endl; - ndbout << "-l Number of loops to run, default 1, 0=infinite" << endl; - ndbout << "-a Number of attributes, default 25" << endl; - ndbout << "-c Number of tables, default 1" << endl; - ndbout << "-s Size of each attribute, default 1" << endl; - ndbout << "-stdtables Use standard table names" << endl; - ndbout << "-no_table_create Don't create tables in db" << endl; - ndbout << "-sleep Sleep a number of seconds before running the test" << endl; - ndbout << "-p Parallellism to use 1-32, default:1" << endl; - ndbout << "-abort Test scan abort after a number of tuples" << endl; - ndbout << "-no_scan_update Don't do scan updates" << endl; - ndbout << "-no_scan_delete Don't do scan deletes" << endl; - ndbout << "-h Print this text" << endl; - // inputErrorArg(); - flexScanErrorData->printCmdLineArgs(ndbout); -} - -static int readArguments(int argc, const char** argv) -{ - int i = 1; - int retValue = 0; - int printFlag = 0; - - tNoOfThreads = 1; // Set default Value - tNoOfTables = 1; // Default Value - - while (argc > 1) { - if (strcmp(argv[i], "-t") == 0) { - if (argv[i + 1] != NULL) { - tNoOfThreads = atoi(argv[i + 1]); - if ((tNoOfThreads < 1) || (tNoOfThreads > MAXTHREADS)) { - retValue = -1; - } // if - } // if - else { - retValue = -1; - } // else - } // if - else if (strcmp(argv[i], "-o") == 0) { - if (argv[i + 1] != NULL) { - tNoOfOperations = atoi(argv[i + 1]); - if (tNoOfOperations < 1) { - retValue = -1; - } // if - } // if - else { - retValue = -1; - } // else - } // else if - else if (strcmp(argv[i], "-a") == 0) { - if (argv[i + 1] != NULL) { - tNoOfAttributes = atoi(argv[i + 1]); - if ((tNoOfAttributes < 2) || (tNoOfAttributes > MAXATTR)) { - retValue = -1; - } // if - } // if - else { - retValue = -1; - } // else - } // else if - else if (strcmp(argv[i], "-c") == 0) { - if (argv[i + 1] != NULL) { - tNoOfTables = atoi(argv[i+1]); - if ((tNoOfTables < 1) || (tNoOfTables > MAXTABLES)) { - retValue = -1; - } // if - } // if - else { - retValue = -1; - } // else - } // else if - else if (strcmp(argv[i], "-l") == 0) { - if (argv[i + 1] != NULL) { - tNoOfLoops = atoi(argv[i+1]); - if ((tNoOfLoops < 0) || (tNoOfLoops > 100000)) { - retValue = -1; - } // if - } // if - else { - retValue = -1; - } // else - } // else if - else if (strcmp(argv[i], "-s") == 0) { - if (argv[i + 1] != NULL) { - tAttributeSize = atoi(argv[i+1]); - if ((tAttributeSize < 1) || (tAttributeSize > MAXATTRSIZE)) { - retValue = -1; - } // if - } // if - else { - retValue = -1; - } // else - } // else if - else if (strcmp(argv[i], "-no_table_create") == 0) { - theTableCreateFlag = 1; - argc++; - i--; - } // else if - else if (strcmp(argv[i], "-stdtables") == 0) { - theStdTableNameFlag = 1; - argc++; - i--; - } // else if - else if (strcmp(argv[i], "-sleep") == 0) { - if (argv[i + 1] != NULL) { - tSleepTime = atoi(argv[i+1]); - if ((tSleepTime < 1) || (tSleepTime > 3600)) { - retValue = -1; - } // if - } // if - else { - retValue = -1; - } // else - } // else if - else if (strcmp(argv[i], "-abort") == 0) { - // Test scan abort after a number of tuples - theScanAbortTestFlag = 1; - if (argv[i + 1] != NULL) { - tAbortAfter = atoi(argv[i + 1]); - } // if - else { - retValue = -1; - } // else - } // else if - else if (strcmp(argv[i], "-p") == 0) { - if (argv[i + 1] != NULL) { - tParallellism = atoi(argv[i + 1]); - if ((tParallellism < 1) || (tParallellism > 32)) { - retValue = -1; - } // if - } // if - else { - retValue = -1; - } // else - } // else if - else if (strcmp(argv[i], "-h") == 0) { - printFlag = 1; - argc++; - i--; - } // else if - else if (strcmp(argv[i], "-no_scan_update") == 0) { - theNoScanUpdateFlag = 1; - argc++; - i--; - } // else if - else if (strcmp(argv[i], "-no_scan_delete") == 0) { - theNoScanDeleteFlag = 1; - argc++; - i--; - } // else if - else { - retValue = -1; - } // else - - argc -= 2; - i = i + 2; - } - - if ((retValue != 0) || (printFlag == 1)) { - printUsage(); - } // if - - return(retValue); - -} // readArguments - -static void sleepBeforeStartingTest(int seconds) -{ - if (seconds > 0) { - ndbout << "Sleeping(" <getNdbError().message); - ndbout_c("Error code = %d", MyTransaction->getNdbError().code);} - tResult = 20; - } else if (retCode == 2) { - ndbout << "4115 should not happen in flexBench" << endl; - tResult = 20; - } else if (retCode == 3) { -// -------------------------------------------------------------------- -// We are not certain if the transaction was successful or not. -// We must reexecute but might very well find that the transaction -// actually was updated. Updates and Reads are no problem here. Inserts -// will not cause a problem if error code 630 arrives. Deletes will -// not cause a problem if 626 arrives. -// -------------------------------------------------------------------- - /* What can we do here? */ - ndbout_c("execute: %s", MyTransaction->getNdbError().message); - }//if(retCode == 3) - - } // if(check == -1) - - pNdb->closeTransaction(MyTransaction); - } // else - } // for opCount - - return(tResult); -} // insertRows - -static int readRows(Ndb* pNdb, - int* pkValue, - int* readValue) -{ - int tResult = 0; - int tableCount = 0; - int attrCount = 0; - int check = 0; - NdbConnection* MyTransaction = NULL; - NdbOperation* MyOperations[MAXTABLES] = {NULL}; - NdbRecAttr* tmp = NULL; - int Value = 0; - int Index = 0; - int opCount = 0; - - for (opCount = 0; opCount < tNoOfOperations; opCount++) { - MyTransaction = pNdb->startTransaction(); - if (MyTransaction == NULL) { - tResult = 1; - } // if - else { - for (tableCount = 0; tableCount < tNoOfTables; tableCount++) { - - MyOperations[tableCount] = - MyTransaction->getNdbOperation(tableName[tableCount]); - if (MyOperations[tableCount] == NULL) { - tResult = 2; - // Break for tableCount loop - break; - } // if - - check = MyOperations[tableCount]->readTuple(); - if (check == -1) { - tResult = 3; - break; - } // if - - check = MyOperations[tableCount]-> - equal((char*)attrName[0], (char*)&(pkValue[opCount])); - if (check == -1) { - tResult = 7; - break; - } // if - - for (int attrCount = 0; attrCount < tNoOfAttributes - 1; attrCount++) { - Index = tableCount * (tNoOfAttributes - 1) * tNoOfOperations * tAttributeSize + - attrCount * tNoOfOperations * tAttributeSize + opCount * tAttributeSize; - tmp = MyOperations[tableCount]-> - getValue((char*)attrName[attrCount + 1], (char*)&(readValue[Index])); - - if (tmp == NULL) { - tResult = 9; - break; - } // if - } // for attrCount - } // for tableCount - // Execute transaction reading one tuple in every table - check = MyTransaction->execute(Commit); - if (check == -1) { - ndbout << MyTransaction->getNdbError().message << endl; - - // Add complete error handling here - - int retCode = flexScanErrorData->handleErrorCommon(MyTransaction->getNdbError()); - if (retCode == 1) { - if (MyTransaction->getNdbError().code != 626 && MyTransaction->getNdbError().code != 630){ - ndbout_c("execute: %d, %s", opCount, MyTransaction ->getNdbError().message ); - ndbout_c("Error code = %d", MyTransaction->getNdbError().code );} - tResult = 20; - } else if (retCode == 2) { - ndbout << "4115 should not happen in flexBench" << endl; - tResult = 20; - } else if (retCode == 3) { -// -------------------------------------------------------------------- -// We are not certain if the transaction was successful or not. -// We must reexecute but might very well find that the transaction -// actually was updated. Updates and Reads are no problem here. Inserts -// will not cause a problem if error code 630 arrives. Deletes will -// not cause a problem if 626 arrives. -// -------------------------------------------------------------------- - /* What can we do here? */ - ndbout_c("execute: %s", MyTransaction ->getNdbError().message ); - }//if(retCode == 3) - - } // if - - pNdb->closeTransaction(MyTransaction); - } // else - } // for opCount - - return(tResult); -} // readRows - -static int scanReadRows(Ndb* pNdb, int* readValue) -{ - int tResult = 0; - int tableCount = 0; - int attrCount = 0; - int check = 0; - int countAbort = 0; // Counts loops until scan abort if requested - NdbConnection* MyTransaction = NULL; - NdbOperation* MyOperation = NULL; - NdbRecAttr* tmp = NULL; - - - for (tableCount = 0; tableCount < tNoOfTables; tableCount++) { - MyTransaction = pNdb->startTransaction(); - if (MyTransaction == NULL) { - tResult = 1; - break; - } // if - MyOperation = MyTransaction->getNdbOperation(tableName[tableCount]); - if (MyOperation == NULL) { - tResult = 2; - break; - } // if - - check = MyOperation->openScanRead(tParallellism); - if (check == -1) { - tResult = 10; - break; - } // if - - for (int attrCount = 0; attrCount < tNoOfAttributes-1; attrCount++) { - // Get all attributes - tmp = MyOperation-> - getValue((char*)attrName[attrCount+1], - (char*)&(readValue[tableCount*(tNoOfAttributes-1)*tNoOfOperations*tAttributeSize + - attrCount*tNoOfOperations*tAttributeSize])); - if (tmp == NULL) { - tResult = 9; - break; - } // if - } // for attrCount - - check = MyTransaction->executeScan(); - if (check == -1) { - tResult = 12; - break; - } // if - - check = MyTransaction->nextScanResult(); - while (check == 0) { - // Check if scan abort is requested - if (theScanAbortTestFlag == 1) { - if (countAbort == tAbortAfter) { - MyTransaction->stopScan(); - ndbout << "scanread aborted on request after " << countAbort*tParallellism << - " tuples" << endl; - break; // break while loop - } // if - countAbort++; - } // if - check = MyTransaction->nextScanResult(); - } // while - - pNdb->closeTransaction(MyTransaction); - } // for tableCount - - return(tResult); -} // scanReadRows - -static int scanUpdateRows(Ndb* pNdb, - int* readValue, - int* attrValue) -{ - int tResult = 0; - int tableCount = 0; - int attrCount = 0; - int check = 0; - int opCount = 0; - NdbConnection* MyTransaction = NULL; - NdbOperation* MyOperation = NULL; - NdbConnection* MyTakeOverTrans = NULL; - NdbOperation* MyTakeOverOp = NULL; - NdbRecAttr* tTmp = NULL; - - for (tableCount = 0; tableCount < tNoOfTables; tableCount++) { - MyTransaction = pNdb->startTransaction(); - if (MyTransaction == NULL) { - tResult = 1; - break; // break tableCount for loop - } // if - MyOperation = MyTransaction->getNdbOperation(tableName[tableCount]); - if (MyOperation == NULL) { - tResult = 2; - break; - } // if - - check = MyOperation->openScanExclusive(tParallellism); - if (check == -1) { - tResult = 11; - break; - } // if - - MyOperation->interpret_exit_ok(); - // Fetch all attributes - for (int attrCount = 0; attrCount < tNoOfAttributes-1; attrCount++) { - tTmp = MyOperation-> - getValue((char*)attrName[attrCount+1], - (char*)&(readValue[tableCount*(tNoOfAttributes-1)*tNoOfOperations*tAttributeSize + - attrCount*tNoOfOperations*tAttributeSize])); - if (tTmp == NULL) { - tResult = 9; - break; // break for loop - } // if - } // for - if (tResult != 0) { - break; // break while loop also - } // if - - check = MyTransaction->executeScan(); - if (check == -1) { - tResult = 12; - break; - } // if - check = MyTransaction->nextScanResult(); - opCount = 0; - while (check == 0) { - MyTakeOverTrans = pNdb->startTransaction(); - MyTakeOverOp = MyOperation->takeOverForUpdate(MyTakeOverTrans); - for (attrCount = 0; attrCount < tNoOfAttributes-1; attrCount++) { - check = MyTakeOverOp->setValue((char*)attrName[attrCount+1], - (char*)&(attrValue[tableCount*(tNoOfAttributes-1)*tNoOfOperations*tAttributeSize + - attrCount*tNoOfOperations*tAttributeSize + opCount*tAttributeSize])); - } // for - - check = MyTakeOverTrans->execute(Commit); - if (check == 0) { - check = MyTransaction->nextScanResult(); - opCount++; - } // if - else { - tResult = 95; - - /* MyTransaction, MyTakeOverTrans, Which one? */ - - // Any further error handling? - int retCode = flexScanErrorData->handleErrorCommon(MyTakeOverTrans->getNdbError()); - if (retCode == 1) { - if (MyTakeOverTrans->getNdbError().code != 626 && MyTakeOverTrans->getNdbError().code != 630){ - ndbout_c("execute: %s", MyTakeOverTrans->getNdbError().message); - ndbout_c("Error code = %d", MyTakeOverTrans->getNdbError().code);} - tResult = 20; - } else if (retCode == 2) { - ndbout << "4115 should not happen in flexBench" << endl; - tResult = 20; - } else if (retCode == 3) { - // -------------------------------------------------------------------- - // We are not certain if the transaction was successful or not. - // We must reexecute but might very well find that the transaction - // actually was updated. Updates and Reads are no problem here. Inserts - // will not cause a problem if error code 630 arrives. Deletes will - // not cause a problem if 626 arrives. - // -------------------------------------------------------------------- - /* What can we do here? */ - ndbout_c("execute: %s", MyTakeOverTrans->getNdbError().message); - }//if(retCode == 3) - - } // else - pNdb->closeTransaction(MyTakeOverTrans); - } // while - - pNdb->closeTransaction(MyTransaction); - } // for - - return(tResult); -} // scanUpdateRows - -static int scanDeleteRows(Ndb* pNdb, int* readValue) -{ - int tResult = 0; - int tableCount = 0; - int attrCount = 0; - int check = 0; - NdbRecAttr* tTmp = NULL; - NdbConnection* MyTransaction = NULL; - NdbOperation* MyOperation = NULL; - NdbConnection* MyTakeOverTrans = NULL; - NdbOperation* MyTakeOverOp = NULL; - - for (tableCount = 0; tableCount < tNoOfTables; tableCount++) { - MyTransaction = pNdb->startTransaction(); - if (MyTransaction == NULL) { - tResult = 1; - break; // break tableCount for loop - } // if - - MyOperation = MyTransaction->getNdbOperation(tableName[tableCount]); - if (MyOperation == NULL) { - tResult = 2; - break; - } // if - - check = MyOperation->openScanExclusive(tParallellism); - if (check == -1) { - tResult = 11; - break; - } // if - - MyOperation->interpret_exit_ok(); - for (int attrCount = 0; attrCount < tNoOfAttributes-1; attrCount++) { - tTmp = MyOperation-> - getValue((char*)attrName[attrCount+1], - (char*)&(readValue[tableCount*(tNoOfAttributes-1)*tNoOfOperations + - attrCount*tNoOfOperations])); - if (tTmp == NULL) { - tResult = 9; - break; - } // if - } // for - - check = MyTransaction->executeScan(); - if (check == -1) { - tResult = 12; - break; - } // if - check = MyTransaction->nextScanResult(); - while (check == 0) { - MyTakeOverTrans = pNdb->startTransaction(); - MyTakeOverOp = MyOperation->takeOverForDelete(MyTakeOverTrans); - check = MyTakeOverOp->deleteTuple(); - - check = MyTakeOverTrans->execute(Commit); - - //Error handling here - - int retCode =flexScanErrorData->handleErrorCommon(MyTakeOverTrans->getNdbError()); - if (retCode == 1) { - if (MyTakeOverTrans->getNdbError().code != 626 && MyTakeOverTrans->getNdbError().code != 630){ - ndbout_c("execute: %s", MyTakeOverTrans->getNdbError().message ); - ndbout_c("Error code = %d", MyTakeOverTrans->getNdbError().code );} - tResult = 20; - } else if (retCode == 2) { - ndbout << "4115 should not happen in flexBench" << endl; - tResult = 20; - } else if (retCode == 3) { -// -------------------------------------------------------------------- -// We are not certain if the transaction was successful or not. -// We must reexecute but might very well find that the transaction -// actually was updated. Updates and Reads are no problem here. Inserts -// will not cause a problem if error code 630 arrives. Deletes will -// not cause a problem if 626 arrives. -// -------------------------------------------------------------------- - /* What can we do here? */ - ndbout_c("execute: %s", MyTakeOverTrans->getNdbError().message ); - }//if(retCode == 3) End of error handling - - pNdb->closeTransaction(MyTakeOverTrans); - check = MyTransaction->nextScanResult(); - } // while - pNdb->closeTransaction(MyTransaction); - } // for tableCount - return(tResult); -} // scanDeleteRows - -static int deleteRows(Ndb* pNdb, - int* pkValue) -{ - int tResult = 0; - NdbConnection* MyTransaction = NULL; - int tableCount = 0; - int opCount = 0; - int check = 0; - NdbOperation* MyOperations[MAXTABLES] = {NULL}; - - for (opCount = 0; opCount < tNoOfOperations; opCount++) { - MyTransaction = pNdb->startTransaction(); - if (MyTransaction == NULL) { - tResult = 1; - } // if - else { - for (tableCount = 0; tableCount < tNoOfTables; tableCount++) { - - MyOperations[tableCount] = - MyTransaction->getNdbOperation(tableName[tableCount]); - if (MyOperations[tableCount] == NULL) { - tResult = 2; - // Break for tableCount loop - break; - } // if - - check = MyOperations[tableCount]->deleteTuple(); - if (check == -1) { - tResult = 3; - break; - } // if - - check = MyOperations[tableCount]-> - equal((char*)attrName[0], (char*)&(pkValue[opCount])); - if (check == -1) { - tResult = 7; - break; - } // if - - } // for tableCount - - // Execute transaction deleting one tuple in every table - check = MyTransaction->execute(Commit); - if (check == -1) { - ndbout << MyTransaction->getNdbError().message << endl; - // Add complete error handling here - - int retCode = flexScanErrorData->handleErrorCommon(MyTransaction->getNdbError()); - if (retCode == 1) { - if (MyTransaction->getNdbError().code != 626 && MyTransaction->getNdbError().code != 630){ - ndbout_c("execute: %d, %s", opCount, MyTransaction->getNdbError().message ); - ndbout_c("Error code = %d", MyTransaction->getNdbError().code );} - tResult = 20; - } else if (retCode == 2) { - ndbout << "4115 should not happen in flexBench" << endl; - tResult = 20; - } else if (retCode == 3) { -// -------------------------------------------------------------------- -// We are not certain if the transaction was successful or not. -// We must reexecute but might very well find that the transaction -// actually was updated. Updates and Reads are no problem here. Inserts -// will not cause a problem if error code 630 arrives. Deletes will -// not cause a problem if 626 arrives. -// -------------------------------------------------------------------- - /* What can we do here? */ - ndbout_c("execute: %s", MyTransaction->getNdbError().message ); - }//if(retCode == 3) - - } // if - - pNdb->closeTransaction(MyTransaction); - } // else - } // for opCount - - return(tResult); - -} // deleteRows - -//////////////////////////////////////// -// -// Name: verifyDeleteRows -// -// Purpose: Verifies that all tables are empty by reading every tuple -// No deletions made here -// -// Returns: 'Standard' error codes -// -///////////////////////////////////// -static int verifyDeleteRows(Ndb* pNdb, - int* pkValue, - int* readValue) -{ - int tResult = 0; - int tableCount = 0; - int attrCount = 0; - int check = 0; - NdbConnection* MyTransaction = NULL; - NdbOperation* MyOperations = NULL; - NdbRecAttr* tmp = NULL; - int Value = 0; - int Index = 0; - int opCount = 0; - - for (opCount = 0; opCount < tNoOfOperations; opCount++) { - for (tableCount = 0; tableCount < tNoOfTables; tableCount++) { - MyTransaction = pNdb->startTransaction(); - if (MyTransaction == NULL) { - tResult = 1; - } // if - else { - - MyOperations = - MyTransaction->getNdbOperation(tableName[tableCount]); - if (MyOperations == NULL) { - tResult = 2; - // Break for tableCount loop - break; - } // if - - check = MyOperations->readTuple(); - if (check == -1) { - tResult = 3; - break; - } // if - - check = MyOperations-> - equal((char*)attrName[0], (char*)&(pkValue[opCount])); - if (check == -1) { - tResult = 7; - break; - } // if - - for (int attrCount = 0; attrCount < tNoOfAttributes - 1; attrCount++) { - Index = tableCount * (tNoOfAttributes - 1) * tNoOfOperations * tAttributeSize + - attrCount * tNoOfOperations * tAttributeSize + opCount * tAttributeSize; - tmp = MyOperations-> - getValue((char*)attrName[attrCount + 1], (char*)&(readValue[Index])); - - if (tmp == NULL) { - tResult = 9; - break; - } // if - } // for attrCount - // Execute transaction reading one tuple in every table - check = MyTransaction->execute(Commit); - if ((check == -1) && (MyTransaction->getNdbError().code == 626)){ - // This is expected because everything should be deleted - } // if - else if (check == 0) { - // We have found a tuple that should have been deleted - ndbout << "tuple " << tableName[tableCount] << ":" << - opCount << " was never deleted" << endl; - tResult = 97; - } // else if - else { - // Unexpected error - ndbout << "Unexpected error during delete" << endl; - assert(false); - } // else - - pNdb->closeTransaction(MyTransaction); - - } // else - } // for tableCount - } // for opCount - - return(tResult); -} // verifyDeleteRows diff --git a/ndb/test/ndbapi/flexTT.cpp b/ndb/test/ndbapi/flexTT.cpp new file mode 100644 index 00000000000..c45cbd95762 --- /dev/null +++ b/ndb/test/ndbapi/flexTT.cpp @@ -0,0 +1,927 @@ +/* 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 */ + + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#define MAX_PARTS 4 +#define MAX_SEEK 16 +#define MAXSTRLEN 16 +#define MAXATTR 64 +#define MAXTABLES 64 +#define MAXTHREADS 128 +#define MAXPAR 1024 +#define MAXATTRSIZE 1000 +#define PKSIZE 1 + + +#ifdef NDB_WIN32 +inline long lrand48(void) { return rand(); }; +#endif + + +enum StartType { + stIdle, + stInsert, + stRead, + stUpdate, + stDelete, + stStop +} ; + +struct ThreadNdb +{ + int threadNo; + Ndb* threadNdb; + Uint32 threadBase; + Uint32 threadLoopCounter; + Uint32 threadNextStart; + Uint32 threadStop; + Uint32 threadLoopStop; + Uint32 threadIncrement; + Uint32 threadNoCompleted; + bool threadCompleted; + StartType threadStartType; +}; + +struct TransNdb +{ + char transRecord[128]; + Ndb* transNdb; + StartType transStartType; + Uint32 vpn_number; + Uint32 vpn_identity; + Uint32 transErrorCount; + NdbOperation* transOperation; + ThreadNdb* transThread; +}; + +extern "C" { static void* threadLoop(void*); } +static void setAttrNames(void); +static void setTableNames(void); +static int readArguments(int argc, const char** argv); +static int createTables(Ndb*); +static bool defineOperation(NdbConnection* aTransObject, TransNdb*, + Uint32 vpn_nb, Uint32 vpn_id); +static bool executeTransaction(TransNdb* transNdbRef); +static StartType random_choice(); +static void execute(StartType aType); +static bool executeThread(ThreadNdb*, TransNdb*); +static void executeCallback(int result, NdbConnection* NdbObject, + void* aObject); +static bool error_handler(const NdbError & err) ; +static Uint32 getKey(Uint32, Uint32) ; +static void input_error(); + +ErrorData * flexTTErrorData; + +static NdbThread* threadLife[MAXTHREADS]; +static int tNodeId; +static int ThreadReady[MAXTHREADS]; +static StartType ThreadStart[MAXTHREADS]; +static char tableName[1][MAXSTRLEN+1]; +static char attrName[5][MAXSTRLEN+1]; + +// Program Parameters +static bool tInsert = false; +static bool tDelete = false; +static bool tReadUpdate = true; +static int tUpdateFreq = 20; +static bool tLocal = false; +static int tLocalPart = 0; +static int tMinEvents = 0; +static int tSendForce = 0; +static int tNoOfLoops = 1; +static Uint32 tNoOfThreads = 1; +static Uint32 tNoOfParallelTrans = 32; +static Uint32 tNoOfTransactions = 500; +static Uint32 tLoadFactor = 80; +static bool tempTable = false; +static bool startTransGuess = true; + +//Program Flags +static int theSimpleFlag = 0; +static int theDirtyFlag = 0; +static int theWriteFlag = 0; +static int theTableCreateFlag = 1; + +#define START_REAL_TIME +#define STOP_REAL_TIME +#define START_TIMER { NdbTimer timer; timer.doStart(); +#define STOP_TIMER timer.doStop(); +#define PRINT_TIMER(text, trans, opertrans) timer.printTransactionStatistics(text, trans, opertrans); }; + +static void +resetThreads(){ + + for (int i = 0; i < tNoOfThreads ; i++) { + ThreadReady[i] = 0; + ThreadStart[i] = stIdle; + }//for +} + +static void +waitForThreads(void) +{ + int cont = 0; + do { + cont = 0; + NdbSleep_MilliSleep(20); + for (int i = 0; i < tNoOfThreads ; i++) { + if (ThreadReady[i] == 0) { + cont = 1; + }//if + }//for + } while (cont == 1); +} + +static void +tellThreads(StartType what) +{ + for (int i = 0; i < tNoOfThreads ; i++) + ThreadStart[i] = what; +} + +NDB_COMMAND(flexTT, "flexTT", "flexTT", "flexTT", 65535) +{ + ThreadNdb* pThreadData; + int returnValue = NDBT_OK; + + flexTTErrorData = new ErrorData; + flexTTErrorData->resetErrorCounters(); + + if (readArguments(argc, argv) != 0){ + input_error(); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + + pThreadData = new ThreadNdb[MAXTHREADS]; + + ndbout << endl << "FLEXTT - Starting normal mode" << endl; + ndbout << "Perform TimesTen benchmark" << endl; + ndbout << " " << tNoOfThreads << " number of concurrent threads " << endl; + ndbout << " " << tNoOfParallelTrans; + ndbout << " number of parallel transaction per thread " << endl; + ndbout << " " << tNoOfTransactions << " transaction(s) per round " << endl; + ndbout << " " << tNoOfLoops << " iterations " << endl; + ndbout << " " << "Update Frequency is " << tUpdateFreq << "%" << endl; + ndbout << " " << "Load Factor is " << tLoadFactor << "%" << endl; + if (tLocal == true) { + ndbout << " " << "We only use Local Part = "; + ndbout << tLocalPart << endl; + }//if + if (tempTable == true) { + ndbout << " Tables are without logging " << endl; + } else { + ndbout << " Tables are with logging " << endl; + }//if + if (startTransGuess == true) { + ndbout << " Transactions are executed with hint provided" << endl; + } else { + ndbout << " Transactions are executed with round robin scheme" << endl; + }//if + if (tSendForce == 0) { + ndbout << " No force send is used, adaptive algorithm used" << endl; + } else if (tSendForce == 1) { + ndbout << " Force send used" << endl; + } else { + ndbout << " No force send is used, adaptive algorithm disabled" << endl; + }//if + + ndbout << endl; + + /* print Setting */ + flexTTErrorData->printSettings(ndbout); + + NdbThread_SetConcurrencyLevel(2 + tNoOfThreads); + + setAttrNames(); + setTableNames(); + + Ndb * pNdb = new Ndb("TEST_DB"); + pNdb->init(); + tNodeId = pNdb->getNodeId(); + + ndbout << " NdbAPI node with id = " << pNdb->getNodeId() << endl; + ndbout << endl; + + ndbout << "Waiting for ndb to become ready..." <waitUntilReady(2000) != 0){ + ndbout << "NDB is not ready" << endl; + ndbout << "Benchmark failed!" << endl; + returnValue = NDBT_FAILED; + } + + if(returnValue == NDBT_OK){ + if (createTables(pNdb) != 0){ + returnValue = NDBT_FAILED; + } + } + + if(returnValue == NDBT_OK){ + /**************************************************************** + * Create NDB objects. * + ****************************************************************/ + resetThreads(); + for (int i = 0; i < tNoOfThreads ; i++) { + pThreadData[i].threadNo = i; + threadLife[i] = NdbThread_Create(threadLoop, + (void**)&pThreadData[i], + 32768, + "flexAsynchThread", + NDB_THREAD_PRIO_LOW); + }//for + ndbout << endl << "All NDB objects and table created" << endl << endl; + int noOfTransacts = tNoOfParallelTrans * tNoOfTransactions * + tNoOfThreads * tNoOfLoops; + /**************************************************************** + * Execute program. * + ****************************************************************/ + /**************************************************************** + * Perform inserts. * + ****************************************************************/ + + if (tInsert == true) { + tInsert = false; + tReadUpdate = false; + START_TIMER; + execute(stInsert); + STOP_TIMER; + PRINT_TIMER("insert", noOfTransacts, 1); + }//if + /**************************************************************** + * Perform read + updates. * + ****************************************************************/ + + if (tReadUpdate == true) { + START_TIMER; + execute(stRead); + STOP_TIMER; + PRINT_TIMER("update + read", noOfTransacts, 1); + }//if + /**************************************************************** + * Perform delete. * + ****************************************************************/ + + if (tDelete == true) { + tDelete = false; + START_TIMER; + execute(stDelete); + STOP_TIMER; + PRINT_TIMER("delete", noOfTransacts, 1); + }//if + ndbout << "--------------------------------------------------" << endl; + + execute(stStop); + void * tmp; + for(int i = 0; iprintErrorCounters(ndbout); + + return NDBT_ProgramExit(returnValue); +}//main() + + +static void execute(StartType aType) +{ + resetThreads(); + tellThreads(aType); + waitForThreads(); +}//execute() + +static void* +threadLoop(void* ThreadData) +{ + Ndb* localNdb; + ThreadNdb* tabThread = (ThreadNdb*)ThreadData; + int loc_threadNo = tabThread->threadNo; + + void * mem = malloc(sizeof(TransNdb)*tNoOfParallelTrans); + TransNdb* pTransData = (TransNdb*)mem; + + localNdb = new Ndb("TEST_DB"); + localNdb->init(1024); + localNdb->waitUntilReady(); + + if (tLocal == false) { + tabThread->threadIncrement = 1; + } else { + tabThread->threadIncrement = MAX_SEEK; + }//if + tabThread->threadBase = (loc_threadNo << 16) + tNodeId; + tabThread->threadNdb = localNdb; + tabThread->threadStop = tNoOfParallelTrans * tNoOfTransactions; + tabThread->threadStop *= tabThread->threadIncrement; + tabThread->threadLoopStop = tNoOfLoops; + Uint32 i, j; + for (i = 0; i < tNoOfParallelTrans; i++) { + pTransData[i].transNdb = localNdb; + pTransData[i].transThread = tabThread; + pTransData[i].transOperation = NULL; + pTransData[i].transStartType = stIdle; + pTransData[i].vpn_number = tabThread->threadBase; + pTransData[i].vpn_identity = 0; + pTransData[i].transErrorCount = 0; + for (j = 0; j < 128; j++) { + pTransData[i].transRecord[j] = 0x30; + }//for + }//for + + for (;;){ + while (ThreadStart[loc_threadNo] == stIdle) { + NdbSleep_MilliSleep(10); + }//while + + // Check if signal to exit is received + if (ThreadStart[loc_threadNo] == stStop) { + break; + }//if + + tabThread->threadStartType = ThreadStart[loc_threadNo]; + tabThread->threadLoopCounter = 0; + tabThread->threadCompleted = false; + tabThread->threadNoCompleted = 0; + tabThread->threadNextStart = 0; + + ThreadStart[loc_threadNo] = stIdle; + if(!executeThread(tabThread, pTransData)){ + break; + } + ThreadReady[loc_threadNo] = 1; + }//for + + free(mem); + delete localNdb; + ThreadReady[loc_threadNo] = 1; + + NdbThread_Exit(0); + return NULL; // Just to keep compiler happy +}//threadLoop() + +static +bool +executeThread(ThreadNdb* tabThread, TransNdb* atransDataArrayPtr) { + Uint32 i; + for (i = 0; i < tNoOfParallelTrans; i++) { + TransNdb* transNdbPtr = &atransDataArrayPtr[i]; + transNdbPtr->vpn_identity = i * tabThread->threadIncrement; + transNdbPtr->transStartType = tabThread->threadStartType; + if (executeTransaction(transNdbPtr) == false) { + return false; + }//if + }//for + tabThread->threadNextStart = tNoOfParallelTrans * tabThread->threadIncrement; + do { + tabThread->threadNdb->sendPollNdb(3000, tMinEvents, tSendForce); + } while (tabThread->threadCompleted == false); + return true; +}//executeThread() + +static +bool executeTransaction(TransNdb* transNdbRef) +{ + NdbConnection* MyTrans; + ThreadNdb* tabThread = transNdbRef->transThread; + Ndb* aNdbObject = transNdbRef->transNdb; + Uint32 threadBase = tabThread->threadBase; + Uint32 startKey = transNdbRef->vpn_identity; + if (tLocal == true) { + startKey = getKey(startKey, threadBase); + }//if + if (startTransGuess == true) { + Uint32 tKey[2]; + tKey[0] = startKey; + tKey[1] = threadBase; + MyTrans = aNdbObject->startTransaction((Uint32)0, //Priority + (const char*)&tKey[0], //Main PKey + (Uint32)8); //Key Length + } else { + MyTrans = aNdbObject->startTransaction(); + }//if + if (MyTrans == NULL) { + error_handler(aNdbObject->getNdbError()); + ndbout << endl << "Unable to recover! Quiting now" << endl ; + return false; + }//if + //------------------------------------------------------- + // Define the operation, but do not execute it yet. + //------------------------------------------------------- + if (!defineOperation(MyTrans, transNdbRef, startKey, threadBase)) + return false; + + return true; +}//executeTransaction() + + +static +Uint32 +getKey(Uint32 aBase, Uint32 aThreadBase) { + Uint32 Tfound = aBase; + Uint32 hash; + Uint64 Tkey64; + Uint32* tKey32 = (Uint32*)&Tkey64; + tKey32[0] = aThreadBase; + for (int i = aBase; i < (aBase + MAX_SEEK); i++) { + tKey32[1] = (Uint32)i; + hash = md5_hash((Uint64*)&Tkey64, (Uint32)2); + hash = (hash >> 6) & (MAX_PARTS - 1); + if (hash == tLocalPart) { + Tfound = i; + break; + }//if + }//for + return Tfound; +}//getKey() + +static void +executeCallback(int result, NdbConnection* NdbObject, void* aObject) +{ + TransNdb* transNdbRef = (TransNdb*)aObject; + ThreadNdb* tabThread = transNdbRef->transThread; + Ndb* tNdb = transNdbRef->transNdb; + Uint32 vpn_id = transNdbRef->vpn_identity; + Uint32 vpn_nb = tabThread->threadBase; + + if (result == -1) { +// Add complete error handling here + int retCode = flexTTErrorData->handleErrorCommon(NdbObject->getNdbError()); + if (retCode == 1) { + if (NdbObject->getNdbError().code != 626 && + NdbObject->getNdbError().code != 630) { + ndbout_c("execute: %s", NdbObject->getNdbError().message); + ndbout_c("Error code = %d", NdbObject->getNdbError().code); + } + } else if (retCode == 2) { + ndbout << "4115 should not happen in flexTT" << endl; + } else if (retCode == 3) { + /* What can we do here? */ + ndbout_c("execute: %s", NdbObject->getNdbError().message); + }//if(retCode == 3) + transNdbRef->transErrorCount++; + const NdbError & err = NdbObject->getNdbError(); + switch (err.classification) { + case NdbError::NoDataFound: + case NdbError::ConstraintViolation: + ndbout << "Error with vpn_id = " << vpn_id << " and vpn_nb = "; + ndbout << vpn_nb << endl; + ndbout << err << endl; + goto checkCompleted; + case NdbError::OverloadError: + NdbSleep_MilliSleep(10); + case NdbError::NodeRecoveryError: + case NdbError::UnknownResultError: + case NdbError::TimeoutExpired: + break; + default: + goto checkCompleted; + }//if + if ((transNdbRef->transErrorCount > 10) || + (tabThread->threadNoCompleted > 0)) { + goto checkCompleted; + }//if + } else { + if (tabThread->threadNoCompleted == 0) { + transNdbRef->transErrorCount = 0; + transNdbRef->vpn_identity = tabThread->threadNextStart; + if (tabThread->threadNextStart == tabThread->threadStop) { + tabThread->threadLoopCounter++; + transNdbRef->vpn_identity = 0; + tabThread->threadNextStart = 0; + if (tabThread->threadLoopCounter == tNoOfLoops) { + goto checkCompleted; + }//if + }//if + tabThread->threadNextStart += tabThread->threadIncrement; + } else { + goto checkCompleted; + }//if + }//if + tNdb->closeTransaction(NdbObject); + executeTransaction(transNdbRef); + return; + +checkCompleted: + tNdb->closeTransaction(NdbObject); + tabThread->threadNoCompleted++; + if (tabThread->threadNoCompleted == tNoOfParallelTrans) { + tabThread->threadCompleted = true; + }//if + return; +}//executeCallback() + +static +StartType +random_choice() +{ +//---------------------------------------------------- +// Generate a random key between 0 and tNoOfRecords - 1 +//---------------------------------------------------- + UintR random_number = lrand48() % 100; + if (random_number < tUpdateFreq) + return stUpdate; + else + return stRead; +}//random_choice() + +static bool +defineOperation(NdbConnection* localNdbConnection, TransNdb* transNdbRef, + unsigned int vpn_id, unsigned int vpn_nb) +{ + NdbOperation* localNdbOperation; + StartType TType = transNdbRef->transStartType; + + //------------------------------------------------------- + // Set-up the attribute values for this operation. + //------------------------------------------------------- + localNdbOperation = localNdbConnection->getNdbOperation(tableName[0]); + if (localNdbOperation == NULL) { + error_handler(localNdbConnection->getNdbError()); + return false; + }//if + switch (TType) { + case stInsert: // Insert case + if (theWriteFlag == 1 && theDirtyFlag == 1) { + localNdbOperation->dirtyWrite(); + } else if (theWriteFlag == 1) { + localNdbOperation->writeTuple(); + } else { + localNdbOperation->insertTuple(); + }//if + break; + case stRead: // Read Case + TType = random_choice(); + if (TType == stRead) { + if (theSimpleFlag == 1) { + localNdbOperation->simpleRead(); + } else if (theDirtyFlag == 1) { + localNdbOperation->dirtyRead(); + } else { + localNdbOperation->readTuple(); + }//if + } else { + if (theWriteFlag == 1 && theDirtyFlag == 1) { + localNdbOperation->dirtyWrite(); + } else if (theWriteFlag == 1) { + localNdbOperation->writeTuple(); + } else if (theDirtyFlag == 1) { + localNdbOperation->dirtyUpdate(); + } else { + localNdbOperation->updateTuple(); + }//if + }//if + break; + case stDelete: // Delete Case + localNdbOperation->deleteTuple(); + break; + default: + error_handler(localNdbOperation->getNdbError()); + }//switch + localNdbOperation->equal((Uint32)0,vpn_id); + localNdbOperation->equal((Uint32)1,vpn_nb); + char* attrValue = &transNdbRef->transRecord[0]; + switch (TType) { + case stInsert: // Insert case + localNdbOperation->setValue((Uint32)2, attrValue); + localNdbOperation->setValue((Uint32)3, attrValue); + localNdbOperation->setValue((Uint32)4, attrValue); + break; + case stUpdate: // Update Case + localNdbOperation->setValue((Uint32)3, attrValue); + break; + case stRead: // Read Case + localNdbOperation->getValue((Uint32)2, attrValue); + localNdbOperation->getValue((Uint32)3, attrValue); + localNdbOperation->getValue((Uint32)4, attrValue); + break; + case stDelete: // Delete Case + break; + default: + error_handler(localNdbOperation->getNdbError()); + }//switch + localNdbConnection->executeAsynchPrepare(Commit, &executeCallback, + (void*)transNdbRef); + return true; +}//defineOperation() + + +static void setAttrNames() +{ + snprintf(attrName[0], MAXSTRLEN, "VPN_ID"); + snprintf(attrName[1], MAXSTRLEN, "VPN_NB"); + snprintf(attrName[2], MAXSTRLEN, "DIRECTORY_NB"); + snprintf(attrName[3], MAXSTRLEN, "LAST_CALL_PARTY"); + snprintf(attrName[4], MAXSTRLEN, "DESCR"); +} + + +static void setTableNames() +{ + snprintf(tableName[0], MAXSTRLEN, "VPN_USERS"); +} + +static +int +createTables(Ndb* pMyNdb){ + + NdbSchemaCon *MySchemaTransaction; + NdbSchemaOp *MySchemaOp; + int check; + + if (theTableCreateFlag == 0) { + ndbout << "Creating Table: vpn_users " << "..." << endl; + MySchemaTransaction = pMyNdb->startSchemaTransaction(); + + if(MySchemaTransaction == NULL && + (!error_handler(MySchemaTransaction->getNdbError()))) + return -1; + + MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); + if(MySchemaOp == NULL && + (!error_handler(MySchemaTransaction->getNdbError()))) + return -1; + + check = MySchemaOp->createTable( tableName[0] + ,8 // Table Size + ,TupleKey // Key Type + ,40 // Nr of Pages + ,All + ,6 + ,(tLoadFactor - 5) + ,tLoadFactor + ,1 + ,!tempTable + ); + + if (check == -1 && + (!error_handler(MySchemaTransaction->getNdbError()))) + return -1; + + check = MySchemaOp->createAttribute( (char*)attrName[0], + TupleKey, + 32, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + + if (check == -1 && + (!error_handler(MySchemaTransaction->getNdbError()))) + return -1; + check = MySchemaOp->createAttribute( (char*)attrName[1], + TupleKey, + 32, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + + if (check == -1 && + (!error_handler(MySchemaTransaction->getNdbError()))) + return -1; + check = MySchemaOp->createAttribute( (char*)attrName[2], + NoKey, + 8, + 10, + UnSigned, + MMBased, + NotNullAttribute ); + if (check == -1 && + (!error_handler(MySchemaTransaction->getNdbError()))) + return -1; + + check = MySchemaOp->createAttribute( (char*)attrName[3], + NoKey, + 8, + 10, + UnSigned, + MMBased, + NotNullAttribute ); + if (check == -1 && + (!error_handler(MySchemaTransaction->getNdbError()))) + return -1; + + check = MySchemaOp->createAttribute( (char*)attrName[4], + NoKey, + 8, + 100, + UnSigned, + MMBased, + NotNullAttribute ); + if (check == -1 && + (!error_handler(MySchemaTransaction->getNdbError()))) + return -1; + + if (MySchemaTransaction->execute() == -1 && + (!error_handler(MySchemaTransaction->getNdbError()))) + return -1; + + pMyNdb->closeSchemaTransaction(MySchemaTransaction); + }//if + + return 0; +} + +bool error_handler(const NdbError& err){ + ndbout << err << endl ; + switch(err.classification){ + case NdbError::NodeRecoveryError: + case NdbError::SchemaError: + case NdbError::TimeoutExpired: + ndbout << endl << "Attempting to recover and continue now..." << endl ; + return true ; // return true to retry + } + return false; +} +#if 0 +bool error_handler(const char* error_string, int error_int) { + ndbout << error_string << endl ; + if ((4008 == error_int) || + (677 == error_int) || + (891 == error_int) || + (1221 == error_int) || + (721 == error_int) || + (266 == error_int)) { + ndbout << endl << "Attempting to recover and continue now..." << endl ; + return true ; // return true to retry + } + return false ; // return false to abort +} +#endif + +static +int +readArguments(int argc, const char** argv){ + + int i = 1; + while (argc > 1){ + if (strcmp(argv[i], "-t") == 0){ + tNoOfThreads = atoi(argv[i+1]); + if ((tNoOfThreads < 1) || (tNoOfThreads > MAXTHREADS)){ + ndbout_c("Invalid no of threads"); + return -1; + } + } else if (strcmp(argv[i], "-p") == 0){ + tNoOfParallelTrans = atoi(argv[i+1]); + if ((tNoOfParallelTrans < 1) || (tNoOfParallelTrans > MAXPAR)){ + ndbout_c("Invalid no of parallell transactions"); + return -1; + } + } else if (strcmp(argv[i], "-o") == 0) { + tNoOfTransactions = atoi(argv[i+1]); + if (tNoOfTransactions < 1){ + ndbout_c("Invalid no of transactions"); + return -1; + } + } else if (strcmp(argv[i], "-l") == 0){ + tNoOfLoops = atoi(argv[i+1]); + if (tNoOfLoops < 1) { + ndbout_c("Invalid no of loops"); + return -1; + } + } else if (strcmp(argv[i], "-e") == 0){ + tMinEvents = atoi(argv[i+1]); + if ((tMinEvents < 1) || (tMinEvents > tNoOfParallelTrans)) { + ndbout_c("Invalid no of loops"); + return -1; + } + } else if (strcmp(argv[i], "-local") == 0){ + tLocalPart = atoi(argv[i+1]); + tLocal = true; + startTransGuess = true; + if ((tLocalPart < 0) || (tLocalPart > MAX_PARTS)){ + ndbout_c("Invalid local part"); + return -1; + } + } else if (strcmp(argv[i], "-ufreq") == 0){ + tUpdateFreq = atoi(argv[i+1]); + if ((tUpdateFreq < 0) || (tUpdateFreq > 100)){ + ndbout_c("Invalid Update Frequency"); + return -1; + } + } else if (strcmp(argv[i], "-load_factor") == 0){ + tLoadFactor = atoi(argv[i+1]); + if ((tLoadFactor < 40) || (tLoadFactor >= 100)){ + ndbout_c("Invalid LoadFactor"); + return -1; + } + } else if (strcmp(argv[i], "-d") == 0){ + tDelete = true; + argc++; + i--; + } else if (strcmp(argv[i], "-i") == 0){ + tInsert = true; + argc++; + i--; + } else if (strcmp(argv[i], "-simple") == 0){ + theSimpleFlag = 1; + argc++; + i--; + } else if (strcmp(argv[i], "-adaptive") == 0){ + tSendForce = 0; + argc++; + i--; + } else if (strcmp(argv[i], "-force") == 0){ + tSendForce = 1; + argc++; + i--; + } else if (strcmp(argv[i], "-non_adaptive") == 0){ + tSendForce = 2; + argc++; + i--; + } else if (strcmp(argv[i], "-write") == 0){ + theWriteFlag = 1; + argc++; + i--; + } else if (strcmp(argv[i], "-dirty") == 0){ + theDirtyFlag = 1; + argc++; + i--; + } else if (strcmp(argv[i], "-table_create") == 0){ + theTableCreateFlag = 0; + tInsert = true; + argc++; + i--; + } else if (strcmp(argv[i], "-temp") == 0){ + tempTable = true; + argc++; + i--; + } else if (strcmp(argv[i], "-no_hint") == 0){ + startTransGuess = false; + argc++; + i--; + } else { + return -1; + } + + argc -= 2; + i = i + 2; + }//while + if (tLocal == true) { + if (startTransGuess == false) { + ndbout_c("Not valid to use no_hint with local"); + }//if + }//if + return 0; +} + +static +void +input_error(){ + + ndbout_c("FLEXTT"); + ndbout_c(" Perform benchmark of insert, update and delete transactions"); + ndbout_c(""); + ndbout_c("Arguments:"); + ndbout_c(" -t Number of threads to start, default 1"); + ndbout_c(" -p Number of parallel transactions per thread, default 32"); + ndbout_c(" -o Number of transactions per loop, default 500"); + ndbout_c(" -ufreq Number Update Frequency in percent (0 -> 100), rest is read"); + ndbout_c(" -load_factor Number Fill level in index in percent (40 -> 99)"); + ndbout_c(" -l Number of loops to run, default 1, 0=infinite"); + ndbout_c(" -i Start by inserting all records"); + ndbout_c(" -d End by deleting all records (only one loop)"); + ndbout_c(" -simple Use simple read to read from database"); + ndbout_c(" -dirty Use dirty read to read from database"); + ndbout_c(" -write Use writeTuple in insert and update"); + ndbout_c(" -n Use standard table names"); + ndbout_c(" -table_create Create tables in db"); + ndbout_c(" -temp Create table(s) without logging"); + ndbout_c(" -no_hint Don't give hint on where to execute transaction coordinator"); + ndbout_c(" -adaptive Use adaptive send algorithm (default)"); + ndbout_c(" -force Force send when communicating"); + ndbout_c(" -non_adaptive Send at a 10 millisecond interval"); + ndbout_c(" -local Number of part, only use keys in one part out of 16"); +} diff --git a/ndb/test/ndbapi/flexTT/Makefile b/ndb/test/ndbapi/flexTT/Makefile deleted file mode 100644 index a63bd803d95..00000000000 --- a/ndb/test/ndbapi/flexTT/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := flexTT - -# Source files of non-templated classes (.C files) -SOURCES = flexTT.cpp - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/test/ndbapi/flexTT/flexTT.cpp b/ndb/test/ndbapi/flexTT/flexTT.cpp deleted file mode 100644 index c45cbd95762..00000000000 --- a/ndb/test/ndbapi/flexTT/flexTT.cpp +++ /dev/null @@ -1,927 +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 */ - - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#define MAX_PARTS 4 -#define MAX_SEEK 16 -#define MAXSTRLEN 16 -#define MAXATTR 64 -#define MAXTABLES 64 -#define MAXTHREADS 128 -#define MAXPAR 1024 -#define MAXATTRSIZE 1000 -#define PKSIZE 1 - - -#ifdef NDB_WIN32 -inline long lrand48(void) { return rand(); }; -#endif - - -enum StartType { - stIdle, - stInsert, - stRead, - stUpdate, - stDelete, - stStop -} ; - -struct ThreadNdb -{ - int threadNo; - Ndb* threadNdb; - Uint32 threadBase; - Uint32 threadLoopCounter; - Uint32 threadNextStart; - Uint32 threadStop; - Uint32 threadLoopStop; - Uint32 threadIncrement; - Uint32 threadNoCompleted; - bool threadCompleted; - StartType threadStartType; -}; - -struct TransNdb -{ - char transRecord[128]; - Ndb* transNdb; - StartType transStartType; - Uint32 vpn_number; - Uint32 vpn_identity; - Uint32 transErrorCount; - NdbOperation* transOperation; - ThreadNdb* transThread; -}; - -extern "C" { static void* threadLoop(void*); } -static void setAttrNames(void); -static void setTableNames(void); -static int readArguments(int argc, const char** argv); -static int createTables(Ndb*); -static bool defineOperation(NdbConnection* aTransObject, TransNdb*, - Uint32 vpn_nb, Uint32 vpn_id); -static bool executeTransaction(TransNdb* transNdbRef); -static StartType random_choice(); -static void execute(StartType aType); -static bool executeThread(ThreadNdb*, TransNdb*); -static void executeCallback(int result, NdbConnection* NdbObject, - void* aObject); -static bool error_handler(const NdbError & err) ; -static Uint32 getKey(Uint32, Uint32) ; -static void input_error(); - -ErrorData * flexTTErrorData; - -static NdbThread* threadLife[MAXTHREADS]; -static int tNodeId; -static int ThreadReady[MAXTHREADS]; -static StartType ThreadStart[MAXTHREADS]; -static char tableName[1][MAXSTRLEN+1]; -static char attrName[5][MAXSTRLEN+1]; - -// Program Parameters -static bool tInsert = false; -static bool tDelete = false; -static bool tReadUpdate = true; -static int tUpdateFreq = 20; -static bool tLocal = false; -static int tLocalPart = 0; -static int tMinEvents = 0; -static int tSendForce = 0; -static int tNoOfLoops = 1; -static Uint32 tNoOfThreads = 1; -static Uint32 tNoOfParallelTrans = 32; -static Uint32 tNoOfTransactions = 500; -static Uint32 tLoadFactor = 80; -static bool tempTable = false; -static bool startTransGuess = true; - -//Program Flags -static int theSimpleFlag = 0; -static int theDirtyFlag = 0; -static int theWriteFlag = 0; -static int theTableCreateFlag = 1; - -#define START_REAL_TIME -#define STOP_REAL_TIME -#define START_TIMER { NdbTimer timer; timer.doStart(); -#define STOP_TIMER timer.doStop(); -#define PRINT_TIMER(text, trans, opertrans) timer.printTransactionStatistics(text, trans, opertrans); }; - -static void -resetThreads(){ - - for (int i = 0; i < tNoOfThreads ; i++) { - ThreadReady[i] = 0; - ThreadStart[i] = stIdle; - }//for -} - -static void -waitForThreads(void) -{ - int cont = 0; - do { - cont = 0; - NdbSleep_MilliSleep(20); - for (int i = 0; i < tNoOfThreads ; i++) { - if (ThreadReady[i] == 0) { - cont = 1; - }//if - }//for - } while (cont == 1); -} - -static void -tellThreads(StartType what) -{ - for (int i = 0; i < tNoOfThreads ; i++) - ThreadStart[i] = what; -} - -NDB_COMMAND(flexTT, "flexTT", "flexTT", "flexTT", 65535) -{ - ThreadNdb* pThreadData; - int returnValue = NDBT_OK; - - flexTTErrorData = new ErrorData; - flexTTErrorData->resetErrorCounters(); - - if (readArguments(argc, argv) != 0){ - input_error(); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - - pThreadData = new ThreadNdb[MAXTHREADS]; - - ndbout << endl << "FLEXTT - Starting normal mode" << endl; - ndbout << "Perform TimesTen benchmark" << endl; - ndbout << " " << tNoOfThreads << " number of concurrent threads " << endl; - ndbout << " " << tNoOfParallelTrans; - ndbout << " number of parallel transaction per thread " << endl; - ndbout << " " << tNoOfTransactions << " transaction(s) per round " << endl; - ndbout << " " << tNoOfLoops << " iterations " << endl; - ndbout << " " << "Update Frequency is " << tUpdateFreq << "%" << endl; - ndbout << " " << "Load Factor is " << tLoadFactor << "%" << endl; - if (tLocal == true) { - ndbout << " " << "We only use Local Part = "; - ndbout << tLocalPart << endl; - }//if - if (tempTable == true) { - ndbout << " Tables are without logging " << endl; - } else { - ndbout << " Tables are with logging " << endl; - }//if - if (startTransGuess == true) { - ndbout << " Transactions are executed with hint provided" << endl; - } else { - ndbout << " Transactions are executed with round robin scheme" << endl; - }//if - if (tSendForce == 0) { - ndbout << " No force send is used, adaptive algorithm used" << endl; - } else if (tSendForce == 1) { - ndbout << " Force send used" << endl; - } else { - ndbout << " No force send is used, adaptive algorithm disabled" << endl; - }//if - - ndbout << endl; - - /* print Setting */ - flexTTErrorData->printSettings(ndbout); - - NdbThread_SetConcurrencyLevel(2 + tNoOfThreads); - - setAttrNames(); - setTableNames(); - - Ndb * pNdb = new Ndb("TEST_DB"); - pNdb->init(); - tNodeId = pNdb->getNodeId(); - - ndbout << " NdbAPI node with id = " << pNdb->getNodeId() << endl; - ndbout << endl; - - ndbout << "Waiting for ndb to become ready..." <waitUntilReady(2000) != 0){ - ndbout << "NDB is not ready" << endl; - ndbout << "Benchmark failed!" << endl; - returnValue = NDBT_FAILED; - } - - if(returnValue == NDBT_OK){ - if (createTables(pNdb) != 0){ - returnValue = NDBT_FAILED; - } - } - - if(returnValue == NDBT_OK){ - /**************************************************************** - * Create NDB objects. * - ****************************************************************/ - resetThreads(); - for (int i = 0; i < tNoOfThreads ; i++) { - pThreadData[i].threadNo = i; - threadLife[i] = NdbThread_Create(threadLoop, - (void**)&pThreadData[i], - 32768, - "flexAsynchThread", - NDB_THREAD_PRIO_LOW); - }//for - ndbout << endl << "All NDB objects and table created" << endl << endl; - int noOfTransacts = tNoOfParallelTrans * tNoOfTransactions * - tNoOfThreads * tNoOfLoops; - /**************************************************************** - * Execute program. * - ****************************************************************/ - /**************************************************************** - * Perform inserts. * - ****************************************************************/ - - if (tInsert == true) { - tInsert = false; - tReadUpdate = false; - START_TIMER; - execute(stInsert); - STOP_TIMER; - PRINT_TIMER("insert", noOfTransacts, 1); - }//if - /**************************************************************** - * Perform read + updates. * - ****************************************************************/ - - if (tReadUpdate == true) { - START_TIMER; - execute(stRead); - STOP_TIMER; - PRINT_TIMER("update + read", noOfTransacts, 1); - }//if - /**************************************************************** - * Perform delete. * - ****************************************************************/ - - if (tDelete == true) { - tDelete = false; - START_TIMER; - execute(stDelete); - STOP_TIMER; - PRINT_TIMER("delete", noOfTransacts, 1); - }//if - ndbout << "--------------------------------------------------" << endl; - - execute(stStop); - void * tmp; - for(int i = 0; iprintErrorCounters(ndbout); - - return NDBT_ProgramExit(returnValue); -}//main() - - -static void execute(StartType aType) -{ - resetThreads(); - tellThreads(aType); - waitForThreads(); -}//execute() - -static void* -threadLoop(void* ThreadData) -{ - Ndb* localNdb; - ThreadNdb* tabThread = (ThreadNdb*)ThreadData; - int loc_threadNo = tabThread->threadNo; - - void * mem = malloc(sizeof(TransNdb)*tNoOfParallelTrans); - TransNdb* pTransData = (TransNdb*)mem; - - localNdb = new Ndb("TEST_DB"); - localNdb->init(1024); - localNdb->waitUntilReady(); - - if (tLocal == false) { - tabThread->threadIncrement = 1; - } else { - tabThread->threadIncrement = MAX_SEEK; - }//if - tabThread->threadBase = (loc_threadNo << 16) + tNodeId; - tabThread->threadNdb = localNdb; - tabThread->threadStop = tNoOfParallelTrans * tNoOfTransactions; - tabThread->threadStop *= tabThread->threadIncrement; - tabThread->threadLoopStop = tNoOfLoops; - Uint32 i, j; - for (i = 0; i < tNoOfParallelTrans; i++) { - pTransData[i].transNdb = localNdb; - pTransData[i].transThread = tabThread; - pTransData[i].transOperation = NULL; - pTransData[i].transStartType = stIdle; - pTransData[i].vpn_number = tabThread->threadBase; - pTransData[i].vpn_identity = 0; - pTransData[i].transErrorCount = 0; - for (j = 0; j < 128; j++) { - pTransData[i].transRecord[j] = 0x30; - }//for - }//for - - for (;;){ - while (ThreadStart[loc_threadNo] == stIdle) { - NdbSleep_MilliSleep(10); - }//while - - // Check if signal to exit is received - if (ThreadStart[loc_threadNo] == stStop) { - break; - }//if - - tabThread->threadStartType = ThreadStart[loc_threadNo]; - tabThread->threadLoopCounter = 0; - tabThread->threadCompleted = false; - tabThread->threadNoCompleted = 0; - tabThread->threadNextStart = 0; - - ThreadStart[loc_threadNo] = stIdle; - if(!executeThread(tabThread, pTransData)){ - break; - } - ThreadReady[loc_threadNo] = 1; - }//for - - free(mem); - delete localNdb; - ThreadReady[loc_threadNo] = 1; - - NdbThread_Exit(0); - return NULL; // Just to keep compiler happy -}//threadLoop() - -static -bool -executeThread(ThreadNdb* tabThread, TransNdb* atransDataArrayPtr) { - Uint32 i; - for (i = 0; i < tNoOfParallelTrans; i++) { - TransNdb* transNdbPtr = &atransDataArrayPtr[i]; - transNdbPtr->vpn_identity = i * tabThread->threadIncrement; - transNdbPtr->transStartType = tabThread->threadStartType; - if (executeTransaction(transNdbPtr) == false) { - return false; - }//if - }//for - tabThread->threadNextStart = tNoOfParallelTrans * tabThread->threadIncrement; - do { - tabThread->threadNdb->sendPollNdb(3000, tMinEvents, tSendForce); - } while (tabThread->threadCompleted == false); - return true; -}//executeThread() - -static -bool executeTransaction(TransNdb* transNdbRef) -{ - NdbConnection* MyTrans; - ThreadNdb* tabThread = transNdbRef->transThread; - Ndb* aNdbObject = transNdbRef->transNdb; - Uint32 threadBase = tabThread->threadBase; - Uint32 startKey = transNdbRef->vpn_identity; - if (tLocal == true) { - startKey = getKey(startKey, threadBase); - }//if - if (startTransGuess == true) { - Uint32 tKey[2]; - tKey[0] = startKey; - tKey[1] = threadBase; - MyTrans = aNdbObject->startTransaction((Uint32)0, //Priority - (const char*)&tKey[0], //Main PKey - (Uint32)8); //Key Length - } else { - MyTrans = aNdbObject->startTransaction(); - }//if - if (MyTrans == NULL) { - error_handler(aNdbObject->getNdbError()); - ndbout << endl << "Unable to recover! Quiting now" << endl ; - return false; - }//if - //------------------------------------------------------- - // Define the operation, but do not execute it yet. - //------------------------------------------------------- - if (!defineOperation(MyTrans, transNdbRef, startKey, threadBase)) - return false; - - return true; -}//executeTransaction() - - -static -Uint32 -getKey(Uint32 aBase, Uint32 aThreadBase) { - Uint32 Tfound = aBase; - Uint32 hash; - Uint64 Tkey64; - Uint32* tKey32 = (Uint32*)&Tkey64; - tKey32[0] = aThreadBase; - for (int i = aBase; i < (aBase + MAX_SEEK); i++) { - tKey32[1] = (Uint32)i; - hash = md5_hash((Uint64*)&Tkey64, (Uint32)2); - hash = (hash >> 6) & (MAX_PARTS - 1); - if (hash == tLocalPart) { - Tfound = i; - break; - }//if - }//for - return Tfound; -}//getKey() - -static void -executeCallback(int result, NdbConnection* NdbObject, void* aObject) -{ - TransNdb* transNdbRef = (TransNdb*)aObject; - ThreadNdb* tabThread = transNdbRef->transThread; - Ndb* tNdb = transNdbRef->transNdb; - Uint32 vpn_id = transNdbRef->vpn_identity; - Uint32 vpn_nb = tabThread->threadBase; - - if (result == -1) { -// Add complete error handling here - int retCode = flexTTErrorData->handleErrorCommon(NdbObject->getNdbError()); - if (retCode == 1) { - if (NdbObject->getNdbError().code != 626 && - NdbObject->getNdbError().code != 630) { - ndbout_c("execute: %s", NdbObject->getNdbError().message); - ndbout_c("Error code = %d", NdbObject->getNdbError().code); - } - } else if (retCode == 2) { - ndbout << "4115 should not happen in flexTT" << endl; - } else if (retCode == 3) { - /* What can we do here? */ - ndbout_c("execute: %s", NdbObject->getNdbError().message); - }//if(retCode == 3) - transNdbRef->transErrorCount++; - const NdbError & err = NdbObject->getNdbError(); - switch (err.classification) { - case NdbError::NoDataFound: - case NdbError::ConstraintViolation: - ndbout << "Error with vpn_id = " << vpn_id << " and vpn_nb = "; - ndbout << vpn_nb << endl; - ndbout << err << endl; - goto checkCompleted; - case NdbError::OverloadError: - NdbSleep_MilliSleep(10); - case NdbError::NodeRecoveryError: - case NdbError::UnknownResultError: - case NdbError::TimeoutExpired: - break; - default: - goto checkCompleted; - }//if - if ((transNdbRef->transErrorCount > 10) || - (tabThread->threadNoCompleted > 0)) { - goto checkCompleted; - }//if - } else { - if (tabThread->threadNoCompleted == 0) { - transNdbRef->transErrorCount = 0; - transNdbRef->vpn_identity = tabThread->threadNextStart; - if (tabThread->threadNextStart == tabThread->threadStop) { - tabThread->threadLoopCounter++; - transNdbRef->vpn_identity = 0; - tabThread->threadNextStart = 0; - if (tabThread->threadLoopCounter == tNoOfLoops) { - goto checkCompleted; - }//if - }//if - tabThread->threadNextStart += tabThread->threadIncrement; - } else { - goto checkCompleted; - }//if - }//if - tNdb->closeTransaction(NdbObject); - executeTransaction(transNdbRef); - return; - -checkCompleted: - tNdb->closeTransaction(NdbObject); - tabThread->threadNoCompleted++; - if (tabThread->threadNoCompleted == tNoOfParallelTrans) { - tabThread->threadCompleted = true; - }//if - return; -}//executeCallback() - -static -StartType -random_choice() -{ -//---------------------------------------------------- -// Generate a random key between 0 and tNoOfRecords - 1 -//---------------------------------------------------- - UintR random_number = lrand48() % 100; - if (random_number < tUpdateFreq) - return stUpdate; - else - return stRead; -}//random_choice() - -static bool -defineOperation(NdbConnection* localNdbConnection, TransNdb* transNdbRef, - unsigned int vpn_id, unsigned int vpn_nb) -{ - NdbOperation* localNdbOperation; - StartType TType = transNdbRef->transStartType; - - //------------------------------------------------------- - // Set-up the attribute values for this operation. - //------------------------------------------------------- - localNdbOperation = localNdbConnection->getNdbOperation(tableName[0]); - if (localNdbOperation == NULL) { - error_handler(localNdbConnection->getNdbError()); - return false; - }//if - switch (TType) { - case stInsert: // Insert case - if (theWriteFlag == 1 && theDirtyFlag == 1) { - localNdbOperation->dirtyWrite(); - } else if (theWriteFlag == 1) { - localNdbOperation->writeTuple(); - } else { - localNdbOperation->insertTuple(); - }//if - break; - case stRead: // Read Case - TType = random_choice(); - if (TType == stRead) { - if (theSimpleFlag == 1) { - localNdbOperation->simpleRead(); - } else if (theDirtyFlag == 1) { - localNdbOperation->dirtyRead(); - } else { - localNdbOperation->readTuple(); - }//if - } else { - if (theWriteFlag == 1 && theDirtyFlag == 1) { - localNdbOperation->dirtyWrite(); - } else if (theWriteFlag == 1) { - localNdbOperation->writeTuple(); - } else if (theDirtyFlag == 1) { - localNdbOperation->dirtyUpdate(); - } else { - localNdbOperation->updateTuple(); - }//if - }//if - break; - case stDelete: // Delete Case - localNdbOperation->deleteTuple(); - break; - default: - error_handler(localNdbOperation->getNdbError()); - }//switch - localNdbOperation->equal((Uint32)0,vpn_id); - localNdbOperation->equal((Uint32)1,vpn_nb); - char* attrValue = &transNdbRef->transRecord[0]; - switch (TType) { - case stInsert: // Insert case - localNdbOperation->setValue((Uint32)2, attrValue); - localNdbOperation->setValue((Uint32)3, attrValue); - localNdbOperation->setValue((Uint32)4, attrValue); - break; - case stUpdate: // Update Case - localNdbOperation->setValue((Uint32)3, attrValue); - break; - case stRead: // Read Case - localNdbOperation->getValue((Uint32)2, attrValue); - localNdbOperation->getValue((Uint32)3, attrValue); - localNdbOperation->getValue((Uint32)4, attrValue); - break; - case stDelete: // Delete Case - break; - default: - error_handler(localNdbOperation->getNdbError()); - }//switch - localNdbConnection->executeAsynchPrepare(Commit, &executeCallback, - (void*)transNdbRef); - return true; -}//defineOperation() - - -static void setAttrNames() -{ - snprintf(attrName[0], MAXSTRLEN, "VPN_ID"); - snprintf(attrName[1], MAXSTRLEN, "VPN_NB"); - snprintf(attrName[2], MAXSTRLEN, "DIRECTORY_NB"); - snprintf(attrName[3], MAXSTRLEN, "LAST_CALL_PARTY"); - snprintf(attrName[4], MAXSTRLEN, "DESCR"); -} - - -static void setTableNames() -{ - snprintf(tableName[0], MAXSTRLEN, "VPN_USERS"); -} - -static -int -createTables(Ndb* pMyNdb){ - - NdbSchemaCon *MySchemaTransaction; - NdbSchemaOp *MySchemaOp; - int check; - - if (theTableCreateFlag == 0) { - ndbout << "Creating Table: vpn_users " << "..." << endl; - MySchemaTransaction = pMyNdb->startSchemaTransaction(); - - if(MySchemaTransaction == NULL && - (!error_handler(MySchemaTransaction->getNdbError()))) - return -1; - - MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); - if(MySchemaOp == NULL && - (!error_handler(MySchemaTransaction->getNdbError()))) - return -1; - - check = MySchemaOp->createTable( tableName[0] - ,8 // Table Size - ,TupleKey // Key Type - ,40 // Nr of Pages - ,All - ,6 - ,(tLoadFactor - 5) - ,tLoadFactor - ,1 - ,!tempTable - ); - - if (check == -1 && - (!error_handler(MySchemaTransaction->getNdbError()))) - return -1; - - check = MySchemaOp->createAttribute( (char*)attrName[0], - TupleKey, - 32, - 1, - UnSigned, - MMBased, - NotNullAttribute ); - - if (check == -1 && - (!error_handler(MySchemaTransaction->getNdbError()))) - return -1; - check = MySchemaOp->createAttribute( (char*)attrName[1], - TupleKey, - 32, - 1, - UnSigned, - MMBased, - NotNullAttribute ); - - if (check == -1 && - (!error_handler(MySchemaTransaction->getNdbError()))) - return -1; - check = MySchemaOp->createAttribute( (char*)attrName[2], - NoKey, - 8, - 10, - UnSigned, - MMBased, - NotNullAttribute ); - if (check == -1 && - (!error_handler(MySchemaTransaction->getNdbError()))) - return -1; - - check = MySchemaOp->createAttribute( (char*)attrName[3], - NoKey, - 8, - 10, - UnSigned, - MMBased, - NotNullAttribute ); - if (check == -1 && - (!error_handler(MySchemaTransaction->getNdbError()))) - return -1; - - check = MySchemaOp->createAttribute( (char*)attrName[4], - NoKey, - 8, - 100, - UnSigned, - MMBased, - NotNullAttribute ); - if (check == -1 && - (!error_handler(MySchemaTransaction->getNdbError()))) - return -1; - - if (MySchemaTransaction->execute() == -1 && - (!error_handler(MySchemaTransaction->getNdbError()))) - return -1; - - pMyNdb->closeSchemaTransaction(MySchemaTransaction); - }//if - - return 0; -} - -bool error_handler(const NdbError& err){ - ndbout << err << endl ; - switch(err.classification){ - case NdbError::NodeRecoveryError: - case NdbError::SchemaError: - case NdbError::TimeoutExpired: - ndbout << endl << "Attempting to recover and continue now..." << endl ; - return true ; // return true to retry - } - return false; -} -#if 0 -bool error_handler(const char* error_string, int error_int) { - ndbout << error_string << endl ; - if ((4008 == error_int) || - (677 == error_int) || - (891 == error_int) || - (1221 == error_int) || - (721 == error_int) || - (266 == error_int)) { - ndbout << endl << "Attempting to recover and continue now..." << endl ; - return true ; // return true to retry - } - return false ; // return false to abort -} -#endif - -static -int -readArguments(int argc, const char** argv){ - - int i = 1; - while (argc > 1){ - if (strcmp(argv[i], "-t") == 0){ - tNoOfThreads = atoi(argv[i+1]); - if ((tNoOfThreads < 1) || (tNoOfThreads > MAXTHREADS)){ - ndbout_c("Invalid no of threads"); - return -1; - } - } else if (strcmp(argv[i], "-p") == 0){ - tNoOfParallelTrans = atoi(argv[i+1]); - if ((tNoOfParallelTrans < 1) || (tNoOfParallelTrans > MAXPAR)){ - ndbout_c("Invalid no of parallell transactions"); - return -1; - } - } else if (strcmp(argv[i], "-o") == 0) { - tNoOfTransactions = atoi(argv[i+1]); - if (tNoOfTransactions < 1){ - ndbout_c("Invalid no of transactions"); - return -1; - } - } else if (strcmp(argv[i], "-l") == 0){ - tNoOfLoops = atoi(argv[i+1]); - if (tNoOfLoops < 1) { - ndbout_c("Invalid no of loops"); - return -1; - } - } else if (strcmp(argv[i], "-e") == 0){ - tMinEvents = atoi(argv[i+1]); - if ((tMinEvents < 1) || (tMinEvents > tNoOfParallelTrans)) { - ndbout_c("Invalid no of loops"); - return -1; - } - } else if (strcmp(argv[i], "-local") == 0){ - tLocalPart = atoi(argv[i+1]); - tLocal = true; - startTransGuess = true; - if ((tLocalPart < 0) || (tLocalPart > MAX_PARTS)){ - ndbout_c("Invalid local part"); - return -1; - } - } else if (strcmp(argv[i], "-ufreq") == 0){ - tUpdateFreq = atoi(argv[i+1]); - if ((tUpdateFreq < 0) || (tUpdateFreq > 100)){ - ndbout_c("Invalid Update Frequency"); - return -1; - } - } else if (strcmp(argv[i], "-load_factor") == 0){ - tLoadFactor = atoi(argv[i+1]); - if ((tLoadFactor < 40) || (tLoadFactor >= 100)){ - ndbout_c("Invalid LoadFactor"); - return -1; - } - } else if (strcmp(argv[i], "-d") == 0){ - tDelete = true; - argc++; - i--; - } else if (strcmp(argv[i], "-i") == 0){ - tInsert = true; - argc++; - i--; - } else if (strcmp(argv[i], "-simple") == 0){ - theSimpleFlag = 1; - argc++; - i--; - } else if (strcmp(argv[i], "-adaptive") == 0){ - tSendForce = 0; - argc++; - i--; - } else if (strcmp(argv[i], "-force") == 0){ - tSendForce = 1; - argc++; - i--; - } else if (strcmp(argv[i], "-non_adaptive") == 0){ - tSendForce = 2; - argc++; - i--; - } else if (strcmp(argv[i], "-write") == 0){ - theWriteFlag = 1; - argc++; - i--; - } else if (strcmp(argv[i], "-dirty") == 0){ - theDirtyFlag = 1; - argc++; - i--; - } else if (strcmp(argv[i], "-table_create") == 0){ - theTableCreateFlag = 0; - tInsert = true; - argc++; - i--; - } else if (strcmp(argv[i], "-temp") == 0){ - tempTable = true; - argc++; - i--; - } else if (strcmp(argv[i], "-no_hint") == 0){ - startTransGuess = false; - argc++; - i--; - } else { - return -1; - } - - argc -= 2; - i = i + 2; - }//while - if (tLocal == true) { - if (startTransGuess == false) { - ndbout_c("Not valid to use no_hint with local"); - }//if - }//if - return 0; -} - -static -void -input_error(){ - - ndbout_c("FLEXTT"); - ndbout_c(" Perform benchmark of insert, update and delete transactions"); - ndbout_c(""); - ndbout_c("Arguments:"); - ndbout_c(" -t Number of threads to start, default 1"); - ndbout_c(" -p Number of parallel transactions per thread, default 32"); - ndbout_c(" -o Number of transactions per loop, default 500"); - ndbout_c(" -ufreq Number Update Frequency in percent (0 -> 100), rest is read"); - ndbout_c(" -load_factor Number Fill level in index in percent (40 -> 99)"); - ndbout_c(" -l Number of loops to run, default 1, 0=infinite"); - ndbout_c(" -i Start by inserting all records"); - ndbout_c(" -d End by deleting all records (only one loop)"); - ndbout_c(" -simple Use simple read to read from database"); - ndbout_c(" -dirty Use dirty read to read from database"); - ndbout_c(" -write Use writeTuple in insert and update"); - ndbout_c(" -n Use standard table names"); - ndbout_c(" -table_create Create tables in db"); - ndbout_c(" -temp Create table(s) without logging"); - ndbout_c(" -no_hint Don't give hint on where to execute transaction coordinator"); - ndbout_c(" -adaptive Use adaptive send algorithm (default)"); - ndbout_c(" -force Force send when communicating"); - ndbout_c(" -non_adaptive Send at a 10 millisecond interval"); - ndbout_c(" -local Number of part, only use keys in one part out of 16"); -} diff --git a/ndb/test/ndbapi/flexTimedAsynch.cpp b/ndb/test/ndbapi/flexTimedAsynch.cpp new file mode 100644 index 00000000000..761be53fdd3 --- /dev/null +++ b/ndb/test/ndbapi/flexTimedAsynch.cpp @@ -0,0 +1,852 @@ +/* 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 */ + +/* *************************************************** + FLEXTIMEDASYNCH + Perform benchmark of insert, update and delete transactions. + + Arguments: + -t Number of threads to start, i.e., number of parallel loops, default 1 + -p Number of transactions in a batch, default 32 + -o Number of batches per loop, default 200 + -i Time between batch starts, default 0 + -l Number of loops to run, default 1, 0=infinite + -a Number of attributes, default 25 + -c Number of operations per transaction + -s Size of each attribute in 32 bit word, default 1 (Primary Key is always of size 1, + independent of this value) + -simple Use simple read to read from database + -dirty Use dirty read to read from database + -write Use writeTuple in insert and update + -n Use standard table names + -no_table_create Don't create tables in db + -temp Use temporary tables, no writing to disk. + + Returns: + 0 - Test passed + -1 - Test failed + 1 - Invalid arguments + + * *************************************************** */ + +#include "NdbApi.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define MAXSTRLEN 16 +#define MAXATTR 64 +#define MAXTABLES 64 +#define MAXTHREADS 256 +#define MAXATTRSIZE 1000 +#define PKSIZE 1 + +enum StartType { stIdle, + stInsert, + stRead, + stUpdate, + stDelete, + stStop } ; + +ErrorData * flexTimedAsynchErrorData; + +struct ThreadNdb +{ + int NoOfOps; + int ThreadNo; + unsigned int threadBase; + unsigned int transactionCompleted; +}; + +extern "C" void* threadLoop(void*); +void setAttrNames(void); +void setTableNames(void); +void readArguments(int argc, const char** argv); +void createAttributeSpace(); +void createTables(Ndb*); +void defineOperation(NdbConnection* aTransObject, StartType aType, unsigned int key, int *); +void execute(StartType aType); +void executeThread(StartType aType, Ndb* aNdbObject, ThreadNdb* threadInfo); +void executeCallback(int result, NdbConnection* NdbObject, void* aObject); + +/* epaulsa > *************************************************************/ +bool error_handler(const NdbError &) ; //replaces 'goto' things +static int failed = 0 ; // lame global variable that keeps track of failed transactions + // incremented in executeCallback() and reset in main() +/************************************************************* < epaulsa */ + +static NdbThread* threadLife[MAXTHREADS]; +static int tNodeId; +static int ThreadReady[MAXTHREADS]; +static StartType ThreadStart[MAXTHREADS]; +static char tableName[MAXTABLES][MAXSTRLEN+1]; +static char attrName[MAXATTR][MAXSTRLEN+1]; +static int *getAttrValueTable; + +// Program Parameters +static int tNoOfLoops = 1; +static int tAttributeSize = 1; +static unsigned int tNoOfThreads = 1; +static unsigned int tNoOfTransInBatch = 32; +static unsigned int tNoOfAttributes = 25; +static unsigned int tNoOfBatchesInLoop = 200; +static unsigned int tNoOfOpsPerTrans = 1; +static unsigned int tTimeBetweenBatches = 0; + +//Program Flags +static int theTestFlag = 0; +static int theTempFlag = 1; +static int theSimpleFlag = 0; +static int theDirtyFlag = 0; +static int theWriteFlag = 0; +static int theStdTableNameFlag = 0; +static int theTableCreateFlag = 0; + +#define START_REAL_TIME NdbTimer timer; timer.doStart(); +#define STOP_REAL_TIME timer.doStop(); + +#define START_TIMER { NdbTimer timer; timer.doStart(); +#define STOP_TIMER timer.doStop(); +#define PRINT_TIMER(text, trans, opertrans) timer.printTransactionStatistics(text, trans, opertrans); }; + +void +resetThreads(){ + + for (int i = 0; i < tNoOfThreads ; i++) { + ThreadReady[i] = 0; + ThreadStart[i] = stIdle; + } +} + +void +waitForThreads(void) +{ + int cont; + do { + cont = 0; + NdbSleep_MilliSleep(20); + for (int i = 0; i < tNoOfThreads ; i++) { + if (ThreadReady[i] == 0) { + cont = 1; + } + } + } while (cont == 1); +} + +void +tellThreads(StartType what) +{ + for (int i = 0; i < tNoOfThreads ; i++) + ThreadStart[i] = what; +} + +void createAttributeSpace(){ + getAttrValueTable = new int[tAttributeSize* + tNoOfThreads * + tNoOfAttributes ]; + +} + +void deleteAttributeSpace(){ + delete [] getAttrValueTable; +} + +NDB_COMMAND(flexTimedAsynch, "flexTimedAsynch", "flexTimedAsynch [-tpoilcas]", "flexTimedAsynch", 65535) +{ + ThreadNdb tabThread[MAXTHREADS]; + int tLoops=0; + int returnValue; + //NdbOut flexTimedAsynchNdbOut; + + flexTimedAsynchErrorData = new ErrorData; + flexTimedAsynchErrorData->resetErrorCounters(); + + Ndb* pNdb; + pNdb = new Ndb( "TEST_DB" ); + pNdb->init(); + + readArguments(argc, argv); + + createAttributeSpace(); + + ndbout << endl << "FLEXTIMEDASYNCH - Starting normal mode" << endl; + ndbout << "Perform benchmark of insert, update and delete transactions" << endl << endl; + + if(theTempFlag == 0) + ndbout << " " << "Using temporary tables. " << endl; + + // -t, tNoOfThreads + ndbout << " " << tNoOfThreads << " number of concurrent threads " << endl; + // -c, tNoOfOpsPerTrans + ndbout << " " << tNoOfOpsPerTrans << " operations per transaction " << endl; + // -p, tNoOfTransInBatch + ndbout << " " << tNoOfTransInBatch << " number of transactions in a batch per thread " << endl; + // -o, tNoOfBatchesInLoop + ndbout << " " << tNoOfBatchesInLoop << " number of batches per loop " << endl; + // -i, tTimeBetweenBatches + ndbout << " " << tTimeBetweenBatches << " milli seconds at least between batch starts " << endl; + // -l, tNoOfLoops + ndbout << " " << tNoOfLoops << " loops " << endl; + // -a, tNoOfAttributes + ndbout << " " << tNoOfAttributes << " attributes per table " << endl; + // -s, tAttributeSize + ndbout << " " << tAttributeSize << " is the number of 32 bit words per attribute " << endl << endl; + + NdbThread_SetConcurrencyLevel(2 + tNoOfThreads); + + /* print Setting */ + flexTimedAsynchErrorData->printSettings(ndbout); + + setAttrNames(); + setTableNames(); + + ndbout << "Waiting for ndb to become ready..." <waitUntilReady() == 0) { + tNodeId = pNdb->getNodeId(); + ndbout << " NdbAPI node with id = " << tNodeId << endl; + createTables(pNdb); + + /**************************************************************** + * Create NDB objects. * + ****************************************************************/ + resetThreads(); + for (int i = 0; i < tNoOfThreads ; i++) { + tabThread[i].ThreadNo = i; + + threadLife[i] = NdbThread_Create(threadLoop, + (void**)&tabThread[i], + 32768, + "flexTimedAsynchThread", + NDB_THREAD_PRIO_LOW); + } + ndbout << endl << "All NDB objects and table created" << endl << endl; + int noOfTransacts = tNoOfTransInBatch*tNoOfBatchesInLoop*tNoOfThreads; + + /**************************************************************** + * Execute program. * + ****************************************************************/ + + + for(;;) { + + int loopCount = tLoops + 1 ; + ndbout << endl << "Loop # " << loopCount << endl << endl ; + + /**************************************************************** + * Perform inserts. * + ****************************************************************/ + + failed = 0 ; + + START_TIMER; + execute(stInsert); + STOP_TIMER; + PRINT_TIMER("insert", noOfTransacts, tNoOfOpsPerTrans); + + if (0 < failed) { + ndbout << failed << " of the transactions returned errors!, moving on now..."<printErrorCounters(ndbout); + + return NDBT_ProgramExit(returnValue); +}//main() + +//////////////////////////////////////// + +void execute(StartType aType) +{ + resetThreads(); + tellThreads(aType); + waitForThreads(); +} + +void* +threadLoop(void* ThreadData) +{ + // Do work until signaled to stop. + + Ndb* localNdb; + StartType tType; + ThreadNdb* threadInfo = (ThreadNdb*)ThreadData; + int threadNo = threadInfo->ThreadNo; + localNdb = new Ndb("TEST_DB"); + localNdb->init(512); + localNdb->waitUntilReady(); + threadInfo->threadBase = (threadNo * 2000000) + (tNodeId * 260000000); + + for (;;) { + while (ThreadStart[threadNo] == stIdle) { + NdbSleep_MilliSleep(10); + } + + // Check if signal to exit is received + if (ThreadStart[threadNo] == stStop) { + break; + } + + tType = ThreadStart[threadNo]; + ThreadStart[threadNo] = stIdle; + executeThread(tType, localNdb, threadInfo); + ThreadReady[threadNo] = 1; + } + + delete localNdb; + ThreadReady[threadNo] = 1; + NdbThread_Exit(0); + + return NULL; +} + +void executeThread(StartType aType, Ndb* aNdbObject, ThreadNdb* threadInfo) +{ + // Do all batch job in loop with start specified delay + int i, j, k; + NdbConnection* tConArray[1024]; + unsigned int tBase; + unsigned int tBase2; + int threadId = threadInfo->ThreadNo; + int *getValueRowAddress = NULL; + + NdbTimer timer; + timer.doStart(); + + for (i = 0; i < tNoOfBatchesInLoop; i++) { + //tBase = threadBase + (i * tNoOfTransInBatch * tNoOfOpsPerTrans); + tBase = threadInfo->threadBase + (i * tNoOfTransInBatch * tNoOfOpsPerTrans); + //tCompleted = 0; + threadInfo->transactionCompleted = 0; + + for (j = 0; j < tNoOfTransInBatch; j++) { + tBase2 = tBase + (j * tNoOfOpsPerTrans); + tConArray[j] = aNdbObject->startTransaction(); + if ( tConArray[j] == NULL && !error_handler(aNdbObject->getNdbError())) { + ndbout << endl << "Unable to recover! Quiting now" << endl ; + exit (-1) ; + return ; + } + + for (k = 0; k < tNoOfOpsPerTrans; k++) { + //------------------------------------------------------- + // Define the operation, but do not execute it yet. + //------------------------------------------------------- + if(aType == stRead){ + getValueRowAddress = getAttrValueTable + + threadId * tNoOfAttributes * tAttributeSize; + } + defineOperation(tConArray[j], aType, (tBase2 + k), getValueRowAddress); + } + + tConArray[j]->executeAsynchPrepare(Commit, &executeCallback, threadInfo); + } + + //------------------------------------------------------- + // Now we have defined a set of transactions (= batch), it is now time + // to execute all of them. + //------------------------------------------------------- + aNdbObject->sendPollNdb(3000, 0, 0); + + //while (tCompleted < tNoOfTransInBatch) { + while (threadInfo->transactionCompleted < tNoOfTransInBatch) { + aNdbObject->pollNdb(3000, 0); + ndbout << "threadInfo->transactionCompleted = " << + threadInfo->transactionCompleted << endl; + } + + for (j = 0 ; j < tNoOfTransInBatch ; j++) { + aNdbObject->closeTransaction(tConArray[j]); + } + + // Control the elapsed time since the last batch start. + // Wait at least tTimeBetweenBatches milli seconds. + timer.doStop(); + while(timer.elapsedTime() < tTimeBetweenBatches){ + NdbSleep_MilliSleep(1); + timer.doStop(); + } + // Ready to start new batch + timer.doStart(); + } + return; +} + +void +executeCallback(int result, NdbConnection* NdbObject, void* aObject) +{ + //tCompleted++; + ThreadNdb *threadInfo = (ThreadNdb *)aObject; + threadInfo->transactionCompleted++; + + if (result == -1) { + + // Add complete error handling here + + int retCode = flexTimedAsynchErrorData->handleErrorCommon(NdbObject->getNdbError()); + if (retCode == 1) { + if (NdbObject->getNdbError().code != 626 && NdbObject->getNdbError().code != 630){ + ndbout_c("execute: %s", NdbObject->getNdbError().message); + ndbout_c("Error code = %d", NdbObject->getNdbError().code);} + } else if (retCode == 2) { + ndbout << "4115 should not happen in flexAsynch" << endl; + } else if (retCode == 3) { + /* What can we do here? */ + ndbout_c("execute: %s", NdbObject->getNdbError().message); + }//if(retCode == 3) + + // ndbout << "Error occured in poll:" << NdbObject->getNdbError() << + // " ErrorCode = " << NdbObject->getNdbError() << endl; + ndbout << "executeCallback threadInfo->transactionCompleted = " << + threadInfo->transactionCompleted << endl; + failed++ ; + return; + } + return; +} + +void +defineOperation(NdbConnection* localNdbConnection, + StartType aType, + unsigned int threadBase, + int *pRow ) +{ + NdbOperation* localNdbOperation; + unsigned int loopCountAttributes = tNoOfAttributes; + unsigned int countAttributes; + int attrValue[MAXATTRSIZE]; + + //------------------------------------------------------- + // Set-up the attribute values for this operation. + //------------------------------------------------------- + for (int k = 0; k < loopCountAttributes; k++) { + *(int *)&attrValue[k] = (int)threadBase; + } + localNdbOperation = localNdbConnection->getNdbOperation(tableName[0]); + if (localNdbOperation == NULL) { + error_handler(localNdbOperation->getNdbError()) ; + } + + switch (aType) { + case stInsert: { // Insert case + if (theWriteFlag == 1 && theDirtyFlag == 1) { + localNdbOperation->dirtyWrite(); + } else if (theWriteFlag == 1) { + localNdbOperation->writeTuple(); + } else { + localNdbOperation->insertTuple(); + } + break; + } + case stRead: { // Read Case + if (theSimpleFlag == 1) { + localNdbOperation->simpleRead(); + } else if (theDirtyFlag == 1) { + localNdbOperation->dirtyRead(); + } else { + localNdbOperation->readTuple(); + } + break; + } + case stUpdate: { // Update Case + if (theWriteFlag == 1 && theDirtyFlag == 1) { + localNdbOperation->dirtyWrite(); + } else if (theWriteFlag == 1) { + localNdbOperation->writeTuple(); + } else if (theDirtyFlag == 1) { + localNdbOperation->dirtyUpdate(); + } else { + localNdbOperation->updateTuple(); + } + break; + } + case stDelete: { // Delete Case + localNdbOperation->deleteTuple(); + break; + } + default: { + error_handler(localNdbOperation->getNdbError()); + } + } + + localNdbOperation->equal((char*)attrName[0],(char*)&attrValue[0]); + + switch (aType) { + case stInsert: // Insert case + case stUpdate: // Update Case + { + for (countAttributes = 1; countAttributes < loopCountAttributes; countAttributes++) { + localNdbOperation->setValue( (char*)attrName[countAttributes],(char*)&attrValue[0]); + } + break; + } + case stRead: { // Read Case + for (countAttributes = 1; countAttributes < loopCountAttributes; countAttributes++) { + //localNdbOperation->getValue((char*)attrName[countAttributes],(char*)&attrValue[0]); + localNdbOperation->getValue((char*)attrName[countAttributes], + (char *) (pRow + countAttributes*tAttributeSize)); + } + break; + } + case stDelete: { // Delete Case + break; + } + default: { + error_handler(localNdbOperation->getNdbError()); + } + } + return; +} + +void readArguments(int argc, const char** argv) +{ + int i = 1; + while (argc > 1) + { + if (strcmp(argv[i], "-t") == 0) + { + tNoOfThreads = atoi(argv[i+1]); + // if ((tNoOfThreads < 1) || (tNoOfThreads > MAXTHREADS)) + if ((tNoOfThreads < 1) || (tNoOfThreads > MAXTHREADS)) + exit(-1); + } + else if (strcmp(argv[i], "-i") == 0) + { + tTimeBetweenBatches = atoi(argv[i+1]); + if (tTimeBetweenBatches < 0) + exit(-1); + } + else if (strcmp(argv[i], "-p") == 0) + { + tNoOfTransInBatch = atoi(argv[i+1]); + //if ((tNoOfTransInBatch < 1) || (tNoOfTransInBatch > MAXTHREADS)) + if ((tNoOfTransInBatch < 1) || (tNoOfTransInBatch > 10000)) + exit(-1); + } + else if (strcmp(argv[i], "-c") == 0) + { + tNoOfOpsPerTrans = atoi(argv[i+1]); + if (tNoOfOpsPerTrans < 1) + exit(-1); + } + else if (strcmp(argv[i], "-o") == 0) + { + tNoOfBatchesInLoop = atoi(argv[i+1]); + if (tNoOfBatchesInLoop < 1) + exit(-1); + } + else if (strcmp(argv[i], "-a") == 0) + { + tNoOfAttributes = atoi(argv[i+1]); + if ((tNoOfAttributes < 2) || (tNoOfAttributes > MAXATTR)) + exit(-1); + } + else if (strcmp(argv[i], "-n") == 0) + { + theStdTableNameFlag = 1; + argc++; + i--; + } + else if (strcmp(argv[i], "-l") == 0) + { + tNoOfLoops = atoi(argv[i+1]); + if ((tNoOfLoops < 0) || (tNoOfLoops > 100000)) + exit(-1); + } + else if (strcmp(argv[i], "-s") == 0) + { + tAttributeSize = atoi(argv[i+1]); + if ((tAttributeSize < 1) || (tAttributeSize > MAXATTRSIZE)) + exit(-1); + } + else if (strcmp(argv[i], "-simple") == 0) + { + theSimpleFlag = 1; + argc++; + i--; + } + else if (strcmp(argv[i], "-write") == 0) + { + theWriteFlag = 1; + argc++; + i--; + } + else if (strcmp(argv[i], "-dirty") == 0) + { + theDirtyFlag = 1; + argc++; + i--; + } + else if (strcmp(argv[i], "-test") == 0) + { + theTestFlag = 1; + argc++; + i--; + } + else if (strcmp(argv[i], "-temp") == 0) + { + theTempFlag = 0; // 0 if temporary tables. + argc++; + i--; + } + else if (strcmp(argv[i], "-no_table_create") == 0) + { + theTableCreateFlag = 1; + argc++; + i--; + } + else + { + ndbout << "Arguments: " << endl; + ndbout << "-t Number of threads to start, i.e., number of parallel loops, default 1 " << endl; + ndbout << "-p Number of transactions in a batch, default 32 " << endl; + ndbout << "-o Number of batches per loop, default 200 " << endl; + ndbout << "-i Minimum time between batch starts in milli seconds, default 0 " << endl; + ndbout << "-l Number of loops to run, default 1, 0=infinite " << endl; + ndbout << "-a Number of attributes, default 25 " << endl; + ndbout << "-c Number of operations per transaction, default 1 " << endl; + ndbout << "-s Size of each attribute in 32 bit word, default 1" + "(Primary Key is always of size 1, independent of this value) " << endl; + ndbout << "-simple Use simple read to read from database " << endl; + ndbout << "-dirty Use dirty read to read from database " << endl; + ndbout << "-write Use writeTuple in insert and update " << endl; + ndbout << "-n Use standard table names " << endl; + ndbout << "-no_table_create Don't create tables in db " << endl; + ndbout << "-temp Use temporary tables, no writing to disk. " << endl; + exit(-1); + } + + argc -= 2; + i = i + 2; + } +} + +void setAttrNames() +{ + int i; + + for (i = 0; i < MAXATTR ; i++) + { + sprintf(attrName[i], "COL%d", i); + } +} + + +void setTableNames() +{ + // Note! Uses only uppercase letters in table name's + // so that we can look at the tables with SQL + int i; + for (i = 0; i < MAXTABLES ; i++) + { + if (theStdTableNameFlag==1) + { + sprintf(tableName[i], "TAB%d_%d", tNoOfAttributes, + NdbTick_CurrentMillisecond()/1000); + } else { + sprintf(tableName[i], "TAB%d_%d", tNoOfAttributes, tAttributeSize*4); + } + } +} + +void createTables(Ndb* pMyNdb) +{ + + NdbSchemaCon *MySchemaTransaction; + NdbSchemaOp *MySchemaOp; + int check; + + if (theTableCreateFlag == 0) + { + for(int i=0; i < 1 ;i++) + { + ndbout << "Creating " << tableName[i] << "..." << endl; + MySchemaTransaction = pMyNdb->startSchemaTransaction(); + + if( MySchemaTransaction == + NULL && (!error_handler(MySchemaTransaction->getNdbError()))) + exit(-1) ;/*goto error_handler; getNdbSchemaOp(); + if( MySchemaOp == NULL + && (!error_handler(MySchemaTransaction->getNdbError()))) + exit(-1) ; + + check = MySchemaOp->createTable( tableName[i], + 8, // Table Size + TupleKey, // Key Type + 40, // Nr of Pages + All, // FragmentType + 6, + 78, + 80, + 1, // MemoryType + theTempFlag // 0 if temporary tables else 1 + ); + + if ( check == -1 && (!error_handler(MySchemaTransaction->getNdbError()))) + exit(-1) ; /* epaulsa > goto error_handler; < epaulsa */ + + + check = MySchemaOp->createAttribute( (char*)attrName[0], + TupleKey, + 32, + PKSIZE, + UnSigned, + MMBased, + NotNullAttribute ); + + if ( check == -1 &&(!error_handler(MySchemaTransaction->getNdbError()))) + exit(-1) ; /* epaulsa > goto error_handler; < epaulsa */ + + for (int j = 1; j < tNoOfAttributes ; j++) + { + check = MySchemaOp->createAttribute( (char*)attrName[j], + NoKey, + 32, + tAttributeSize, + UnSigned, + MMBased, + NotNullAttribute ); + if ( check == -1 + && (!error_handler(MySchemaTransaction->getNdbError()))) + exit(-1) ; /* epaulsa > goto error_handler; < epaulsa */ + } + + if ( MySchemaTransaction->execute() == -1 + &&(!error_handler(MySchemaTransaction->getNdbError()))) + exit(-1) ; /* epaulsa > goto error_handler; < epaulsa */ + + pMyNdb->closeSchemaTransaction(MySchemaTransaction); + } + } + + return; +} + +bool error_handler(const NdbError & err) { + ndbout << err << endl ; + if ( 4008==err.code || 721==err.code || 266==err.code ){ + ndbout << endl << "Attempting to recover and continue now..." << endl ; + return true ; // return true to retry + } + return false ; // return false to abort +} + + +//******************************************************************************************* + + + + + diff --git a/ndb/test/ndbapi/flexTimedAsynch/Makefile b/ndb/test/ndbapi/flexTimedAsynch/Makefile deleted file mode 100644 index e9995dbd16f..00000000000 --- a/ndb/test/ndbapi/flexTimedAsynch/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := flexTimedAsynch - -# Source files of non-templated classes (.C files) -SOURCES = flexTimedAsynch.cpp - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/test/ndbapi/flexTimedAsynch/flexTimedAsynch.cpp b/ndb/test/ndbapi/flexTimedAsynch/flexTimedAsynch.cpp deleted file mode 100644 index 761be53fdd3..00000000000 --- a/ndb/test/ndbapi/flexTimedAsynch/flexTimedAsynch.cpp +++ /dev/null @@ -1,852 +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 */ - -/* *************************************************** - FLEXTIMEDASYNCH - Perform benchmark of insert, update and delete transactions. - - Arguments: - -t Number of threads to start, i.e., number of parallel loops, default 1 - -p Number of transactions in a batch, default 32 - -o Number of batches per loop, default 200 - -i Time between batch starts, default 0 - -l Number of loops to run, default 1, 0=infinite - -a Number of attributes, default 25 - -c Number of operations per transaction - -s Size of each attribute in 32 bit word, default 1 (Primary Key is always of size 1, - independent of this value) - -simple Use simple read to read from database - -dirty Use dirty read to read from database - -write Use writeTuple in insert and update - -n Use standard table names - -no_table_create Don't create tables in db - -temp Use temporary tables, no writing to disk. - - Returns: - 0 - Test passed - -1 - Test failed - 1 - Invalid arguments - - * *************************************************** */ - -#include "NdbApi.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define MAXSTRLEN 16 -#define MAXATTR 64 -#define MAXTABLES 64 -#define MAXTHREADS 256 -#define MAXATTRSIZE 1000 -#define PKSIZE 1 - -enum StartType { stIdle, - stInsert, - stRead, - stUpdate, - stDelete, - stStop } ; - -ErrorData * flexTimedAsynchErrorData; - -struct ThreadNdb -{ - int NoOfOps; - int ThreadNo; - unsigned int threadBase; - unsigned int transactionCompleted; -}; - -extern "C" void* threadLoop(void*); -void setAttrNames(void); -void setTableNames(void); -void readArguments(int argc, const char** argv); -void createAttributeSpace(); -void createTables(Ndb*); -void defineOperation(NdbConnection* aTransObject, StartType aType, unsigned int key, int *); -void execute(StartType aType); -void executeThread(StartType aType, Ndb* aNdbObject, ThreadNdb* threadInfo); -void executeCallback(int result, NdbConnection* NdbObject, void* aObject); - -/* epaulsa > *************************************************************/ -bool error_handler(const NdbError &) ; //replaces 'goto' things -static int failed = 0 ; // lame global variable that keeps track of failed transactions - // incremented in executeCallback() and reset in main() -/************************************************************* < epaulsa */ - -static NdbThread* threadLife[MAXTHREADS]; -static int tNodeId; -static int ThreadReady[MAXTHREADS]; -static StartType ThreadStart[MAXTHREADS]; -static char tableName[MAXTABLES][MAXSTRLEN+1]; -static char attrName[MAXATTR][MAXSTRLEN+1]; -static int *getAttrValueTable; - -// Program Parameters -static int tNoOfLoops = 1; -static int tAttributeSize = 1; -static unsigned int tNoOfThreads = 1; -static unsigned int tNoOfTransInBatch = 32; -static unsigned int tNoOfAttributes = 25; -static unsigned int tNoOfBatchesInLoop = 200; -static unsigned int tNoOfOpsPerTrans = 1; -static unsigned int tTimeBetweenBatches = 0; - -//Program Flags -static int theTestFlag = 0; -static int theTempFlag = 1; -static int theSimpleFlag = 0; -static int theDirtyFlag = 0; -static int theWriteFlag = 0; -static int theStdTableNameFlag = 0; -static int theTableCreateFlag = 0; - -#define START_REAL_TIME NdbTimer timer; timer.doStart(); -#define STOP_REAL_TIME timer.doStop(); - -#define START_TIMER { NdbTimer timer; timer.doStart(); -#define STOP_TIMER timer.doStop(); -#define PRINT_TIMER(text, trans, opertrans) timer.printTransactionStatistics(text, trans, opertrans); }; - -void -resetThreads(){ - - for (int i = 0; i < tNoOfThreads ; i++) { - ThreadReady[i] = 0; - ThreadStart[i] = stIdle; - } -} - -void -waitForThreads(void) -{ - int cont; - do { - cont = 0; - NdbSleep_MilliSleep(20); - for (int i = 0; i < tNoOfThreads ; i++) { - if (ThreadReady[i] == 0) { - cont = 1; - } - } - } while (cont == 1); -} - -void -tellThreads(StartType what) -{ - for (int i = 0; i < tNoOfThreads ; i++) - ThreadStart[i] = what; -} - -void createAttributeSpace(){ - getAttrValueTable = new int[tAttributeSize* - tNoOfThreads * - tNoOfAttributes ]; - -} - -void deleteAttributeSpace(){ - delete [] getAttrValueTable; -} - -NDB_COMMAND(flexTimedAsynch, "flexTimedAsynch", "flexTimedAsynch [-tpoilcas]", "flexTimedAsynch", 65535) -{ - ThreadNdb tabThread[MAXTHREADS]; - int tLoops=0; - int returnValue; - //NdbOut flexTimedAsynchNdbOut; - - flexTimedAsynchErrorData = new ErrorData; - flexTimedAsynchErrorData->resetErrorCounters(); - - Ndb* pNdb; - pNdb = new Ndb( "TEST_DB" ); - pNdb->init(); - - readArguments(argc, argv); - - createAttributeSpace(); - - ndbout << endl << "FLEXTIMEDASYNCH - Starting normal mode" << endl; - ndbout << "Perform benchmark of insert, update and delete transactions" << endl << endl; - - if(theTempFlag == 0) - ndbout << " " << "Using temporary tables. " << endl; - - // -t, tNoOfThreads - ndbout << " " << tNoOfThreads << " number of concurrent threads " << endl; - // -c, tNoOfOpsPerTrans - ndbout << " " << tNoOfOpsPerTrans << " operations per transaction " << endl; - // -p, tNoOfTransInBatch - ndbout << " " << tNoOfTransInBatch << " number of transactions in a batch per thread " << endl; - // -o, tNoOfBatchesInLoop - ndbout << " " << tNoOfBatchesInLoop << " number of batches per loop " << endl; - // -i, tTimeBetweenBatches - ndbout << " " << tTimeBetweenBatches << " milli seconds at least between batch starts " << endl; - // -l, tNoOfLoops - ndbout << " " << tNoOfLoops << " loops " << endl; - // -a, tNoOfAttributes - ndbout << " " << tNoOfAttributes << " attributes per table " << endl; - // -s, tAttributeSize - ndbout << " " << tAttributeSize << " is the number of 32 bit words per attribute " << endl << endl; - - NdbThread_SetConcurrencyLevel(2 + tNoOfThreads); - - /* print Setting */ - flexTimedAsynchErrorData->printSettings(ndbout); - - setAttrNames(); - setTableNames(); - - ndbout << "Waiting for ndb to become ready..." <waitUntilReady() == 0) { - tNodeId = pNdb->getNodeId(); - ndbout << " NdbAPI node with id = " << tNodeId << endl; - createTables(pNdb); - - /**************************************************************** - * Create NDB objects. * - ****************************************************************/ - resetThreads(); - for (int i = 0; i < tNoOfThreads ; i++) { - tabThread[i].ThreadNo = i; - - threadLife[i] = NdbThread_Create(threadLoop, - (void**)&tabThread[i], - 32768, - "flexTimedAsynchThread", - NDB_THREAD_PRIO_LOW); - } - ndbout << endl << "All NDB objects and table created" << endl << endl; - int noOfTransacts = tNoOfTransInBatch*tNoOfBatchesInLoop*tNoOfThreads; - - /**************************************************************** - * Execute program. * - ****************************************************************/ - - - for(;;) { - - int loopCount = tLoops + 1 ; - ndbout << endl << "Loop # " << loopCount << endl << endl ; - - /**************************************************************** - * Perform inserts. * - ****************************************************************/ - - failed = 0 ; - - START_TIMER; - execute(stInsert); - STOP_TIMER; - PRINT_TIMER("insert", noOfTransacts, tNoOfOpsPerTrans); - - if (0 < failed) { - ndbout << failed << " of the transactions returned errors!, moving on now..."<printErrorCounters(ndbout); - - return NDBT_ProgramExit(returnValue); -}//main() - -//////////////////////////////////////// - -void execute(StartType aType) -{ - resetThreads(); - tellThreads(aType); - waitForThreads(); -} - -void* -threadLoop(void* ThreadData) -{ - // Do work until signaled to stop. - - Ndb* localNdb; - StartType tType; - ThreadNdb* threadInfo = (ThreadNdb*)ThreadData; - int threadNo = threadInfo->ThreadNo; - localNdb = new Ndb("TEST_DB"); - localNdb->init(512); - localNdb->waitUntilReady(); - threadInfo->threadBase = (threadNo * 2000000) + (tNodeId * 260000000); - - for (;;) { - while (ThreadStart[threadNo] == stIdle) { - NdbSleep_MilliSleep(10); - } - - // Check if signal to exit is received - if (ThreadStart[threadNo] == stStop) { - break; - } - - tType = ThreadStart[threadNo]; - ThreadStart[threadNo] = stIdle; - executeThread(tType, localNdb, threadInfo); - ThreadReady[threadNo] = 1; - } - - delete localNdb; - ThreadReady[threadNo] = 1; - NdbThread_Exit(0); - - return NULL; -} - -void executeThread(StartType aType, Ndb* aNdbObject, ThreadNdb* threadInfo) -{ - // Do all batch job in loop with start specified delay - int i, j, k; - NdbConnection* tConArray[1024]; - unsigned int tBase; - unsigned int tBase2; - int threadId = threadInfo->ThreadNo; - int *getValueRowAddress = NULL; - - NdbTimer timer; - timer.doStart(); - - for (i = 0; i < tNoOfBatchesInLoop; i++) { - //tBase = threadBase + (i * tNoOfTransInBatch * tNoOfOpsPerTrans); - tBase = threadInfo->threadBase + (i * tNoOfTransInBatch * tNoOfOpsPerTrans); - //tCompleted = 0; - threadInfo->transactionCompleted = 0; - - for (j = 0; j < tNoOfTransInBatch; j++) { - tBase2 = tBase + (j * tNoOfOpsPerTrans); - tConArray[j] = aNdbObject->startTransaction(); - if ( tConArray[j] == NULL && !error_handler(aNdbObject->getNdbError())) { - ndbout << endl << "Unable to recover! Quiting now" << endl ; - exit (-1) ; - return ; - } - - for (k = 0; k < tNoOfOpsPerTrans; k++) { - //------------------------------------------------------- - // Define the operation, but do not execute it yet. - //------------------------------------------------------- - if(aType == stRead){ - getValueRowAddress = getAttrValueTable + - threadId * tNoOfAttributes * tAttributeSize; - } - defineOperation(tConArray[j], aType, (tBase2 + k), getValueRowAddress); - } - - tConArray[j]->executeAsynchPrepare(Commit, &executeCallback, threadInfo); - } - - //------------------------------------------------------- - // Now we have defined a set of transactions (= batch), it is now time - // to execute all of them. - //------------------------------------------------------- - aNdbObject->sendPollNdb(3000, 0, 0); - - //while (tCompleted < tNoOfTransInBatch) { - while (threadInfo->transactionCompleted < tNoOfTransInBatch) { - aNdbObject->pollNdb(3000, 0); - ndbout << "threadInfo->transactionCompleted = " << - threadInfo->transactionCompleted << endl; - } - - for (j = 0 ; j < tNoOfTransInBatch ; j++) { - aNdbObject->closeTransaction(tConArray[j]); - } - - // Control the elapsed time since the last batch start. - // Wait at least tTimeBetweenBatches milli seconds. - timer.doStop(); - while(timer.elapsedTime() < tTimeBetweenBatches){ - NdbSleep_MilliSleep(1); - timer.doStop(); - } - // Ready to start new batch - timer.doStart(); - } - return; -} - -void -executeCallback(int result, NdbConnection* NdbObject, void* aObject) -{ - //tCompleted++; - ThreadNdb *threadInfo = (ThreadNdb *)aObject; - threadInfo->transactionCompleted++; - - if (result == -1) { - - // Add complete error handling here - - int retCode = flexTimedAsynchErrorData->handleErrorCommon(NdbObject->getNdbError()); - if (retCode == 1) { - if (NdbObject->getNdbError().code != 626 && NdbObject->getNdbError().code != 630){ - ndbout_c("execute: %s", NdbObject->getNdbError().message); - ndbout_c("Error code = %d", NdbObject->getNdbError().code);} - } else if (retCode == 2) { - ndbout << "4115 should not happen in flexAsynch" << endl; - } else if (retCode == 3) { - /* What can we do here? */ - ndbout_c("execute: %s", NdbObject->getNdbError().message); - }//if(retCode == 3) - - // ndbout << "Error occured in poll:" << NdbObject->getNdbError() << - // " ErrorCode = " << NdbObject->getNdbError() << endl; - ndbout << "executeCallback threadInfo->transactionCompleted = " << - threadInfo->transactionCompleted << endl; - failed++ ; - return; - } - return; -} - -void -defineOperation(NdbConnection* localNdbConnection, - StartType aType, - unsigned int threadBase, - int *pRow ) -{ - NdbOperation* localNdbOperation; - unsigned int loopCountAttributes = tNoOfAttributes; - unsigned int countAttributes; - int attrValue[MAXATTRSIZE]; - - //------------------------------------------------------- - // Set-up the attribute values for this operation. - //------------------------------------------------------- - for (int k = 0; k < loopCountAttributes; k++) { - *(int *)&attrValue[k] = (int)threadBase; - } - localNdbOperation = localNdbConnection->getNdbOperation(tableName[0]); - if (localNdbOperation == NULL) { - error_handler(localNdbOperation->getNdbError()) ; - } - - switch (aType) { - case stInsert: { // Insert case - if (theWriteFlag == 1 && theDirtyFlag == 1) { - localNdbOperation->dirtyWrite(); - } else if (theWriteFlag == 1) { - localNdbOperation->writeTuple(); - } else { - localNdbOperation->insertTuple(); - } - break; - } - case stRead: { // Read Case - if (theSimpleFlag == 1) { - localNdbOperation->simpleRead(); - } else if (theDirtyFlag == 1) { - localNdbOperation->dirtyRead(); - } else { - localNdbOperation->readTuple(); - } - break; - } - case stUpdate: { // Update Case - if (theWriteFlag == 1 && theDirtyFlag == 1) { - localNdbOperation->dirtyWrite(); - } else if (theWriteFlag == 1) { - localNdbOperation->writeTuple(); - } else if (theDirtyFlag == 1) { - localNdbOperation->dirtyUpdate(); - } else { - localNdbOperation->updateTuple(); - } - break; - } - case stDelete: { // Delete Case - localNdbOperation->deleteTuple(); - break; - } - default: { - error_handler(localNdbOperation->getNdbError()); - } - } - - localNdbOperation->equal((char*)attrName[0],(char*)&attrValue[0]); - - switch (aType) { - case stInsert: // Insert case - case stUpdate: // Update Case - { - for (countAttributes = 1; countAttributes < loopCountAttributes; countAttributes++) { - localNdbOperation->setValue( (char*)attrName[countAttributes],(char*)&attrValue[0]); - } - break; - } - case stRead: { // Read Case - for (countAttributes = 1; countAttributes < loopCountAttributes; countAttributes++) { - //localNdbOperation->getValue((char*)attrName[countAttributes],(char*)&attrValue[0]); - localNdbOperation->getValue((char*)attrName[countAttributes], - (char *) (pRow + countAttributes*tAttributeSize)); - } - break; - } - case stDelete: { // Delete Case - break; - } - default: { - error_handler(localNdbOperation->getNdbError()); - } - } - return; -} - -void readArguments(int argc, const char** argv) -{ - int i = 1; - while (argc > 1) - { - if (strcmp(argv[i], "-t") == 0) - { - tNoOfThreads = atoi(argv[i+1]); - // if ((tNoOfThreads < 1) || (tNoOfThreads > MAXTHREADS)) - if ((tNoOfThreads < 1) || (tNoOfThreads > MAXTHREADS)) - exit(-1); - } - else if (strcmp(argv[i], "-i") == 0) - { - tTimeBetweenBatches = atoi(argv[i+1]); - if (tTimeBetweenBatches < 0) - exit(-1); - } - else if (strcmp(argv[i], "-p") == 0) - { - tNoOfTransInBatch = atoi(argv[i+1]); - //if ((tNoOfTransInBatch < 1) || (tNoOfTransInBatch > MAXTHREADS)) - if ((tNoOfTransInBatch < 1) || (tNoOfTransInBatch > 10000)) - exit(-1); - } - else if (strcmp(argv[i], "-c") == 0) - { - tNoOfOpsPerTrans = atoi(argv[i+1]); - if (tNoOfOpsPerTrans < 1) - exit(-1); - } - else if (strcmp(argv[i], "-o") == 0) - { - tNoOfBatchesInLoop = atoi(argv[i+1]); - if (tNoOfBatchesInLoop < 1) - exit(-1); - } - else if (strcmp(argv[i], "-a") == 0) - { - tNoOfAttributes = atoi(argv[i+1]); - if ((tNoOfAttributes < 2) || (tNoOfAttributes > MAXATTR)) - exit(-1); - } - else if (strcmp(argv[i], "-n") == 0) - { - theStdTableNameFlag = 1; - argc++; - i--; - } - else if (strcmp(argv[i], "-l") == 0) - { - tNoOfLoops = atoi(argv[i+1]); - if ((tNoOfLoops < 0) || (tNoOfLoops > 100000)) - exit(-1); - } - else if (strcmp(argv[i], "-s") == 0) - { - tAttributeSize = atoi(argv[i+1]); - if ((tAttributeSize < 1) || (tAttributeSize > MAXATTRSIZE)) - exit(-1); - } - else if (strcmp(argv[i], "-simple") == 0) - { - theSimpleFlag = 1; - argc++; - i--; - } - else if (strcmp(argv[i], "-write") == 0) - { - theWriteFlag = 1; - argc++; - i--; - } - else if (strcmp(argv[i], "-dirty") == 0) - { - theDirtyFlag = 1; - argc++; - i--; - } - else if (strcmp(argv[i], "-test") == 0) - { - theTestFlag = 1; - argc++; - i--; - } - else if (strcmp(argv[i], "-temp") == 0) - { - theTempFlag = 0; // 0 if temporary tables. - argc++; - i--; - } - else if (strcmp(argv[i], "-no_table_create") == 0) - { - theTableCreateFlag = 1; - argc++; - i--; - } - else - { - ndbout << "Arguments: " << endl; - ndbout << "-t Number of threads to start, i.e., number of parallel loops, default 1 " << endl; - ndbout << "-p Number of transactions in a batch, default 32 " << endl; - ndbout << "-o Number of batches per loop, default 200 " << endl; - ndbout << "-i Minimum time between batch starts in milli seconds, default 0 " << endl; - ndbout << "-l Number of loops to run, default 1, 0=infinite " << endl; - ndbout << "-a Number of attributes, default 25 " << endl; - ndbout << "-c Number of operations per transaction, default 1 " << endl; - ndbout << "-s Size of each attribute in 32 bit word, default 1" - "(Primary Key is always of size 1, independent of this value) " << endl; - ndbout << "-simple Use simple read to read from database " << endl; - ndbout << "-dirty Use dirty read to read from database " << endl; - ndbout << "-write Use writeTuple in insert and update " << endl; - ndbout << "-n Use standard table names " << endl; - ndbout << "-no_table_create Don't create tables in db " << endl; - ndbout << "-temp Use temporary tables, no writing to disk. " << endl; - exit(-1); - } - - argc -= 2; - i = i + 2; - } -} - -void setAttrNames() -{ - int i; - - for (i = 0; i < MAXATTR ; i++) - { - sprintf(attrName[i], "COL%d", i); - } -} - - -void setTableNames() -{ - // Note! Uses only uppercase letters in table name's - // so that we can look at the tables with SQL - int i; - for (i = 0; i < MAXTABLES ; i++) - { - if (theStdTableNameFlag==1) - { - sprintf(tableName[i], "TAB%d_%d", tNoOfAttributes, - NdbTick_CurrentMillisecond()/1000); - } else { - sprintf(tableName[i], "TAB%d_%d", tNoOfAttributes, tAttributeSize*4); - } - } -} - -void createTables(Ndb* pMyNdb) -{ - - NdbSchemaCon *MySchemaTransaction; - NdbSchemaOp *MySchemaOp; - int check; - - if (theTableCreateFlag == 0) - { - for(int i=0; i < 1 ;i++) - { - ndbout << "Creating " << tableName[i] << "..." << endl; - MySchemaTransaction = pMyNdb->startSchemaTransaction(); - - if( MySchemaTransaction == - NULL && (!error_handler(MySchemaTransaction->getNdbError()))) - exit(-1) ;/*goto error_handler; getNdbSchemaOp(); - if( MySchemaOp == NULL - && (!error_handler(MySchemaTransaction->getNdbError()))) - exit(-1) ; - - check = MySchemaOp->createTable( tableName[i], - 8, // Table Size - TupleKey, // Key Type - 40, // Nr of Pages - All, // FragmentType - 6, - 78, - 80, - 1, // MemoryType - theTempFlag // 0 if temporary tables else 1 - ); - - if ( check == -1 && (!error_handler(MySchemaTransaction->getNdbError()))) - exit(-1) ; /* epaulsa > goto error_handler; < epaulsa */ - - - check = MySchemaOp->createAttribute( (char*)attrName[0], - TupleKey, - 32, - PKSIZE, - UnSigned, - MMBased, - NotNullAttribute ); - - if ( check == -1 &&(!error_handler(MySchemaTransaction->getNdbError()))) - exit(-1) ; /* epaulsa > goto error_handler; < epaulsa */ - - for (int j = 1; j < tNoOfAttributes ; j++) - { - check = MySchemaOp->createAttribute( (char*)attrName[j], - NoKey, - 32, - tAttributeSize, - UnSigned, - MMBased, - NotNullAttribute ); - if ( check == -1 - && (!error_handler(MySchemaTransaction->getNdbError()))) - exit(-1) ; /* epaulsa > goto error_handler; < epaulsa */ - } - - if ( MySchemaTransaction->execute() == -1 - &&(!error_handler(MySchemaTransaction->getNdbError()))) - exit(-1) ; /* epaulsa > goto error_handler; < epaulsa */ - - pMyNdb->closeSchemaTransaction(MySchemaTransaction); - } - } - - return; -} - -bool error_handler(const NdbError & err) { - ndbout << err << endl ; - if ( 4008==err.code || 721==err.code || 266==err.code ){ - ndbout << endl << "Attempting to recover and continue now..." << endl ; - return true ; // return true to retry - } - return false ; // return false to abort -} - - -//******************************************************************************************* - - - - - diff --git a/ndb/test/ndbapi/flex_bench_mysql.cpp b/ndb/test/ndbapi/flex_bench_mysql.cpp new file mode 100644 index 00000000000..7cc883ab3e6 --- /dev/null +++ b/ndb/test/ndbapi/flex_bench_mysql.cpp @@ -0,0 +1,1749 @@ +/* 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 */ + + +/* *************************************************** +FLEXBENCH +Perform benchmark of insert, update and delete transactions + +Arguments: + -t Number of threads to start, default 1 + -o Number of operations per loop, default 500 + -l Number of loops to run, default 1, 0=infinite + -a Number of attributes, default 25 + -c Number of tables, default 1 + -s Size of each attribute, default 1 (Primary Key is always of size 1, + independent of this value) + -lkn Number of long primary keys, default 1 + -lks Size of each long primary key, default 1 + -simple Use simple read to read from database + -dirty Use dirty read to read from database + -write Use writeTuple in insert and update + -stdtables Use standard table names + -no_table_create Don't create tables in db + -sleep Sleep a number of seconds before running the test, this + can be used so that another flexBench have time to create tables + -temp Use tables without logging + -verify Verify inserts, updates and deletes + -use_ndb Use NDB API, otherwise use mysql client +#ifdef CEBIT_STAT + -statserv host:port statistics server to report to + -statfreq ops report every ops operations (default 100) +#endif + Returns: + 0 - Test passed + 1 - Test failed + 2 - Invalid arguments + +* *************************************************** */ + +#define USE_MYSQL +#ifdef USE_MYSQL +#include +#endif + +#include "NdbApi.hpp" + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define MAXSTRLEN 16 +#define MAXATTR 64 +#define MAXTABLES 128 +#define MAXATTRSIZE 1000 +#define MAXNOLONGKEY 16 // Max number of long keys. +#define MAXLONGKEYTOTALSIZE 1023 // words = 4092 bytes + +extern "C" { static void* flexBenchThread(void*); } +static int readArguments(int argc, const char** argv); +#ifdef USE_MYSQL +static int createTables(MYSQL*); +static int dropTables(MYSQL*); +#endif +static int createTables(Ndb*); +static void sleepBeforeStartingTest(int seconds); +static void input_error(); + +enum StartType { + stIdle, + stInsert, + stVerify, + stRead, + stUpdate, + stDelete, + stTryDelete, + stVerifyDelete, + stStop +}; + +struct ThreadData +{ + int threadNo; + NdbThread* threadLife; + int threadReady; + StartType threadStart; + int threadResult; +}; + +static int tNodeId = 0 ; +static char tableName[MAXTABLES][MAXSTRLEN+1]; +static char attrName[MAXATTR][MAXSTRLEN+1]; +static char** longKeyAttrName; + +// Program Parameters +static int tNoOfLoops = 1; +static int tAttributeSize = 1; +static unsigned int tNoOfThreads = 1; +static unsigned int tNoOfTables = 1; +static unsigned int tNoOfAttributes = 25; +static unsigned int tNoOfOperations = 500; +static unsigned int tSleepTime = 0; +static unsigned int tNoOfLongPK = 1; +static unsigned int tSizeOfLongPK = 1; +static unsigned int t_instances = 1; + +//Program Flags +static int theSimpleFlag = 0; +static int theDirtyFlag = 0; +static int theWriteFlag = 0; +static int theStdTableNameFlag = 0; +static int theTableCreateFlag = 0; +static bool theTempTable = false; +static bool VerifyFlag = true; +static bool useLongKeys = false; +static bool verbose = false; +#ifdef USE_MYSQL +static bool use_ndb = false; +static int engine_id = 0; +static int sockets[16]; +static int n_sockets = 0; +static char* engine[] = + { + " ENGINE = NDBCLUSTER ", // use default engine + " ENGINE = MEMORY ", + " ENGINE = MYISAM ", + " ENGINE = INNODB " + }; +#else +static bool use_ndb = true; +#endif + +static ErrorData theErrorData; // Part of flexBench-program + +#define START_TIMER { NdbTimer timer; timer.doStart(); +#define STOP_TIMER timer.doStop(); +#define PRINT_TIMER(text, trans, opertrans) timer.printTransactionStatistics(text, trans, opertrans); }; + +#include + +#ifdef CEBIT_STAT +#include +static bool statEnable = false; +static char statHost[100]; +static int statFreq = 100; +static int statPort = 0; +static int statSock = -1; +static enum { statError = -1, statClosed, statOpen } statState; +static NdbMutex statMutex = NDB_MUTEX_INITIALIZER; +#endif + +//------------------------------------------------------------------- +// Statistical Reporting routines +//------------------------------------------------------------------- +#ifdef CEBIT_STAT +// Experimental client-side statistic for CeBIT + +static void +statReport(enum StartType st, int ops) +{ + if (!statEnable) + return; + if (NdbMutex_Lock(&statMutex) < 0) { + if (statState != statError) { + ndbout_c("stat: lock mutex failed: %s", strerror(errno)); + statState = statError; + } + return; + } + static int nodeid; + // open connection + if (statState != statOpen) { + char *p = getenv("NDB_NODEID"); // ndbnet sets NDB_NODEID + nodeid = p == 0 ? 0 : atoi(p); + if ((statSock = socket(PF_INET, SOCK_STREAM, 0)) < 0) { + if (statState != statError) { + ndbout_c("stat: create socket failed: %s", strerror(errno)); + statState = statError; + } + (void)NdbMutex_Unlock(&statMutex); + return; + } + struct sockaddr_in saddr; + memset(&saddr, 0, sizeof(saddr)); + saddr.sin_family = AF_INET; + saddr.sin_port = htons(statPort); + if (Ndb_getInAddr(&saddr.sin_addr, statHost) < 0) { + if (statState != statError) { + ndbout_c("stat: host %s not found", statHost); + statState = statError; + } + (void)close(statSock); + (void)NdbMutex_Unlock(&statMutex); + return; + } + if (connect(statSock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { + if (statState != statError) { + ndbout_c("stat: connect failed: %s", strerror(errno)); + statState = statError; + } + (void)close(statSock); + (void)NdbMutex_Unlock(&statMutex); + return; + } + statState = statOpen; + ndbout_c("stat: connection to %s:%d opened", statHost, (int)statPort); + } + const char *text; + switch (st) { + case stInsert: + text = "insert"; + break; + case stVerify: + text = "verify"; + break; + case stRead: + text = "read"; + break; + case stUpdate: + text = "update"; + break; + case stDelete: + text = "delete"; + break; + case stVerifyDelete: + text = "verifydelete"; + break; + default: + text = "unknown"; + break; + } + char buf[100]; + sprintf(buf, "%d %s %d\n", nodeid, text, ops); + int len = strlen(buf); + // assume SIGPIPE already ignored + if (write(statSock, buf, len) != len) { + if (statState != statError) { + ndbout_c("stat: write failed: %s", strerror(errno)); + statState = statError; + } + (void)close(statSock); + (void)NdbMutex_Unlock(&statMutex); + return; + } + (void)NdbMutex_Unlock(&statMutex); +} +#endif // CEBIT_STAT + +static void +resetThreads(ThreadData* pt){ + for (unsigned int i = 0; i < tNoOfThreads; i++){ + pt[i].threadReady = 0; + pt[i].threadResult = 0; + pt[i].threadStart = stIdle; + } +} + +static int +checkThreadResults(ThreadData* pt){ + for (unsigned int i = 0; i < tNoOfThreads; i++){ + if(pt[i].threadResult != 0){ + ndbout_c("Thread%d reported fatal error %d", i, pt[i].threadResult); + return -1; + } + } + return 0; +} + +static +void +waitForThreads(ThreadData* pt) +{ + int cont = 1; + while (cont){ + NdbSleep_MilliSleep(100); + cont = 0; + for (unsigned int i = 0; i < tNoOfThreads; i++){ + if (pt[i].threadReady == 0) + cont = 1; + } + } +} + +static void +tellThreads(ThreadData* pt, StartType what) +{ + for (unsigned int i = 0; i < tNoOfThreads; i++) + pt[i].threadStart = what; +} + +NDB_COMMAND(flexBench, "flexBench", "flexBench", "flexbench", 65535) +{ + ThreadData* pThreadsData; + int tLoops = 0; + int returnValue = NDBT_OK; + if (readArguments(argc, argv) != 0){ + input_error(); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + NdbAutoPtr p10; + if(useLongKeys){ + int e1 = sizeof(char*) * tNoOfLongPK; + int e2_1 = strlen("KEYATTR ") + 1; + int e2 = e2_1 * tNoOfLongPK; + char *tmp = (char *) malloc(e1 + e2); + p10.reset(tmp); + longKeyAttrName = (char **) tmp; + tmp += e1; + for (Uint32 i = 0; i < tNoOfLongPK; i++) { + // longKeyAttrName[i] = (char *) malloc(strlen("KEYATTR ") + 1); + longKeyAttrName[i] = tmp; + tmp += e2_1; + memset(longKeyAttrName[i], 0, e2_1); + sprintf(longKeyAttrName[i], "KEYATTR%i", i); + } + } + + NdbAutoObjArrayPtr + p12( pThreadsData = new ThreadData[tNoOfThreads] ); + + + ndbout << endl << "FLEXBENCH - Starting normal mode" << endl; + ndbout << "Perform benchmark of insert, update and delete transactions"<< endl; + ndbout << " " << tNoOfThreads << " thread(s) " << endl; + ndbout << " " << tNoOfLoops << " iterations " << endl; + ndbout << " " << tNoOfTables << " table(s) and " << 1 << " operation(s) per transaction " <getNodeId(); + ndbout << " NdbAPI node with id = " << tNodeId << endl; + ndbout << endl; + + ndbout << "Waiting for ndb to become ready..." <waitUntilReady(2000) != 0){ + ndbout << "NDB is not ready" << endl; + ndbout << "Benchmark failed!" << endl; + returnValue = NDBT_FAILED; + } + if(returnValue == NDBT_OK){ + if (createTables(pNdb) != 0){ + returnValue = NDBT_FAILED; + } + } + return_ndb_object(pNdb, ndb_id); + } + } + } + if(returnValue == NDBT_OK){ + + sleepBeforeStartingTest(tSleepTime); + + /**************************************************************** + * Create threads. * + ****************************************************************/ + resetThreads(pThreadsData); + + for (unsigned int i = 0; i < tNoOfThreads; i++){ + pThreadsData[i].threadNo = i; + pThreadsData[i].threadLife = NdbThread_Create(flexBenchThread, + (void**)&pThreadsData[i], + 32768, + "flexBenchThread", + NDB_THREAD_PRIO_LOW); + } + + waitForThreads(pThreadsData); + + ndbout << endl << "All threads started" << endl << endl; + + /**************************************************************** + * Execute program. * + ****************************************************************/ + + for(;;){ + + int loopCount = tLoops + 1; + ndbout << endl << "Loop # " << loopCount << endl << endl; + + /**************************************************************** + * Perform inserts. * + ****************************************************************/ + // Reset and start timer + START_TIMER; + // Give insert-command to all threads + resetThreads(pThreadsData); + tellThreads(pThreadsData, stInsert); + waitForThreads(pThreadsData); + if (checkThreadResults(pThreadsData) != 0){ + ndbout << "Error: Threads failed in performing insert" << endl; + returnValue = NDBT_FAILED; + break; + } + // stop timer and print results. + STOP_TIMER; + PRINT_TIMER("insert", tNoOfOperations*tNoOfThreads, tNoOfTables); + /**************************************************************** + * Verify inserts. * + ****************************************************************/ + if (VerifyFlag) { + resetThreads(pThreadsData); + ndbout << "Verifying inserts...\t" ; + tellThreads(pThreadsData, stVerify); + waitForThreads(pThreadsData); + if (checkThreadResults(pThreadsData) != 0){ + ndbout << "Error: Threads failed while verifying inserts" << endl; + returnValue = NDBT_FAILED; + break; + }else{ + ndbout << "\t\tOK" << endl << endl ; + } + } + + /**************************************************************** + * Perform read. * + ****************************************************************/ + // Reset and start timer + START_TIMER; + // Give read-command to all threads + resetThreads(pThreadsData); + tellThreads(pThreadsData, stRead); + waitForThreads(pThreadsData); + if (checkThreadResults(pThreadsData) != 0){ + ndbout << "Error: Threads failed in performing read" << endl; + returnValue = NDBT_FAILED; + break; + } + // stop timer and print results. + STOP_TIMER; + PRINT_TIMER("read", tNoOfOperations*tNoOfThreads, tNoOfTables); + + /**************************************************************** + * Perform update. * + ****************************************************************/ + // Reset and start timer + START_TIMER; + // Give update-command to all threads + resetThreads(pThreadsData); + tellThreads(pThreadsData, stUpdate); + waitForThreads(pThreadsData); + if (checkThreadResults(pThreadsData) != 0){ + ndbout << "Error: Threads failed in performing update" << endl; + returnValue = NDBT_FAILED; + break; + } + // stop timer and print results. + STOP_TIMER; + PRINT_TIMER("update", tNoOfOperations*tNoOfThreads, tNoOfTables); + + /**************************************************************** + * Verify updates. * + ****************************************************************/ + if (VerifyFlag) { + resetThreads(pThreadsData); + ndbout << "Verifying updates...\t" ; + tellThreads(pThreadsData, stVerify); + waitForThreads(pThreadsData); + if (checkThreadResults(pThreadsData) != 0){ + ndbout << "Error: Threads failed while verifying updates" << endl; + returnValue = NDBT_FAILED; + break; + }else{ + ndbout << "\t\tOK" << endl << endl ; + } + } + + /**************************************************************** + * Perform read. * + ****************************************************************/ + // Reset and start timer + START_TIMER; + // Give read-command to all threads + resetThreads(pThreadsData); + tellThreads(pThreadsData, stRead); + waitForThreads(pThreadsData); + if (checkThreadResults(pThreadsData) != 0){ + ndbout << "Error: Threads failed in performing read" << endl; + returnValue = NDBT_FAILED; + break; + } + // stop timer and print results. + STOP_TIMER; + PRINT_TIMER("read", tNoOfOperations*tNoOfThreads, tNoOfTables); + + /**************************************************************** + * Perform delete. * + ****************************************************************/ + // Reset and start timer + START_TIMER; + // Give delete-command to all threads + resetThreads(pThreadsData); + tellThreads(pThreadsData, stDelete); + waitForThreads(pThreadsData); + if (checkThreadResults(pThreadsData) != 0){ + ndbout << "Error: Threads failed in performing delete" << endl; + returnValue = NDBT_FAILED; + break; + } + // stop timer and print results. + STOP_TIMER; + PRINT_TIMER("delete", tNoOfOperations*tNoOfThreads, tNoOfTables); + + /**************************************************************** + * Verify deletes. * + ****************************************************************/ + if (VerifyFlag) { + resetThreads(pThreadsData); + ndbout << "Verifying tuple deletion..." ; + tellThreads(pThreadsData, stVerifyDelete); + waitForThreads(pThreadsData); + if (checkThreadResults(pThreadsData) != 0){ + ndbout << "Error: Threads failed in verifying deletes" << endl; + returnValue = NDBT_FAILED; + break; + }else{ + ndbout << "\t\tOK" << endl << endl ; + } + } + + ndbout << "--------------------------------------------------" << endl; + + tLoops++; + + if ( 0 != tNoOfLoops && tNoOfLoops <= tLoops ) + break; + theErrorData.printErrorCounters(); + } + + resetThreads(pThreadsData); + tellThreads(pThreadsData, stStop); + waitForThreads(pThreadsData); + + void * tmp; + for(Uint32 i = 0; i> 8) & 255); + hash_value = (hash_value << 5) + hash_value + ((h_key >> 16) & 255); + hash_value = (hash_value << 5) + hash_value + ((h_key >> 24) & 255); + } + return hash_value; +} + +// End of warming up phase + + + +static void* flexBenchThread(void* pArg) +{ + ThreadData* pThreadData = (ThreadData*)pArg; + unsigned int threadNo, threadBase; + Ndb* pNdb = NULL ; + Uint32 ndb_id = 0; + NdbConnection *pTrans = NULL ; + NdbOperation** pOps = NULL ; + StartType tType ; + StartType tSaveType ; + NdbRecAttr* tTmp = NULL ; + int* attrValue = NULL ; + int* attrRefValue = NULL ; + int check = 0 ; + int loopCountOps, loopCountTables, loopCountAttributes; + int tAttemptNo = 0; + int tRetryAttempts = 20; + int tResult = 0; + int tSpecialTrans = 0; + int nRefLocalOpOffset = 0 ; + int nReadBuffSize = + tNoOfTables * tNoOfAttributes * sizeof(int) * tAttributeSize ; + int nRefBuffSize = + tNoOfOperations * tNoOfAttributes * sizeof(int) * tAttributeSize ; + unsigned*** longKeyAttrValue = NULL; + + + threadNo = pThreadData->threadNo ; + +#ifdef USE_MYSQL + MYSQL mysql; + int the_socket = sockets[threadNo % n_sockets]; + char the_socket_name[1024]; + //sprintf(the_socket_name, "%s", "/tmp/mysql.sock"); + sprintf(the_socket_name, "%s%u%s", "/tmp/mysql.",the_socket,".sock"); + if (!use_ndb) { + ndbout << the_socket_name << endl; + ndbout << "Thread connecting to MySQL... " << endl; + mysql_init(&mysql); + + if ( mysql_real_connect(&mysql, + "localhost", + "root", + "", + "test", + the_socket, + the_socket_name, + 0) == NULL ) { + ndbout << "failed" << endl; + NdbThread_Exit(0) ; + } + ndbout << "ok" << endl; + + int r; + if (tNoOfTables > 1) + r = mysql_autocommit(&mysql, 0); + else + r = mysql_autocommit(&mysql, 1); + + if (r) { + ndbout << "autocommit on/off failed" << endl; + NdbThread_Exit(0) ; + } + } +#endif + + NdbAutoPtr p00( attrValue= (int*)malloc(nReadBuffSize) ) ; + NdbAutoPtr p01( attrRefValue= (int*)malloc(nRefBuffSize) ); + if (use_ndb) { + pOps = (NdbOperation**)malloc(tNoOfTables*sizeof(NdbOperation*)) ; + } + NdbAutoPtr p02( pOps ); + + if( !attrValue || !attrRefValue || + ( use_ndb && ( !pOps) ) ){ + // Check allocations to make sure we got all the memory we asked for + ndbout << "One or more memory allocations failed when starting thread #"; + ndbout << threadNo << endl ; + ndbout << "Thread #" << threadNo << " will now exit" << endl ; + tResult = 13 ; + NdbThread_Exit(0) ; + } + + if (use_ndb) { + pNdb = get_ndb_object(ndb_id, "test", "def"); + if (pNdb == NULL) { + ndbout << "Failed to get an NDB object" << endl; + ndbout << "Thread #" << threadNo << " will now exit" << endl ; + tResult = 13; + NdbThread_Exit(0) ; + } + pNdb->waitUntilReady(); + return_ndb_object(pNdb, ndb_id); + pNdb = NULL; + } + + // To make sure that two different threads doesn't operate on the same record + // Calculate an "unique" number to use as primary key + threadBase = (threadNo * 2000000) + (tNodeId * 260000000); + + NdbAutoPtr p22; + if(useLongKeys){ + // Allocate and populate the longkey array. + int e1 = sizeof(unsigned**) * tNoOfOperations; + int e2 = sizeof(unsigned*) * tNoOfLongPK * tNoOfOperations; + int e3 = sizeof(unsigned) * tSizeOfLongPK * tNoOfLongPK * tNoOfOperations; + char* tmp; + p22.reset(tmp = (char*)malloc(e1+e2+e3)); + + longKeyAttrValue = (unsigned ***) tmp; + tmp += e1; + for (Uint32 n = 0; n < tNoOfOperations; n++) { + longKeyAttrValue[n] = (unsigned **) tmp; + tmp += sizeof(unsigned*) * tNoOfLongPK; + } + + for (Uint32 n = 0; n < tNoOfOperations; n++){ + for (Uint32 i = 0; i < tNoOfLongPK ; i++) { + longKeyAttrValue[n][i] = (unsigned *) tmp; + tmp += sizeof(unsigned) * tSizeOfLongPK; + memset(longKeyAttrValue[n][i], 0, sizeof(unsigned) * tSizeOfLongPK); + for(Uint32 j = 0; j < tSizeOfLongPK; j++) { + // Repeat the unique value to fill up the long key. + longKeyAttrValue[n][i][j] = threadBase + n; + } + } + } + } + + int nRefOpOffset = 0 ; + //Assign reference attribute values to memory + for(Uint32 ops = 1 ; ops < tNoOfOperations ; ops++){ + // Calculate offset value before going into the next loop + nRefOpOffset = tAttributeSize*tNoOfAttributes*(ops-1) ; + for(Uint32 a = 0 ; a < tNoOfAttributes ; a++){ + *(int*)&attrRefValue[nRefOpOffset + tAttributeSize*a] = + (int)(threadBase + ops + a) ; + } + } + +#ifdef CEBIT_STAT + // ops not yet reported + int statOps = 0; +#endif + +#ifdef USE_MYSQL + // temporary buffer to store prepared statement text + char buf[2048]; + MYSQL_STMT** prep_read = NULL; + MYSQL_STMT** prep_delete = NULL; + MYSQL_STMT** prep_update = NULL; + MYSQL_STMT** prep_insert = NULL; + MYSQL_BIND* bind_delete = NULL; + MYSQL_BIND* bind_read = NULL; + MYSQL_BIND* bind_update = NULL; + MYSQL_BIND* bind_insert = NULL; + int* mysql_data = NULL; + + NdbAutoPtr p21; + + if (!use_ndb) { + // data array to which prepared statements are bound + char* tmp; + int e1 = sizeof(int)*tAttributeSize*tNoOfAttributes; + int e2 = sizeof(MYSQL_BIND)*tNoOfAttributes; + int e3 = sizeof(MYSQL_BIND)*tNoOfAttributes; + int e4 = sizeof(MYSQL_BIND)*tNoOfAttributes; + int e5 = sizeof(MYSQL_BIND)*1; + int e6 = sizeof(MYSQL_STMT*)*tNoOfTables; + int e7 = sizeof(MYSQL_STMT*)*tNoOfTables; + int e8 = sizeof(MYSQL_STMT*)*tNoOfTables; + int e9 = sizeof(MYSQL_STMT*)*tNoOfTables; + p21.reset(tmp = (char*)malloc(e1+e2+e3+e4+e5+e6+e7+e8+e9)); + + mysql_data = (int*)tmp; tmp += e1; + bind_insert = (MYSQL_BIND*)tmp; tmp += e2; + bind_update = (MYSQL_BIND*)tmp; tmp += e3; + bind_read = (MYSQL_BIND*)tmp; tmp += e4; + bind_delete = (MYSQL_BIND*)tmp; tmp += e5; + prep_insert = (MYSQL_STMT**)tmp; tmp += e6; + prep_update = (MYSQL_STMT**)tmp; tmp += e7; + prep_read = (MYSQL_STMT**)tmp; tmp += e8; + prep_delete = (MYSQL_STMT**)tmp; + + for (Uint32 ca = 0; ca < tNoOfAttributes; ca++){ + MYSQL_BIND& bi = bind_insert[ca]; + bi.buffer_type = MYSQL_TYPE_LONG; + bi.buffer = (char*)&mysql_data[ca*tAttributeSize]; + bi.buffer_length = 0; + bi.length = NULL; + bi.is_null = NULL; + }//for + + for (Uint32 ca = 0; ca < tNoOfAttributes; ca++){ + MYSQL_BIND& bi = bind_update[ca]; + bi.buffer_type = MYSQL_TYPE_LONG; + if ( ca == tNoOfAttributes-1 ) // the primary key comes last in statement + bi.buffer = (char*)&mysql_data[0]; + else + bi.buffer = (char*)&mysql_data[(ca+1)*tAttributeSize]; + bi.buffer_length = 0; + bi.length = NULL; + bi.is_null = NULL; + }//for + + for (Uint32 ca = 0; ca < tNoOfAttributes; ca++){ + MYSQL_BIND& bi = bind_read[ca]; + bi.buffer_type = MYSQL_TYPE_LONG; + bi.buffer = (char*)&mysql_data[ca*tAttributeSize]; + bi.buffer_length = 4; + bi.length = NULL; + bi.is_null = NULL; + }//for + + for (Uint32 ca = 0; ca < 1; ca++){ + MYSQL_BIND& bi = bind_delete[ca]; + bi.buffer_type = MYSQL_TYPE_LONG; + bi.buffer = (char*)&mysql_data[ca*tAttributeSize]; + bi.buffer_length = 0; + bi.length = NULL; + bi.is_null = NULL; + }//for + + for (Uint32 i = 0; i < tNoOfTables; i++) { + int pos = 0; + pos += sprintf(buf+pos, "%s%s%s", + "INSERT INTO ", + tableName[i], + " VALUES("); + pos += sprintf(buf+pos, "%s", "?"); + for (Uint32 j = 1; j < tNoOfAttributes; j++) { + pos += sprintf(buf+pos, "%s", ",?"); + } + pos += sprintf(buf+pos, "%s", ")"); + if (verbose) + ndbout << buf << endl; + prep_insert[i] = mysql_prepare(&mysql, buf, pos); + if (prep_insert[i] == 0) { + ndbout << "mysql_prepare: " << mysql_error(&mysql) << endl; + NdbThread_Exit(0) ; + } + if (mysql_bind_param(prep_insert[i], bind_insert)) { + ndbout << "mysql_bind_param: " << mysql_error(&mysql) << endl; + NdbThread_Exit(0) ; + } + } + + for (Uint32 i = 0; i < tNoOfTables; i++) { + int pos = 0; + pos += sprintf(buf+pos, "%s%s%s", + "UPDATE ", + tableName[i], + " SET "); + for (Uint32 j = 1; j < tNoOfAttributes; j++) { + if (j != 1) + pos += sprintf(buf+pos, "%s", ","); + pos += sprintf(buf+pos, "%s%s", attrName[j],"=?"); + } + pos += sprintf(buf+pos, "%s%s%s", " WHERE ", attrName[0], "=?"); + + if (verbose) + ndbout << buf << endl; + prep_update[i] = mysql_prepare(&mysql, buf, pos); + if (prep_update[i] == 0) { + ndbout << "mysql_prepare: " << mysql_error(&mysql) << endl; + NdbThread_Exit(0) ; + } + if (mysql_bind_param(prep_update[i], bind_update)) { + ndbout << "mysql_bind_param: " << mysql_error(&mysql) << endl; + NdbThread_Exit(0) ; + } + } + + for (Uint32 i = 0; i < tNoOfTables; i++) { + int pos = 0; + pos += sprintf(buf+pos, "%s", "SELECT "); + for (Uint32 j = 1; j < tNoOfAttributes; j++) { + if (j != 1) + pos += sprintf(buf+pos, "%s", ","); + pos += sprintf(buf+pos, "%s", attrName[j]); + } + pos += sprintf(buf+pos, "%s%s%s%s%s", + " FROM ", + tableName[i], + " WHERE ", + attrName[0], + "=?"); + if (verbose) + ndbout << buf << endl; + prep_read[i] = mysql_prepare(&mysql, buf, pos); + if (prep_read[i] == 0) { + ndbout << "mysql_prepare: " << mysql_error(&mysql) << endl; + NdbThread_Exit(0) ; + } + if (mysql_bind_param(prep_read[i], bind_read)) { + ndbout << "mysql_bind_param: " << mysql_error(&mysql) << endl; + NdbThread_Exit(0) ; + } + if (mysql_bind_result(prep_read[i], &bind_read[1])) { + ndbout << "mysql_bind_result: " << mysql_error(&mysql) << endl; + NdbThread_Exit(0) ; + } + } + + for (Uint32 i = 0; i < tNoOfTables; i++) { + int pos = 0; + pos += sprintf(buf+pos, "%s%s%s%s%s", + "DELETE FROM ", + tableName[i], + " WHERE ", + attrName[0], + "=?"); + if (verbose) + ndbout << buf << endl; + prep_delete[i] = mysql_prepare(&mysql, buf, pos); + if (prep_delete[i] == 0) { + ndbout << "mysql_prepare: " << mysql_error(&mysql) << endl; + NdbThread_Exit(0) ; + } + if (mysql_bind_param(prep_delete[i], bind_delete)) { + ndbout << "mysql_bind_param: " << mysql_error(&mysql) << endl; + NdbThread_Exit(0) ; + } + } + } +#endif + + for (;;) { + pThreadData->threadResult = tResult; // Report error to main thread, + // normally tResult is set to 0 + pThreadData->threadReady = 1; + + while (pThreadData->threadStart == stIdle){ + NdbSleep_MilliSleep(100); + }//while + + // Check if signal to exit is received + if (pThreadData->threadStart == stStop){ + pThreadData->threadReady = 1; + // ndbout_c("Thread%d is stopping", threadNo); + // In order to stop this thread, the main thread has signaled + // stStop, break out of the for loop so that destructors + // and the proper exit functions are called + break; + }//if + + tType = pThreadData->threadStart; + tSaveType = tType; + pThreadData->threadStart = stIdle; + + // Start transaction, type of transaction + // is received in the array ThreadStart + loopCountOps = tNoOfOperations; + loopCountTables = tNoOfTables; + loopCountAttributes = tNoOfAttributes; + for (int count = 1; count < loopCountOps && tResult == 0;){ + + if (use_ndb) { + pNdb = get_ndb_object(ndb_id, "test", "def"); + if (pNdb == NULL) { + ndbout << "Could not get Ndb object in thread" << threadNo; + ndbout << endl; + tResult = 1; //Indicate fatal error + break; + } + pTrans = pNdb->startTransaction(); + if (pTrans == NULL) { + // This is a fatal error, abort program + ndbout << "Could not start transaction in thread" << threadNo; + ndbout << endl; + ndbout << pNdb->getNdbError() << endl; + tResult = 1; // Indicate fatal error + break; // Break out of for loop + } + } + + // Calculate the current operation offset in the reference array + nRefLocalOpOffset = tAttributeSize*tNoOfAttributes*(count - 1) ; + int* tmpAttrRefValue = attrRefValue + nRefLocalOpOffset; + + for (int countTables = 0; + countTables < loopCountTables && tResult == 0; + countTables++) { + + int nTableOffset = tAttributeSize * + loopCountAttributes * + countTables ; + + int* tmpAttrValue = attrValue + nTableOffset; + + if (use_ndb) { + pOps[countTables] = pTrans->getNdbOperation(tableName[countTables]); + if (pOps[countTables] == NULL) { + // This is a fatal error, abort program + ndbout << "getNdbOperation: " << pTrans->getNdbError(); + tResult = 2; // Indicate fatal error + break; + }//if + + switch (tType) { + case stInsert: // Insert case + if (theWriteFlag == 1 && theDirtyFlag == 1) + pOps[countTables]->dirtyWrite(); + else if (theWriteFlag == 1) + pOps[countTables]->writeTuple(); + else + pOps[countTables]->insertTuple(); + break; + case stRead: // Read Case + if (theSimpleFlag == 1) + pOps[countTables]->simpleRead(); + else if (theDirtyFlag == 1) + pOps[countTables]->dirtyRead(); + else + pOps[countTables]->readTuple(); + break; + case stUpdate: // Update Case + if (theWriteFlag == 1 && theDirtyFlag == 1) + pOps[countTables]->dirtyWrite(); + else if (theWriteFlag == 1) + pOps[countTables]->writeTuple(); + else if (theDirtyFlag == 1) + pOps[countTables]->dirtyUpdate(); + else + pOps[countTables]->updateTuple(); + break; + case stDelete: // Delete Case + pOps[countTables]->deleteTuple(); + break; + case stVerify: + pOps[countTables]->readTuple(); + break; + case stVerifyDelete: + pOps[countTables]->readTuple(); + break; + default: + assert(false); + }//switch + + if(useLongKeys){ + // Loop the equal call so the complete key is send to the kernel. + for(Uint32 i = 0; i < tNoOfLongPK; i++) + pOps[countTables]->equal(longKeyAttrName[i], + (char *)longKeyAttrValue[count - 1][i], + tSizeOfLongPK*4); + } + else + pOps[countTables]->equal((char*)attrName[0], + (char*)&tmpAttrRefValue[0]); + + if (tType == stInsert) { + for (int ca = 1; ca < loopCountAttributes; ca++){ + pOps[countTables]->setValue((char*)attrName[ca], + (char*)&tmpAttrRefValue[tAttributeSize*ca]); + }//for + } else if (tType == stUpdate) { + for (int ca = 1; ca < loopCountAttributes; ca++){ + int* tmp = (int*)&tmpAttrRefValue[tAttributeSize*ca]; + if (countTables == 0) + (*tmp)++; + pOps[countTables]->setValue((char*)attrName[ca],(char*)tmp); + }//for + } else if (tType == stRead || stVerify == tType) { + for (int ca = 1; ca < loopCountAttributes; ca++) { + tTmp = + pOps[countTables]->getValue((char*)attrName[ca], + (char*)&tmpAttrValue[tAttributeSize*ca]); + }//for + } else if (stVerifyDelete == tType) { + if(useLongKeys){ + tTmp = pOps[countTables]->getValue(longKeyAttrName[0], + (char*)&tmpAttrValue[0]); + } else { + tTmp = pOps[countTables]->getValue((char*)attrName[0], + (char*)&tmpAttrValue[0]); + } + }//if + } else { // !use_ndb +#ifndef USE_MYSQL + assert(false); +#else + switch (tType) + { + case stInsert: + for (int ca = 0; ca < loopCountAttributes; ca++){ + mysql_data[ca] = tmpAttrRefValue[tAttributeSize*ca]; + }//for + if (mysql_execute(prep_insert[countTables])) { + ndbout << tableName[countTables]; + ndbout << " mysql_execute: " << mysql_error(&mysql) << endl; + tResult = 1 ; + } + break; + case stUpdate: // Update Case + mysql_data[0] = tmpAttrRefValue[0]; + for (int ca = 1; ca < loopCountAttributes; ca++){ + int* tmp = (int*)&tmpAttrRefValue[tAttributeSize*ca]; + if (countTables == 0) + (*tmp)++; + mysql_data[ca] = *tmp; + }//for + if (mysql_execute(prep_update[countTables])) { + ndbout << tableName[countTables]; + ndbout << " mysql_execute: " << mysql_error(&mysql) << endl; + tResult = 2 ; + } + break; + case stVerify: + case stRead: // Read Case + mysql_data[0] = tmpAttrRefValue[0]; + if (mysql_execute(prep_read[countTables])) { + ndbout << tableName[countTables]; + ndbout << " mysql_execute: " << mysql_error(&mysql) << endl; + tResult = 3 ; + break; + } + if (mysql_stmt_store_result(prep_read[countTables])) { + ndbout << tableName[countTables]; + ndbout << " mysql_stmt_store_result: " + << mysql_error(&mysql) << endl; + tResult = 4 ; + break; + } + { + int rows= 0; + int r; + while ( (r= mysql_fetch(prep_read[countTables])) == 0 ){ + rows++; + } + if ( r == 1 ) { + ndbout << tableName[countTables]; + ndbout << " mysql_fetch: " << mysql_error(&mysql) << endl; + tResult = 5 ; + break; + } + if ( rows != 1 ) { + ndbout << tableName[countTables]; + ndbout << " mysql_fetch: rows = " << rows << endl; + tResult = 6 ; + break; + } + } + { + for (int ca = 1; ca < loopCountAttributes; ca++) { + tmpAttrValue[tAttributeSize*ca] = mysql_data[ca]; + } + } + break; + case stDelete: // Delete Case + mysql_data[0] = tmpAttrRefValue[0]; + if (mysql_execute(prep_delete[countTables])) { + ndbout << tableName[countTables]; + ndbout << " mysql_execute: " << mysql_error(&mysql) << endl; + tResult = 7 ; + break; + } + break; + case stVerifyDelete: + { + sprintf(buf, "%s%s%s", + "SELECT COUNT(*) FROM ",tableName[countTables],";"); + if (mysql_query(&mysql, buf)) { + ndbout << buf << endl; + ndbout << "Error: " << mysql_error(&mysql) << endl; + tResult = 8 ; + break; + } + MYSQL_RES *res = mysql_store_result(&mysql); + if ( res == NULL ) { + ndbout << "mysql_store_result: " + << mysql_error(&mysql) << endl + << "errno: " << mysql_errno(&mysql) << endl; + tResult = 9 ; + break; + } + int num_fields = mysql_num_fields(res); + int num_rows = mysql_num_rows(res); + if ( num_rows != 1 || num_fields != 1 ) { + ndbout << tableName[countTables]; + ndbout << " mysql_store_result: num_rows = " << num_rows + << " num_fields = " << num_fields << endl; + tResult = 10 ; + break; + } + MYSQL_ROW row = mysql_fetch_row(res); + if ( row == NULL ) { + ndbout << "mysql_fetch_row: " + << mysql_error(&mysql) << endl; + tResult = 11 ; + break; + } + if ( *(char*)row[0] != '0' ) { + ndbout << tableName[countTables]; + ndbout << " mysql_fetch_row: value = " + << (char*)(row[0]) << endl; + tResult = 12 ; + break; + } + mysql_free_result(res); + } + break; + default: + assert(false); + } +#endif + } + }//for Tables loop + + if (tResult != 0) + break; + + if (use_ndb){ + check = pTrans->execute(Commit); + } else { +#ifdef USE_MYSQL + if (tNoOfTables > 1) + if (mysql_commit(&mysql)) { + ndbout << " mysql_commit: " << mysql_error(&mysql) << endl; + tResult = 13; + } else + check = 0; +#endif + } + + if (use_ndb) { + // Decide what kind of error this is + if ((tSpecialTrans == 1) && + (check == -1)) { +// -------------------------------------------------------------------- +// A special transaction have been executed, change to check = 0 in +// certain situations. +// -------------------------------------------------------------------- + switch (tType) { + case stInsert: // Insert case + if (630 == pTrans->getNdbError().code ) { + check = 0; + ndbout << "Insert with 4007 was successful" << endl; + }//if + break; + case stDelete: // Delete Case + if (626 == pTrans->getNdbError().code ) { + check = 0; + ndbout << "Delete with 4007 was successful" << endl; + }//if + break; + default: + assert(false); + }//switch + }//if + tSpecialTrans = 0; + if (check == -1) { + if ((stVerifyDelete == tType) && + (626 == pTrans->getNdbError().code)) { + // ---------------------------------------------- + // It's good news - the deleted tuple is gone, + // so reset "check" flag + // ---------------------------------------------- + check = 0 ; + } else { + int retCode = + theErrorData.handleErrorCommon(pTrans->getNdbError()); + if (retCode == 1) { + ndbout_c("execute: %d, %d, %s", count, tType, + pTrans->getNdbError().message ); + ndbout_c("Error code = %d", pTrans->getNdbError().code ); + tResult = 20; + } else if (retCode == 2) { + ndbout << "4115 should not happen in flexBench" << endl; + tResult = 20; + } else if (retCode == 3) { +// -------------------------------------------------------------------- +// We are not certain if the transaction was successful or not. +// We must reexecute but might very well find that the transaction +// actually was updated. Updates and Reads are no problem here. Inserts +// will not cause a problem if error code 630 arrives. Deletes will +// not cause a problem if 626 arrives. +// -------------------------------------------------------------------- + if ((tType == stInsert) || (tType == stDelete)) { + tSpecialTrans = 1; + }//if + }//if + }//if + }//if + // Check if retries should be made + if (check == -1 && tResult == 0) { + if (tAttemptNo < tRetryAttempts){ + tAttemptNo++; + } else { +// -------------------------------------------------------------------- +// Too many retries have been made, report error and break out of loop +// -------------------------------------------------------------------- + ndbout << "Thread" << threadNo; + ndbout << ": too many errors reported" << endl; + tResult = 10; + break; + }//if + }//if + } + + if (check == 0){ + // Go to the next record + count++; + tAttemptNo = 0; +#ifdef CEBIT_STAT + // report successful ops + if (statEnable) { + statOps += loopCountTables; + if (statOps >= statFreq) { + statReport(tType, statOps); + statOps = 0; + }//if + }//if +#endif + }//if + + if (stVerify == tType && 0 == check){ + int nTableOffset = 0 ; + for (int a = 1 ; a < loopCountAttributes ; a++){ + for (int tables = 0 ; tables < loopCountTables ; tables++){ + nTableOffset = tables*loopCountAttributes*tAttributeSize; + int ov =*(int*)&attrValue[nTableOffset + tAttributeSize*a]; + int nv =*(int*)&tmpAttrRefValue[tAttributeSize*a]; + if (ov != nv){ + ndbout << "Error in verify "; + ndbout << "pk = " << tmpAttrRefValue[0] << ":" << endl; + ndbout << "attrValue[" << nTableOffset + tAttributeSize*a << "] = " << ov << endl ; + ndbout << "attrRefValue[" << nRefLocalOpOffset + tAttributeSize*a << "]" << nv << endl ; + tResult = 11 ; + break ; + }//if + }//for + }//for + }// if(stVerify ... ) + if (use_ndb) { + pNdb->closeTransaction(pTrans); + return_ndb_object(pNdb, ndb_id); + pNdb = NULL; + } + }// operations loop +#ifdef CEBIT_STAT + // report remaining successful ops + if (statEnable) { + if (statOps > 0) { + statReport(tType, statOps); + statOps = 0; + }//if + }//if +#endif + if (pNdb) { + pNdb->closeTransaction(pTrans); + return_ndb_object(pNdb, ndb_id); + pNdb = NULL; + } + } + +#ifdef USE_MYSQL + if (!use_ndb) { + mysql_close(&mysql); + for (Uint32 i = 0; i < tNoOfTables; i++) { + mysql_stmt_close(prep_insert[i]); + mysql_stmt_close(prep_update[i]); + mysql_stmt_close(prep_delete[i]); + mysql_stmt_close(prep_read[i]); + } + } +#endif + if (use_ndb && pNdb) { + ndbout << "I got here " << endl; + return_ndb_object(pNdb, ndb_id); + } + NdbThread_Exit(0); + return NULL; // Just to keep compiler happy +} + + +static int readArguments(int argc, const char** argv) +{ + + int i = 1; + while (argc > 1){ + if (strcmp(argv[i], "-t") == 0){ + tNoOfThreads = atoi(argv[i+1]); + if ((tNoOfThreads < 1)) + return -1; + argc -= 1; + i++; + }else if (strcmp(argv[i], "-o") == 0){ + tNoOfOperations = atoi(argv[i+1]); + if (tNoOfOperations < 1) + return -1;; + argc -= 1; + i++; + }else if (strcmp(argv[i], "-a") == 0){ + tNoOfAttributes = atoi(argv[i+1]); + if ((tNoOfAttributes < 2) || (tNoOfAttributes > MAXATTR)) + return -1; + argc -= 1; + i++; + }else if (strcmp(argv[i], "-c") == 0){ + tNoOfTables = atoi(argv[i+1]); + if ((tNoOfTables < 1) || (tNoOfTables > MAXTABLES)) + return -1; + argc -= 1; + i++; + }else if (strcmp(argv[i], "-stdtables") == 0){ + theStdTableNameFlag = 1; + }else if (strcmp(argv[i], "-l") == 0){ + tNoOfLoops = atoi(argv[i+1]); + if ((tNoOfLoops < 0) || (tNoOfLoops > 100000)) + return -1; + argc -= 1; + i++; + }else if (strcmp(argv[i], "-pool_size") == 0){ + t_instances = atoi(argv[i+1]); + if ((t_instances < 1) || (t_instances > 240)) + return -1; + argc -= 1; + i++; +#ifdef USE_MYSQL + }else if (strcmp(argv[i], "-engine") == 0){ + engine_id = atoi(argv[i+1]); + if ((engine_id < 0) || (engine_id > 3)) + return -1; + argc -= 1; + i++; + }else if (strcmp(argv[i], "-socket") == 0){ + sockets[n_sockets] = atoi(argv[i+1]); + if (sockets[n_sockets] <= 0) + return -1; + n_sockets++; + argc -= 1; + i++; + }else if (strcmp(argv[i], "-use_ndb") == 0){ + use_ndb = true; +#endif + }else if (strcmp(argv[i], "-s") == 0){ + tAttributeSize = atoi(argv[i+1]); + if ((tAttributeSize < 1) || (tAttributeSize > MAXATTRSIZE)) + return -1; + argc -= 1; + i++; + }else if (strcmp(argv[i], "-lkn") == 0){ + tNoOfLongPK = atoi(argv[i+1]); + useLongKeys = true; + if ((tNoOfLongPK < 1) || (tNoOfLongPK > MAXNOLONGKEY) || + (tNoOfLongPK * tSizeOfLongPK) > MAXLONGKEYTOTALSIZE){ + ndbout << "Argument -lkn is not in the proper range." << endl; + return -1; + } + argc -= 1; + i++; + }else if (strcmp(argv[i], "-lks") == 0){ + tSizeOfLongPK = atoi(argv[i+1]); + useLongKeys = true; + if ((tSizeOfLongPK < 1) || (tNoOfLongPK * tSizeOfLongPK) > MAXLONGKEYTOTALSIZE){ + ndbout << "Argument -lks is not in the proper range 1 to " << + MAXLONGKEYTOTALSIZE << endl; + return -1; + } + argc -= 1; + i++; + }else if (strcmp(argv[i], "-simple") == 0){ + theSimpleFlag = 1; + }else if (strcmp(argv[i], "-write") == 0){ + theWriteFlag = 1; + }else if (strcmp(argv[i], "-dirty") == 0){ + theDirtyFlag = 1; + }else if (strcmp(argv[i], "-sleep") == 0){ + tSleepTime = atoi(argv[i+1]); + if ((tSleepTime < 1) || (tSleepTime > 3600)) + return -1; + argc -= 1; + i++; + }else if (strcmp(argv[i], "-no_table_create") == 0){ + theTableCreateFlag = 1; + }else if (strcmp(argv[i], "-temp") == 0){ + theTempTable = true; + }else if (strcmp(argv[i], "-noverify") == 0){ + VerifyFlag = false ; + }else if (theErrorData.parseCmdLineArg(argv, i) == true){ + ; //empty, updated in errorArg(..) + }else if (strcmp(argv[i], "-verify") == 0){ + VerifyFlag = true ; +#ifdef CEBIT_STAT + }else if (strcmp(argv[i], "-statserv") == 0){ + if (! (argc > 2)) + return -1; + const char *p = argv[i+1]; + const char *q = strrchr(p, ':'); + if (q == 0) + return -1; + snprintf(statHost, sizeof(statHost), "%.*s", q-p, p); + statPort = atoi(q+1); + statEnable = true; + argc -= 1; + i++; + }else if (strcmp(argv[i], "-statfreq") == 0){ + if (! (argc > 2)) + return -1; + statFreq = atoi(argv[i+1]); + if (statFreq < 1) + return -1; + argc -= 1; + i++; +#endif + }else{ + return -1; + } + argc -= 1; + i++; + } +#ifdef USE_MYSQL + if (n_sockets == 0) { + n_sockets = 1; + sockets[0] = 3306; + } +#endif + return 0; +} + +static void sleepBeforeStartingTest(int seconds){ + if (seconds > 0){ + ndbout << "Sleeping(" <getDictionary()->createTable(tmpTable) == -1){ + return -1; + } + ndbout << "done" << endl; + } + + return 0; +} + + +static void input_error(){ + ndbout << endl << "Invalid argument!" << endl; + ndbout << endl << "Arguments:" << endl; + ndbout << " -t Number of threads to start, default 1" << endl; + ndbout << " -o Number of operations per loop, default 500" << endl; + ndbout << " -l Number of loops to run, default 1, 0=infinite" << endl; + ndbout << " -a Number of attributes, default 25" << endl; + ndbout << " -c Number of tables, default 1" << endl; + ndbout << " -s Size of each attribute, default 1 (Primary Key is always of size 1," << endl; + ndbout << " independent of this value)" << endl; + ndbout << " -lkn Number of long primary keys, default 1" << endl; + ndbout << " -lks Size of each long primary key, default 1" << endl; + + ndbout << " -simple Use simple read to read from database" << endl; + ndbout << " -dirty Use dirty read to read from database" << endl; + ndbout << " -write Use writeTuple in insert and update" << endl; + ndbout << " -stdtables Use standard table names" << endl; + ndbout << " -no_table_create Don't create tables in db" << endl; + ndbout << " -sleep Sleep a number of seconds before running the test, this" << endl; + ndbout << " can be used so that another flexBench have time to create tables" << endl; + ndbout << " -temp Use tables without logging" << endl; + ndbout << " -verify Verify inserts, updates and deletes" << endl ; + ndbout << " -use_ndb Use NDB API (otherwise use mysql client)" << endl ; + ndbout << " -pool_size Number of Ndb objects in pool" << endl ; + theErrorData.printCmdLineArgs(ndbout); + ndbout << endl <<"Returns:" << endl; + ndbout << "\t 0 - Test passed" << endl; + ndbout << "\t 1 - Test failed" << endl; + ndbout << "\t 2 - Invalid arguments" << endl << endl; +} + +// vim: set sw=2: diff --git a/ndb/test/ndbapi/flex_bench_mysql/Makefile b/ndb/test/ndbapi/flex_bench_mysql/Makefile deleted file mode 100644 index d2608526cae..00000000000 --- a/ndb/test/ndbapi/flex_bench_mysql/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := flex_bench_mysql - -# Source files of non-templated classes (.C files) -SOURCES = flex_bench_mysql.cpp - -CCFLAGS_LOC += -I$(call fixpath,$(NDB_TOP)/../include) -BIN_TARGET_LIBS_DIRS += $(NDB_TOP)/../libmysql_r/.libs -BIN_TARGET_LIBS += z mysqlclient_r - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/test/ndbapi/flex_bench_mysql/flex_bench_mysql.cpp b/ndb/test/ndbapi/flex_bench_mysql/flex_bench_mysql.cpp deleted file mode 100644 index 7cc883ab3e6..00000000000 --- a/ndb/test/ndbapi/flex_bench_mysql/flex_bench_mysql.cpp +++ /dev/null @@ -1,1749 +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 */ - - -/* *************************************************** -FLEXBENCH -Perform benchmark of insert, update and delete transactions - -Arguments: - -t Number of threads to start, default 1 - -o Number of operations per loop, default 500 - -l Number of loops to run, default 1, 0=infinite - -a Number of attributes, default 25 - -c Number of tables, default 1 - -s Size of each attribute, default 1 (Primary Key is always of size 1, - independent of this value) - -lkn Number of long primary keys, default 1 - -lks Size of each long primary key, default 1 - -simple Use simple read to read from database - -dirty Use dirty read to read from database - -write Use writeTuple in insert and update - -stdtables Use standard table names - -no_table_create Don't create tables in db - -sleep Sleep a number of seconds before running the test, this - can be used so that another flexBench have time to create tables - -temp Use tables without logging - -verify Verify inserts, updates and deletes - -use_ndb Use NDB API, otherwise use mysql client -#ifdef CEBIT_STAT - -statserv host:port statistics server to report to - -statfreq ops report every ops operations (default 100) -#endif - Returns: - 0 - Test passed - 1 - Test failed - 2 - Invalid arguments - -* *************************************************** */ - -#define USE_MYSQL -#ifdef USE_MYSQL -#include -#endif - -#include "NdbApi.hpp" - -#include -#include -#include -#include -#include -#include -#include - -#include - -#define MAXSTRLEN 16 -#define MAXATTR 64 -#define MAXTABLES 128 -#define MAXATTRSIZE 1000 -#define MAXNOLONGKEY 16 // Max number of long keys. -#define MAXLONGKEYTOTALSIZE 1023 // words = 4092 bytes - -extern "C" { static void* flexBenchThread(void*); } -static int readArguments(int argc, const char** argv); -#ifdef USE_MYSQL -static int createTables(MYSQL*); -static int dropTables(MYSQL*); -#endif -static int createTables(Ndb*); -static void sleepBeforeStartingTest(int seconds); -static void input_error(); - -enum StartType { - stIdle, - stInsert, - stVerify, - stRead, - stUpdate, - stDelete, - stTryDelete, - stVerifyDelete, - stStop -}; - -struct ThreadData -{ - int threadNo; - NdbThread* threadLife; - int threadReady; - StartType threadStart; - int threadResult; -}; - -static int tNodeId = 0 ; -static char tableName[MAXTABLES][MAXSTRLEN+1]; -static char attrName[MAXATTR][MAXSTRLEN+1]; -static char** longKeyAttrName; - -// Program Parameters -static int tNoOfLoops = 1; -static int tAttributeSize = 1; -static unsigned int tNoOfThreads = 1; -static unsigned int tNoOfTables = 1; -static unsigned int tNoOfAttributes = 25; -static unsigned int tNoOfOperations = 500; -static unsigned int tSleepTime = 0; -static unsigned int tNoOfLongPK = 1; -static unsigned int tSizeOfLongPK = 1; -static unsigned int t_instances = 1; - -//Program Flags -static int theSimpleFlag = 0; -static int theDirtyFlag = 0; -static int theWriteFlag = 0; -static int theStdTableNameFlag = 0; -static int theTableCreateFlag = 0; -static bool theTempTable = false; -static bool VerifyFlag = true; -static bool useLongKeys = false; -static bool verbose = false; -#ifdef USE_MYSQL -static bool use_ndb = false; -static int engine_id = 0; -static int sockets[16]; -static int n_sockets = 0; -static char* engine[] = - { - " ENGINE = NDBCLUSTER ", // use default engine - " ENGINE = MEMORY ", - " ENGINE = MYISAM ", - " ENGINE = INNODB " - }; -#else -static bool use_ndb = true; -#endif - -static ErrorData theErrorData; // Part of flexBench-program - -#define START_TIMER { NdbTimer timer; timer.doStart(); -#define STOP_TIMER timer.doStop(); -#define PRINT_TIMER(text, trans, opertrans) timer.printTransactionStatistics(text, trans, opertrans); }; - -#include - -#ifdef CEBIT_STAT -#include -static bool statEnable = false; -static char statHost[100]; -static int statFreq = 100; -static int statPort = 0; -static int statSock = -1; -static enum { statError = -1, statClosed, statOpen } statState; -static NdbMutex statMutex = NDB_MUTEX_INITIALIZER; -#endif - -//------------------------------------------------------------------- -// Statistical Reporting routines -//------------------------------------------------------------------- -#ifdef CEBIT_STAT -// Experimental client-side statistic for CeBIT - -static void -statReport(enum StartType st, int ops) -{ - if (!statEnable) - return; - if (NdbMutex_Lock(&statMutex) < 0) { - if (statState != statError) { - ndbout_c("stat: lock mutex failed: %s", strerror(errno)); - statState = statError; - } - return; - } - static int nodeid; - // open connection - if (statState != statOpen) { - char *p = getenv("NDB_NODEID"); // ndbnet sets NDB_NODEID - nodeid = p == 0 ? 0 : atoi(p); - if ((statSock = socket(PF_INET, SOCK_STREAM, 0)) < 0) { - if (statState != statError) { - ndbout_c("stat: create socket failed: %s", strerror(errno)); - statState = statError; - } - (void)NdbMutex_Unlock(&statMutex); - return; - } - struct sockaddr_in saddr; - memset(&saddr, 0, sizeof(saddr)); - saddr.sin_family = AF_INET; - saddr.sin_port = htons(statPort); - if (Ndb_getInAddr(&saddr.sin_addr, statHost) < 0) { - if (statState != statError) { - ndbout_c("stat: host %s not found", statHost); - statState = statError; - } - (void)close(statSock); - (void)NdbMutex_Unlock(&statMutex); - return; - } - if (connect(statSock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { - if (statState != statError) { - ndbout_c("stat: connect failed: %s", strerror(errno)); - statState = statError; - } - (void)close(statSock); - (void)NdbMutex_Unlock(&statMutex); - return; - } - statState = statOpen; - ndbout_c("stat: connection to %s:%d opened", statHost, (int)statPort); - } - const char *text; - switch (st) { - case stInsert: - text = "insert"; - break; - case stVerify: - text = "verify"; - break; - case stRead: - text = "read"; - break; - case stUpdate: - text = "update"; - break; - case stDelete: - text = "delete"; - break; - case stVerifyDelete: - text = "verifydelete"; - break; - default: - text = "unknown"; - break; - } - char buf[100]; - sprintf(buf, "%d %s %d\n", nodeid, text, ops); - int len = strlen(buf); - // assume SIGPIPE already ignored - if (write(statSock, buf, len) != len) { - if (statState != statError) { - ndbout_c("stat: write failed: %s", strerror(errno)); - statState = statError; - } - (void)close(statSock); - (void)NdbMutex_Unlock(&statMutex); - return; - } - (void)NdbMutex_Unlock(&statMutex); -} -#endif // CEBIT_STAT - -static void -resetThreads(ThreadData* pt){ - for (unsigned int i = 0; i < tNoOfThreads; i++){ - pt[i].threadReady = 0; - pt[i].threadResult = 0; - pt[i].threadStart = stIdle; - } -} - -static int -checkThreadResults(ThreadData* pt){ - for (unsigned int i = 0; i < tNoOfThreads; i++){ - if(pt[i].threadResult != 0){ - ndbout_c("Thread%d reported fatal error %d", i, pt[i].threadResult); - return -1; - } - } - return 0; -} - -static -void -waitForThreads(ThreadData* pt) -{ - int cont = 1; - while (cont){ - NdbSleep_MilliSleep(100); - cont = 0; - for (unsigned int i = 0; i < tNoOfThreads; i++){ - if (pt[i].threadReady == 0) - cont = 1; - } - } -} - -static void -tellThreads(ThreadData* pt, StartType what) -{ - for (unsigned int i = 0; i < tNoOfThreads; i++) - pt[i].threadStart = what; -} - -NDB_COMMAND(flexBench, "flexBench", "flexBench", "flexbench", 65535) -{ - ThreadData* pThreadsData; - int tLoops = 0; - int returnValue = NDBT_OK; - if (readArguments(argc, argv) != 0){ - input_error(); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - NdbAutoPtr p10; - if(useLongKeys){ - int e1 = sizeof(char*) * tNoOfLongPK; - int e2_1 = strlen("KEYATTR ") + 1; - int e2 = e2_1 * tNoOfLongPK; - char *tmp = (char *) malloc(e1 + e2); - p10.reset(tmp); - longKeyAttrName = (char **) tmp; - tmp += e1; - for (Uint32 i = 0; i < tNoOfLongPK; i++) { - // longKeyAttrName[i] = (char *) malloc(strlen("KEYATTR ") + 1); - longKeyAttrName[i] = tmp; - tmp += e2_1; - memset(longKeyAttrName[i], 0, e2_1); - sprintf(longKeyAttrName[i], "KEYATTR%i", i); - } - } - - NdbAutoObjArrayPtr - p12( pThreadsData = new ThreadData[tNoOfThreads] ); - - - ndbout << endl << "FLEXBENCH - Starting normal mode" << endl; - ndbout << "Perform benchmark of insert, update and delete transactions"<< endl; - ndbout << " " << tNoOfThreads << " thread(s) " << endl; - ndbout << " " << tNoOfLoops << " iterations " << endl; - ndbout << " " << tNoOfTables << " table(s) and " << 1 << " operation(s) per transaction " <getNodeId(); - ndbout << " NdbAPI node with id = " << tNodeId << endl; - ndbout << endl; - - ndbout << "Waiting for ndb to become ready..." <waitUntilReady(2000) != 0){ - ndbout << "NDB is not ready" << endl; - ndbout << "Benchmark failed!" << endl; - returnValue = NDBT_FAILED; - } - if(returnValue == NDBT_OK){ - if (createTables(pNdb) != 0){ - returnValue = NDBT_FAILED; - } - } - return_ndb_object(pNdb, ndb_id); - } - } - } - if(returnValue == NDBT_OK){ - - sleepBeforeStartingTest(tSleepTime); - - /**************************************************************** - * Create threads. * - ****************************************************************/ - resetThreads(pThreadsData); - - for (unsigned int i = 0; i < tNoOfThreads; i++){ - pThreadsData[i].threadNo = i; - pThreadsData[i].threadLife = NdbThread_Create(flexBenchThread, - (void**)&pThreadsData[i], - 32768, - "flexBenchThread", - NDB_THREAD_PRIO_LOW); - } - - waitForThreads(pThreadsData); - - ndbout << endl << "All threads started" << endl << endl; - - /**************************************************************** - * Execute program. * - ****************************************************************/ - - for(;;){ - - int loopCount = tLoops + 1; - ndbout << endl << "Loop # " << loopCount << endl << endl; - - /**************************************************************** - * Perform inserts. * - ****************************************************************/ - // Reset and start timer - START_TIMER; - // Give insert-command to all threads - resetThreads(pThreadsData); - tellThreads(pThreadsData, stInsert); - waitForThreads(pThreadsData); - if (checkThreadResults(pThreadsData) != 0){ - ndbout << "Error: Threads failed in performing insert" << endl; - returnValue = NDBT_FAILED; - break; - } - // stop timer and print results. - STOP_TIMER; - PRINT_TIMER("insert", tNoOfOperations*tNoOfThreads, tNoOfTables); - /**************************************************************** - * Verify inserts. * - ****************************************************************/ - if (VerifyFlag) { - resetThreads(pThreadsData); - ndbout << "Verifying inserts...\t" ; - tellThreads(pThreadsData, stVerify); - waitForThreads(pThreadsData); - if (checkThreadResults(pThreadsData) != 0){ - ndbout << "Error: Threads failed while verifying inserts" << endl; - returnValue = NDBT_FAILED; - break; - }else{ - ndbout << "\t\tOK" << endl << endl ; - } - } - - /**************************************************************** - * Perform read. * - ****************************************************************/ - // Reset and start timer - START_TIMER; - // Give read-command to all threads - resetThreads(pThreadsData); - tellThreads(pThreadsData, stRead); - waitForThreads(pThreadsData); - if (checkThreadResults(pThreadsData) != 0){ - ndbout << "Error: Threads failed in performing read" << endl; - returnValue = NDBT_FAILED; - break; - } - // stop timer and print results. - STOP_TIMER; - PRINT_TIMER("read", tNoOfOperations*tNoOfThreads, tNoOfTables); - - /**************************************************************** - * Perform update. * - ****************************************************************/ - // Reset and start timer - START_TIMER; - // Give update-command to all threads - resetThreads(pThreadsData); - tellThreads(pThreadsData, stUpdate); - waitForThreads(pThreadsData); - if (checkThreadResults(pThreadsData) != 0){ - ndbout << "Error: Threads failed in performing update" << endl; - returnValue = NDBT_FAILED; - break; - } - // stop timer and print results. - STOP_TIMER; - PRINT_TIMER("update", tNoOfOperations*tNoOfThreads, tNoOfTables); - - /**************************************************************** - * Verify updates. * - ****************************************************************/ - if (VerifyFlag) { - resetThreads(pThreadsData); - ndbout << "Verifying updates...\t" ; - tellThreads(pThreadsData, stVerify); - waitForThreads(pThreadsData); - if (checkThreadResults(pThreadsData) != 0){ - ndbout << "Error: Threads failed while verifying updates" << endl; - returnValue = NDBT_FAILED; - break; - }else{ - ndbout << "\t\tOK" << endl << endl ; - } - } - - /**************************************************************** - * Perform read. * - ****************************************************************/ - // Reset and start timer - START_TIMER; - // Give read-command to all threads - resetThreads(pThreadsData); - tellThreads(pThreadsData, stRead); - waitForThreads(pThreadsData); - if (checkThreadResults(pThreadsData) != 0){ - ndbout << "Error: Threads failed in performing read" << endl; - returnValue = NDBT_FAILED; - break; - } - // stop timer and print results. - STOP_TIMER; - PRINT_TIMER("read", tNoOfOperations*tNoOfThreads, tNoOfTables); - - /**************************************************************** - * Perform delete. * - ****************************************************************/ - // Reset and start timer - START_TIMER; - // Give delete-command to all threads - resetThreads(pThreadsData); - tellThreads(pThreadsData, stDelete); - waitForThreads(pThreadsData); - if (checkThreadResults(pThreadsData) != 0){ - ndbout << "Error: Threads failed in performing delete" << endl; - returnValue = NDBT_FAILED; - break; - } - // stop timer and print results. - STOP_TIMER; - PRINT_TIMER("delete", tNoOfOperations*tNoOfThreads, tNoOfTables); - - /**************************************************************** - * Verify deletes. * - ****************************************************************/ - if (VerifyFlag) { - resetThreads(pThreadsData); - ndbout << "Verifying tuple deletion..." ; - tellThreads(pThreadsData, stVerifyDelete); - waitForThreads(pThreadsData); - if (checkThreadResults(pThreadsData) != 0){ - ndbout << "Error: Threads failed in verifying deletes" << endl; - returnValue = NDBT_FAILED; - break; - }else{ - ndbout << "\t\tOK" << endl << endl ; - } - } - - ndbout << "--------------------------------------------------" << endl; - - tLoops++; - - if ( 0 != tNoOfLoops && tNoOfLoops <= tLoops ) - break; - theErrorData.printErrorCounters(); - } - - resetThreads(pThreadsData); - tellThreads(pThreadsData, stStop); - waitForThreads(pThreadsData); - - void * tmp; - for(Uint32 i = 0; i> 8) & 255); - hash_value = (hash_value << 5) + hash_value + ((h_key >> 16) & 255); - hash_value = (hash_value << 5) + hash_value + ((h_key >> 24) & 255); - } - return hash_value; -} - -// End of warming up phase - - - -static void* flexBenchThread(void* pArg) -{ - ThreadData* pThreadData = (ThreadData*)pArg; - unsigned int threadNo, threadBase; - Ndb* pNdb = NULL ; - Uint32 ndb_id = 0; - NdbConnection *pTrans = NULL ; - NdbOperation** pOps = NULL ; - StartType tType ; - StartType tSaveType ; - NdbRecAttr* tTmp = NULL ; - int* attrValue = NULL ; - int* attrRefValue = NULL ; - int check = 0 ; - int loopCountOps, loopCountTables, loopCountAttributes; - int tAttemptNo = 0; - int tRetryAttempts = 20; - int tResult = 0; - int tSpecialTrans = 0; - int nRefLocalOpOffset = 0 ; - int nReadBuffSize = - tNoOfTables * tNoOfAttributes * sizeof(int) * tAttributeSize ; - int nRefBuffSize = - tNoOfOperations * tNoOfAttributes * sizeof(int) * tAttributeSize ; - unsigned*** longKeyAttrValue = NULL; - - - threadNo = pThreadData->threadNo ; - -#ifdef USE_MYSQL - MYSQL mysql; - int the_socket = sockets[threadNo % n_sockets]; - char the_socket_name[1024]; - //sprintf(the_socket_name, "%s", "/tmp/mysql.sock"); - sprintf(the_socket_name, "%s%u%s", "/tmp/mysql.",the_socket,".sock"); - if (!use_ndb) { - ndbout << the_socket_name << endl; - ndbout << "Thread connecting to MySQL... " << endl; - mysql_init(&mysql); - - if ( mysql_real_connect(&mysql, - "localhost", - "root", - "", - "test", - the_socket, - the_socket_name, - 0) == NULL ) { - ndbout << "failed" << endl; - NdbThread_Exit(0) ; - } - ndbout << "ok" << endl; - - int r; - if (tNoOfTables > 1) - r = mysql_autocommit(&mysql, 0); - else - r = mysql_autocommit(&mysql, 1); - - if (r) { - ndbout << "autocommit on/off failed" << endl; - NdbThread_Exit(0) ; - } - } -#endif - - NdbAutoPtr p00( attrValue= (int*)malloc(nReadBuffSize) ) ; - NdbAutoPtr p01( attrRefValue= (int*)malloc(nRefBuffSize) ); - if (use_ndb) { - pOps = (NdbOperation**)malloc(tNoOfTables*sizeof(NdbOperation*)) ; - } - NdbAutoPtr p02( pOps ); - - if( !attrValue || !attrRefValue || - ( use_ndb && ( !pOps) ) ){ - // Check allocations to make sure we got all the memory we asked for - ndbout << "One or more memory allocations failed when starting thread #"; - ndbout << threadNo << endl ; - ndbout << "Thread #" << threadNo << " will now exit" << endl ; - tResult = 13 ; - NdbThread_Exit(0) ; - } - - if (use_ndb) { - pNdb = get_ndb_object(ndb_id, "test", "def"); - if (pNdb == NULL) { - ndbout << "Failed to get an NDB object" << endl; - ndbout << "Thread #" << threadNo << " will now exit" << endl ; - tResult = 13; - NdbThread_Exit(0) ; - } - pNdb->waitUntilReady(); - return_ndb_object(pNdb, ndb_id); - pNdb = NULL; - } - - // To make sure that two different threads doesn't operate on the same record - // Calculate an "unique" number to use as primary key - threadBase = (threadNo * 2000000) + (tNodeId * 260000000); - - NdbAutoPtr p22; - if(useLongKeys){ - // Allocate and populate the longkey array. - int e1 = sizeof(unsigned**) * tNoOfOperations; - int e2 = sizeof(unsigned*) * tNoOfLongPK * tNoOfOperations; - int e3 = sizeof(unsigned) * tSizeOfLongPK * tNoOfLongPK * tNoOfOperations; - char* tmp; - p22.reset(tmp = (char*)malloc(e1+e2+e3)); - - longKeyAttrValue = (unsigned ***) tmp; - tmp += e1; - for (Uint32 n = 0; n < tNoOfOperations; n++) { - longKeyAttrValue[n] = (unsigned **) tmp; - tmp += sizeof(unsigned*) * tNoOfLongPK; - } - - for (Uint32 n = 0; n < tNoOfOperations; n++){ - for (Uint32 i = 0; i < tNoOfLongPK ; i++) { - longKeyAttrValue[n][i] = (unsigned *) tmp; - tmp += sizeof(unsigned) * tSizeOfLongPK; - memset(longKeyAttrValue[n][i], 0, sizeof(unsigned) * tSizeOfLongPK); - for(Uint32 j = 0; j < tSizeOfLongPK; j++) { - // Repeat the unique value to fill up the long key. - longKeyAttrValue[n][i][j] = threadBase + n; - } - } - } - } - - int nRefOpOffset = 0 ; - //Assign reference attribute values to memory - for(Uint32 ops = 1 ; ops < tNoOfOperations ; ops++){ - // Calculate offset value before going into the next loop - nRefOpOffset = tAttributeSize*tNoOfAttributes*(ops-1) ; - for(Uint32 a = 0 ; a < tNoOfAttributes ; a++){ - *(int*)&attrRefValue[nRefOpOffset + tAttributeSize*a] = - (int)(threadBase + ops + a) ; - } - } - -#ifdef CEBIT_STAT - // ops not yet reported - int statOps = 0; -#endif - -#ifdef USE_MYSQL - // temporary buffer to store prepared statement text - char buf[2048]; - MYSQL_STMT** prep_read = NULL; - MYSQL_STMT** prep_delete = NULL; - MYSQL_STMT** prep_update = NULL; - MYSQL_STMT** prep_insert = NULL; - MYSQL_BIND* bind_delete = NULL; - MYSQL_BIND* bind_read = NULL; - MYSQL_BIND* bind_update = NULL; - MYSQL_BIND* bind_insert = NULL; - int* mysql_data = NULL; - - NdbAutoPtr p21; - - if (!use_ndb) { - // data array to which prepared statements are bound - char* tmp; - int e1 = sizeof(int)*tAttributeSize*tNoOfAttributes; - int e2 = sizeof(MYSQL_BIND)*tNoOfAttributes; - int e3 = sizeof(MYSQL_BIND)*tNoOfAttributes; - int e4 = sizeof(MYSQL_BIND)*tNoOfAttributes; - int e5 = sizeof(MYSQL_BIND)*1; - int e6 = sizeof(MYSQL_STMT*)*tNoOfTables; - int e7 = sizeof(MYSQL_STMT*)*tNoOfTables; - int e8 = sizeof(MYSQL_STMT*)*tNoOfTables; - int e9 = sizeof(MYSQL_STMT*)*tNoOfTables; - p21.reset(tmp = (char*)malloc(e1+e2+e3+e4+e5+e6+e7+e8+e9)); - - mysql_data = (int*)tmp; tmp += e1; - bind_insert = (MYSQL_BIND*)tmp; tmp += e2; - bind_update = (MYSQL_BIND*)tmp; tmp += e3; - bind_read = (MYSQL_BIND*)tmp; tmp += e4; - bind_delete = (MYSQL_BIND*)tmp; tmp += e5; - prep_insert = (MYSQL_STMT**)tmp; tmp += e6; - prep_update = (MYSQL_STMT**)tmp; tmp += e7; - prep_read = (MYSQL_STMT**)tmp; tmp += e8; - prep_delete = (MYSQL_STMT**)tmp; - - for (Uint32 ca = 0; ca < tNoOfAttributes; ca++){ - MYSQL_BIND& bi = bind_insert[ca]; - bi.buffer_type = MYSQL_TYPE_LONG; - bi.buffer = (char*)&mysql_data[ca*tAttributeSize]; - bi.buffer_length = 0; - bi.length = NULL; - bi.is_null = NULL; - }//for - - for (Uint32 ca = 0; ca < tNoOfAttributes; ca++){ - MYSQL_BIND& bi = bind_update[ca]; - bi.buffer_type = MYSQL_TYPE_LONG; - if ( ca == tNoOfAttributes-1 ) // the primary key comes last in statement - bi.buffer = (char*)&mysql_data[0]; - else - bi.buffer = (char*)&mysql_data[(ca+1)*tAttributeSize]; - bi.buffer_length = 0; - bi.length = NULL; - bi.is_null = NULL; - }//for - - for (Uint32 ca = 0; ca < tNoOfAttributes; ca++){ - MYSQL_BIND& bi = bind_read[ca]; - bi.buffer_type = MYSQL_TYPE_LONG; - bi.buffer = (char*)&mysql_data[ca*tAttributeSize]; - bi.buffer_length = 4; - bi.length = NULL; - bi.is_null = NULL; - }//for - - for (Uint32 ca = 0; ca < 1; ca++){ - MYSQL_BIND& bi = bind_delete[ca]; - bi.buffer_type = MYSQL_TYPE_LONG; - bi.buffer = (char*)&mysql_data[ca*tAttributeSize]; - bi.buffer_length = 0; - bi.length = NULL; - bi.is_null = NULL; - }//for - - for (Uint32 i = 0; i < tNoOfTables; i++) { - int pos = 0; - pos += sprintf(buf+pos, "%s%s%s", - "INSERT INTO ", - tableName[i], - " VALUES("); - pos += sprintf(buf+pos, "%s", "?"); - for (Uint32 j = 1; j < tNoOfAttributes; j++) { - pos += sprintf(buf+pos, "%s", ",?"); - } - pos += sprintf(buf+pos, "%s", ")"); - if (verbose) - ndbout << buf << endl; - prep_insert[i] = mysql_prepare(&mysql, buf, pos); - if (prep_insert[i] == 0) { - ndbout << "mysql_prepare: " << mysql_error(&mysql) << endl; - NdbThread_Exit(0) ; - } - if (mysql_bind_param(prep_insert[i], bind_insert)) { - ndbout << "mysql_bind_param: " << mysql_error(&mysql) << endl; - NdbThread_Exit(0) ; - } - } - - for (Uint32 i = 0; i < tNoOfTables; i++) { - int pos = 0; - pos += sprintf(buf+pos, "%s%s%s", - "UPDATE ", - tableName[i], - " SET "); - for (Uint32 j = 1; j < tNoOfAttributes; j++) { - if (j != 1) - pos += sprintf(buf+pos, "%s", ","); - pos += sprintf(buf+pos, "%s%s", attrName[j],"=?"); - } - pos += sprintf(buf+pos, "%s%s%s", " WHERE ", attrName[0], "=?"); - - if (verbose) - ndbout << buf << endl; - prep_update[i] = mysql_prepare(&mysql, buf, pos); - if (prep_update[i] == 0) { - ndbout << "mysql_prepare: " << mysql_error(&mysql) << endl; - NdbThread_Exit(0) ; - } - if (mysql_bind_param(prep_update[i], bind_update)) { - ndbout << "mysql_bind_param: " << mysql_error(&mysql) << endl; - NdbThread_Exit(0) ; - } - } - - for (Uint32 i = 0; i < tNoOfTables; i++) { - int pos = 0; - pos += sprintf(buf+pos, "%s", "SELECT "); - for (Uint32 j = 1; j < tNoOfAttributes; j++) { - if (j != 1) - pos += sprintf(buf+pos, "%s", ","); - pos += sprintf(buf+pos, "%s", attrName[j]); - } - pos += sprintf(buf+pos, "%s%s%s%s%s", - " FROM ", - tableName[i], - " WHERE ", - attrName[0], - "=?"); - if (verbose) - ndbout << buf << endl; - prep_read[i] = mysql_prepare(&mysql, buf, pos); - if (prep_read[i] == 0) { - ndbout << "mysql_prepare: " << mysql_error(&mysql) << endl; - NdbThread_Exit(0) ; - } - if (mysql_bind_param(prep_read[i], bind_read)) { - ndbout << "mysql_bind_param: " << mysql_error(&mysql) << endl; - NdbThread_Exit(0) ; - } - if (mysql_bind_result(prep_read[i], &bind_read[1])) { - ndbout << "mysql_bind_result: " << mysql_error(&mysql) << endl; - NdbThread_Exit(0) ; - } - } - - for (Uint32 i = 0; i < tNoOfTables; i++) { - int pos = 0; - pos += sprintf(buf+pos, "%s%s%s%s%s", - "DELETE FROM ", - tableName[i], - " WHERE ", - attrName[0], - "=?"); - if (verbose) - ndbout << buf << endl; - prep_delete[i] = mysql_prepare(&mysql, buf, pos); - if (prep_delete[i] == 0) { - ndbout << "mysql_prepare: " << mysql_error(&mysql) << endl; - NdbThread_Exit(0) ; - } - if (mysql_bind_param(prep_delete[i], bind_delete)) { - ndbout << "mysql_bind_param: " << mysql_error(&mysql) << endl; - NdbThread_Exit(0) ; - } - } - } -#endif - - for (;;) { - pThreadData->threadResult = tResult; // Report error to main thread, - // normally tResult is set to 0 - pThreadData->threadReady = 1; - - while (pThreadData->threadStart == stIdle){ - NdbSleep_MilliSleep(100); - }//while - - // Check if signal to exit is received - if (pThreadData->threadStart == stStop){ - pThreadData->threadReady = 1; - // ndbout_c("Thread%d is stopping", threadNo); - // In order to stop this thread, the main thread has signaled - // stStop, break out of the for loop so that destructors - // and the proper exit functions are called - break; - }//if - - tType = pThreadData->threadStart; - tSaveType = tType; - pThreadData->threadStart = stIdle; - - // Start transaction, type of transaction - // is received in the array ThreadStart - loopCountOps = tNoOfOperations; - loopCountTables = tNoOfTables; - loopCountAttributes = tNoOfAttributes; - for (int count = 1; count < loopCountOps && tResult == 0;){ - - if (use_ndb) { - pNdb = get_ndb_object(ndb_id, "test", "def"); - if (pNdb == NULL) { - ndbout << "Could not get Ndb object in thread" << threadNo; - ndbout << endl; - tResult = 1; //Indicate fatal error - break; - } - pTrans = pNdb->startTransaction(); - if (pTrans == NULL) { - // This is a fatal error, abort program - ndbout << "Could not start transaction in thread" << threadNo; - ndbout << endl; - ndbout << pNdb->getNdbError() << endl; - tResult = 1; // Indicate fatal error - break; // Break out of for loop - } - } - - // Calculate the current operation offset in the reference array - nRefLocalOpOffset = tAttributeSize*tNoOfAttributes*(count - 1) ; - int* tmpAttrRefValue = attrRefValue + nRefLocalOpOffset; - - for (int countTables = 0; - countTables < loopCountTables && tResult == 0; - countTables++) { - - int nTableOffset = tAttributeSize * - loopCountAttributes * - countTables ; - - int* tmpAttrValue = attrValue + nTableOffset; - - if (use_ndb) { - pOps[countTables] = pTrans->getNdbOperation(tableName[countTables]); - if (pOps[countTables] == NULL) { - // This is a fatal error, abort program - ndbout << "getNdbOperation: " << pTrans->getNdbError(); - tResult = 2; // Indicate fatal error - break; - }//if - - switch (tType) { - case stInsert: // Insert case - if (theWriteFlag == 1 && theDirtyFlag == 1) - pOps[countTables]->dirtyWrite(); - else if (theWriteFlag == 1) - pOps[countTables]->writeTuple(); - else - pOps[countTables]->insertTuple(); - break; - case stRead: // Read Case - if (theSimpleFlag == 1) - pOps[countTables]->simpleRead(); - else if (theDirtyFlag == 1) - pOps[countTables]->dirtyRead(); - else - pOps[countTables]->readTuple(); - break; - case stUpdate: // Update Case - if (theWriteFlag == 1 && theDirtyFlag == 1) - pOps[countTables]->dirtyWrite(); - else if (theWriteFlag == 1) - pOps[countTables]->writeTuple(); - else if (theDirtyFlag == 1) - pOps[countTables]->dirtyUpdate(); - else - pOps[countTables]->updateTuple(); - break; - case stDelete: // Delete Case - pOps[countTables]->deleteTuple(); - break; - case stVerify: - pOps[countTables]->readTuple(); - break; - case stVerifyDelete: - pOps[countTables]->readTuple(); - break; - default: - assert(false); - }//switch - - if(useLongKeys){ - // Loop the equal call so the complete key is send to the kernel. - for(Uint32 i = 0; i < tNoOfLongPK; i++) - pOps[countTables]->equal(longKeyAttrName[i], - (char *)longKeyAttrValue[count - 1][i], - tSizeOfLongPK*4); - } - else - pOps[countTables]->equal((char*)attrName[0], - (char*)&tmpAttrRefValue[0]); - - if (tType == stInsert) { - for (int ca = 1; ca < loopCountAttributes; ca++){ - pOps[countTables]->setValue((char*)attrName[ca], - (char*)&tmpAttrRefValue[tAttributeSize*ca]); - }//for - } else if (tType == stUpdate) { - for (int ca = 1; ca < loopCountAttributes; ca++){ - int* tmp = (int*)&tmpAttrRefValue[tAttributeSize*ca]; - if (countTables == 0) - (*tmp)++; - pOps[countTables]->setValue((char*)attrName[ca],(char*)tmp); - }//for - } else if (tType == stRead || stVerify == tType) { - for (int ca = 1; ca < loopCountAttributes; ca++) { - tTmp = - pOps[countTables]->getValue((char*)attrName[ca], - (char*)&tmpAttrValue[tAttributeSize*ca]); - }//for - } else if (stVerifyDelete == tType) { - if(useLongKeys){ - tTmp = pOps[countTables]->getValue(longKeyAttrName[0], - (char*)&tmpAttrValue[0]); - } else { - tTmp = pOps[countTables]->getValue((char*)attrName[0], - (char*)&tmpAttrValue[0]); - } - }//if - } else { // !use_ndb -#ifndef USE_MYSQL - assert(false); -#else - switch (tType) - { - case stInsert: - for (int ca = 0; ca < loopCountAttributes; ca++){ - mysql_data[ca] = tmpAttrRefValue[tAttributeSize*ca]; - }//for - if (mysql_execute(prep_insert[countTables])) { - ndbout << tableName[countTables]; - ndbout << " mysql_execute: " << mysql_error(&mysql) << endl; - tResult = 1 ; - } - break; - case stUpdate: // Update Case - mysql_data[0] = tmpAttrRefValue[0]; - for (int ca = 1; ca < loopCountAttributes; ca++){ - int* tmp = (int*)&tmpAttrRefValue[tAttributeSize*ca]; - if (countTables == 0) - (*tmp)++; - mysql_data[ca] = *tmp; - }//for - if (mysql_execute(prep_update[countTables])) { - ndbout << tableName[countTables]; - ndbout << " mysql_execute: " << mysql_error(&mysql) << endl; - tResult = 2 ; - } - break; - case stVerify: - case stRead: // Read Case - mysql_data[0] = tmpAttrRefValue[0]; - if (mysql_execute(prep_read[countTables])) { - ndbout << tableName[countTables]; - ndbout << " mysql_execute: " << mysql_error(&mysql) << endl; - tResult = 3 ; - break; - } - if (mysql_stmt_store_result(prep_read[countTables])) { - ndbout << tableName[countTables]; - ndbout << " mysql_stmt_store_result: " - << mysql_error(&mysql) << endl; - tResult = 4 ; - break; - } - { - int rows= 0; - int r; - while ( (r= mysql_fetch(prep_read[countTables])) == 0 ){ - rows++; - } - if ( r == 1 ) { - ndbout << tableName[countTables]; - ndbout << " mysql_fetch: " << mysql_error(&mysql) << endl; - tResult = 5 ; - break; - } - if ( rows != 1 ) { - ndbout << tableName[countTables]; - ndbout << " mysql_fetch: rows = " << rows << endl; - tResult = 6 ; - break; - } - } - { - for (int ca = 1; ca < loopCountAttributes; ca++) { - tmpAttrValue[tAttributeSize*ca] = mysql_data[ca]; - } - } - break; - case stDelete: // Delete Case - mysql_data[0] = tmpAttrRefValue[0]; - if (mysql_execute(prep_delete[countTables])) { - ndbout << tableName[countTables]; - ndbout << " mysql_execute: " << mysql_error(&mysql) << endl; - tResult = 7 ; - break; - } - break; - case stVerifyDelete: - { - sprintf(buf, "%s%s%s", - "SELECT COUNT(*) FROM ",tableName[countTables],";"); - if (mysql_query(&mysql, buf)) { - ndbout << buf << endl; - ndbout << "Error: " << mysql_error(&mysql) << endl; - tResult = 8 ; - break; - } - MYSQL_RES *res = mysql_store_result(&mysql); - if ( res == NULL ) { - ndbout << "mysql_store_result: " - << mysql_error(&mysql) << endl - << "errno: " << mysql_errno(&mysql) << endl; - tResult = 9 ; - break; - } - int num_fields = mysql_num_fields(res); - int num_rows = mysql_num_rows(res); - if ( num_rows != 1 || num_fields != 1 ) { - ndbout << tableName[countTables]; - ndbout << " mysql_store_result: num_rows = " << num_rows - << " num_fields = " << num_fields << endl; - tResult = 10 ; - break; - } - MYSQL_ROW row = mysql_fetch_row(res); - if ( row == NULL ) { - ndbout << "mysql_fetch_row: " - << mysql_error(&mysql) << endl; - tResult = 11 ; - break; - } - if ( *(char*)row[0] != '0' ) { - ndbout << tableName[countTables]; - ndbout << " mysql_fetch_row: value = " - << (char*)(row[0]) << endl; - tResult = 12 ; - break; - } - mysql_free_result(res); - } - break; - default: - assert(false); - } -#endif - } - }//for Tables loop - - if (tResult != 0) - break; - - if (use_ndb){ - check = pTrans->execute(Commit); - } else { -#ifdef USE_MYSQL - if (tNoOfTables > 1) - if (mysql_commit(&mysql)) { - ndbout << " mysql_commit: " << mysql_error(&mysql) << endl; - tResult = 13; - } else - check = 0; -#endif - } - - if (use_ndb) { - // Decide what kind of error this is - if ((tSpecialTrans == 1) && - (check == -1)) { -// -------------------------------------------------------------------- -// A special transaction have been executed, change to check = 0 in -// certain situations. -// -------------------------------------------------------------------- - switch (tType) { - case stInsert: // Insert case - if (630 == pTrans->getNdbError().code ) { - check = 0; - ndbout << "Insert with 4007 was successful" << endl; - }//if - break; - case stDelete: // Delete Case - if (626 == pTrans->getNdbError().code ) { - check = 0; - ndbout << "Delete with 4007 was successful" << endl; - }//if - break; - default: - assert(false); - }//switch - }//if - tSpecialTrans = 0; - if (check == -1) { - if ((stVerifyDelete == tType) && - (626 == pTrans->getNdbError().code)) { - // ---------------------------------------------- - // It's good news - the deleted tuple is gone, - // so reset "check" flag - // ---------------------------------------------- - check = 0 ; - } else { - int retCode = - theErrorData.handleErrorCommon(pTrans->getNdbError()); - if (retCode == 1) { - ndbout_c("execute: %d, %d, %s", count, tType, - pTrans->getNdbError().message ); - ndbout_c("Error code = %d", pTrans->getNdbError().code ); - tResult = 20; - } else if (retCode == 2) { - ndbout << "4115 should not happen in flexBench" << endl; - tResult = 20; - } else if (retCode == 3) { -// -------------------------------------------------------------------- -// We are not certain if the transaction was successful or not. -// We must reexecute but might very well find that the transaction -// actually was updated. Updates and Reads are no problem here. Inserts -// will not cause a problem if error code 630 arrives. Deletes will -// not cause a problem if 626 arrives. -// -------------------------------------------------------------------- - if ((tType == stInsert) || (tType == stDelete)) { - tSpecialTrans = 1; - }//if - }//if - }//if - }//if - // Check if retries should be made - if (check == -1 && tResult == 0) { - if (tAttemptNo < tRetryAttempts){ - tAttemptNo++; - } else { -// -------------------------------------------------------------------- -// Too many retries have been made, report error and break out of loop -// -------------------------------------------------------------------- - ndbout << "Thread" << threadNo; - ndbout << ": too many errors reported" << endl; - tResult = 10; - break; - }//if - }//if - } - - if (check == 0){ - // Go to the next record - count++; - tAttemptNo = 0; -#ifdef CEBIT_STAT - // report successful ops - if (statEnable) { - statOps += loopCountTables; - if (statOps >= statFreq) { - statReport(tType, statOps); - statOps = 0; - }//if - }//if -#endif - }//if - - if (stVerify == tType && 0 == check){ - int nTableOffset = 0 ; - for (int a = 1 ; a < loopCountAttributes ; a++){ - for (int tables = 0 ; tables < loopCountTables ; tables++){ - nTableOffset = tables*loopCountAttributes*tAttributeSize; - int ov =*(int*)&attrValue[nTableOffset + tAttributeSize*a]; - int nv =*(int*)&tmpAttrRefValue[tAttributeSize*a]; - if (ov != nv){ - ndbout << "Error in verify "; - ndbout << "pk = " << tmpAttrRefValue[0] << ":" << endl; - ndbout << "attrValue[" << nTableOffset + tAttributeSize*a << "] = " << ov << endl ; - ndbout << "attrRefValue[" << nRefLocalOpOffset + tAttributeSize*a << "]" << nv << endl ; - tResult = 11 ; - break ; - }//if - }//for - }//for - }// if(stVerify ... ) - if (use_ndb) { - pNdb->closeTransaction(pTrans); - return_ndb_object(pNdb, ndb_id); - pNdb = NULL; - } - }// operations loop -#ifdef CEBIT_STAT - // report remaining successful ops - if (statEnable) { - if (statOps > 0) { - statReport(tType, statOps); - statOps = 0; - }//if - }//if -#endif - if (pNdb) { - pNdb->closeTransaction(pTrans); - return_ndb_object(pNdb, ndb_id); - pNdb = NULL; - } - } - -#ifdef USE_MYSQL - if (!use_ndb) { - mysql_close(&mysql); - for (Uint32 i = 0; i < tNoOfTables; i++) { - mysql_stmt_close(prep_insert[i]); - mysql_stmt_close(prep_update[i]); - mysql_stmt_close(prep_delete[i]); - mysql_stmt_close(prep_read[i]); - } - } -#endif - if (use_ndb && pNdb) { - ndbout << "I got here " << endl; - return_ndb_object(pNdb, ndb_id); - } - NdbThread_Exit(0); - return NULL; // Just to keep compiler happy -} - - -static int readArguments(int argc, const char** argv) -{ - - int i = 1; - while (argc > 1){ - if (strcmp(argv[i], "-t") == 0){ - tNoOfThreads = atoi(argv[i+1]); - if ((tNoOfThreads < 1)) - return -1; - argc -= 1; - i++; - }else if (strcmp(argv[i], "-o") == 0){ - tNoOfOperations = atoi(argv[i+1]); - if (tNoOfOperations < 1) - return -1;; - argc -= 1; - i++; - }else if (strcmp(argv[i], "-a") == 0){ - tNoOfAttributes = atoi(argv[i+1]); - if ((tNoOfAttributes < 2) || (tNoOfAttributes > MAXATTR)) - return -1; - argc -= 1; - i++; - }else if (strcmp(argv[i], "-c") == 0){ - tNoOfTables = atoi(argv[i+1]); - if ((tNoOfTables < 1) || (tNoOfTables > MAXTABLES)) - return -1; - argc -= 1; - i++; - }else if (strcmp(argv[i], "-stdtables") == 0){ - theStdTableNameFlag = 1; - }else if (strcmp(argv[i], "-l") == 0){ - tNoOfLoops = atoi(argv[i+1]); - if ((tNoOfLoops < 0) || (tNoOfLoops > 100000)) - return -1; - argc -= 1; - i++; - }else if (strcmp(argv[i], "-pool_size") == 0){ - t_instances = atoi(argv[i+1]); - if ((t_instances < 1) || (t_instances > 240)) - return -1; - argc -= 1; - i++; -#ifdef USE_MYSQL - }else if (strcmp(argv[i], "-engine") == 0){ - engine_id = atoi(argv[i+1]); - if ((engine_id < 0) || (engine_id > 3)) - return -1; - argc -= 1; - i++; - }else if (strcmp(argv[i], "-socket") == 0){ - sockets[n_sockets] = atoi(argv[i+1]); - if (sockets[n_sockets] <= 0) - return -1; - n_sockets++; - argc -= 1; - i++; - }else if (strcmp(argv[i], "-use_ndb") == 0){ - use_ndb = true; -#endif - }else if (strcmp(argv[i], "-s") == 0){ - tAttributeSize = atoi(argv[i+1]); - if ((tAttributeSize < 1) || (tAttributeSize > MAXATTRSIZE)) - return -1; - argc -= 1; - i++; - }else if (strcmp(argv[i], "-lkn") == 0){ - tNoOfLongPK = atoi(argv[i+1]); - useLongKeys = true; - if ((tNoOfLongPK < 1) || (tNoOfLongPK > MAXNOLONGKEY) || - (tNoOfLongPK * tSizeOfLongPK) > MAXLONGKEYTOTALSIZE){ - ndbout << "Argument -lkn is not in the proper range." << endl; - return -1; - } - argc -= 1; - i++; - }else if (strcmp(argv[i], "-lks") == 0){ - tSizeOfLongPK = atoi(argv[i+1]); - useLongKeys = true; - if ((tSizeOfLongPK < 1) || (tNoOfLongPK * tSizeOfLongPK) > MAXLONGKEYTOTALSIZE){ - ndbout << "Argument -lks is not in the proper range 1 to " << - MAXLONGKEYTOTALSIZE << endl; - return -1; - } - argc -= 1; - i++; - }else if (strcmp(argv[i], "-simple") == 0){ - theSimpleFlag = 1; - }else if (strcmp(argv[i], "-write") == 0){ - theWriteFlag = 1; - }else if (strcmp(argv[i], "-dirty") == 0){ - theDirtyFlag = 1; - }else if (strcmp(argv[i], "-sleep") == 0){ - tSleepTime = atoi(argv[i+1]); - if ((tSleepTime < 1) || (tSleepTime > 3600)) - return -1; - argc -= 1; - i++; - }else if (strcmp(argv[i], "-no_table_create") == 0){ - theTableCreateFlag = 1; - }else if (strcmp(argv[i], "-temp") == 0){ - theTempTable = true; - }else if (strcmp(argv[i], "-noverify") == 0){ - VerifyFlag = false ; - }else if (theErrorData.parseCmdLineArg(argv, i) == true){ - ; //empty, updated in errorArg(..) - }else if (strcmp(argv[i], "-verify") == 0){ - VerifyFlag = true ; -#ifdef CEBIT_STAT - }else if (strcmp(argv[i], "-statserv") == 0){ - if (! (argc > 2)) - return -1; - const char *p = argv[i+1]; - const char *q = strrchr(p, ':'); - if (q == 0) - return -1; - snprintf(statHost, sizeof(statHost), "%.*s", q-p, p); - statPort = atoi(q+1); - statEnable = true; - argc -= 1; - i++; - }else if (strcmp(argv[i], "-statfreq") == 0){ - if (! (argc > 2)) - return -1; - statFreq = atoi(argv[i+1]); - if (statFreq < 1) - return -1; - argc -= 1; - i++; -#endif - }else{ - return -1; - } - argc -= 1; - i++; - } -#ifdef USE_MYSQL - if (n_sockets == 0) { - n_sockets = 1; - sockets[0] = 3306; - } -#endif - return 0; -} - -static void sleepBeforeStartingTest(int seconds){ - if (seconds > 0){ - ndbout << "Sleeping(" <getDictionary()->createTable(tmpTable) == -1){ - return -1; - } - ndbout << "done" << endl; - } - - return 0; -} - - -static void input_error(){ - ndbout << endl << "Invalid argument!" << endl; - ndbout << endl << "Arguments:" << endl; - ndbout << " -t Number of threads to start, default 1" << endl; - ndbout << " -o Number of operations per loop, default 500" << endl; - ndbout << " -l Number of loops to run, default 1, 0=infinite" << endl; - ndbout << " -a Number of attributes, default 25" << endl; - ndbout << " -c Number of tables, default 1" << endl; - ndbout << " -s Size of each attribute, default 1 (Primary Key is always of size 1," << endl; - ndbout << " independent of this value)" << endl; - ndbout << " -lkn Number of long primary keys, default 1" << endl; - ndbout << " -lks Size of each long primary key, default 1" << endl; - - ndbout << " -simple Use simple read to read from database" << endl; - ndbout << " -dirty Use dirty read to read from database" << endl; - ndbout << " -write Use writeTuple in insert and update" << endl; - ndbout << " -stdtables Use standard table names" << endl; - ndbout << " -no_table_create Don't create tables in db" << endl; - ndbout << " -sleep Sleep a number of seconds before running the test, this" << endl; - ndbout << " can be used so that another flexBench have time to create tables" << endl; - ndbout << " -temp Use tables without logging" << endl; - ndbout << " -verify Verify inserts, updates and deletes" << endl ; - ndbout << " -use_ndb Use NDB API (otherwise use mysql client)" << endl ; - ndbout << " -pool_size Number of Ndb objects in pool" << endl ; - theErrorData.printCmdLineArgs(ndbout); - ndbout << endl <<"Returns:" << endl; - ndbout << "\t 0 - Test passed" << endl; - ndbout << "\t 1 - Test failed" << endl; - ndbout << "\t 2 - Invalid arguments" << endl << endl; -} - -// vim: set sw=2: diff --git a/ndb/test/ndbapi/index.cpp b/ndb/test/ndbapi/index.cpp new file mode 100644 index 00000000000..508186de529 --- /dev/null +++ b/ndb/test/ndbapi/index.cpp @@ -0,0 +1,997 @@ +/* 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 */ + +/* *************************************************** + INDEX TEST 1 + Test index functionality of NDB + + Arguments: + -T create table + -L include a long attribute in key or index + -2 define primary key with two attributes + -c create index + -p make index unique (include primary key attribute) + -r read using index + -u update using index + -d delete using index + -n do n operations (for -I -r -u -d -R -U -D) + -o (for -I -r -u -d -R -U -D) + -m + + Returns: + 0 - Test passed + -1 - Test failed + 1 - Invalid arguments + * *************************************************** */ + +#include + +#include +#include +#include +#include +#include +#include + +#ifndef MIN +#define MIN(x,y) (((x)<(y))?(x):(y)) +#endif + +#define MAX_NO_PARALLEL_OPERATIONS 100 + +bool testPassed = true; + +static void +error_handler(const NdbError & err) +{ + // Test failed + ndbout << endl << err << endl; + testPassed = false; +} + +static void +error_handler4(int line, const NdbError & err){ + ndbout << endl << "Line " << line << endl; + // Test failed + ndbout << err << endl; + testPassed = false; +} + +static char *longName, *sixtysix, *ninetynine, *hundred; + +static void createTable(Ndb &myNdb, bool storeInACC, bool twoKey, bool longKey) +{ + NdbDictionary::Dictionary* dict = myNdb.getDictionary(); + NdbDictionary::Table table("PERSON"); + //NdbDictionary::Column column(); // Bug + NdbDictionary::Column column; + int res; + + column.setName("NAME"); + column.setPrimaryKey(true); + column.setType(NdbDictionary::Column::Char); + column.setLength((longKey)? + 1024 // 1KB => long key + :12); + column.setNullable(false); + table.addColumn(column); + + if (twoKey) { + column.setName("KEY2"); + column.setPrimaryKey(true); + column.setType(NdbDictionary::Column::Unsigned); + column.setLength(1); + column.setNullable(false); + table.addColumn(column); + } + + column.setName("PNUM1"); + column.setPrimaryKey(false); + column.setType(NdbDictionary::Column::Unsigned); + column.setLength(1); + column.setNullable(false); + table.addColumn(column); + + column.setName("PNUM2"); + column.setPrimaryKey(false); + column.setType(NdbDictionary::Column::Unsigned); + column.setLength(1); + column.setNullable(false); + table.addColumn(column); + + column.setName("PNUM3"); + column.setPrimaryKey(false); + column.setType(NdbDictionary::Column::Unsigned); + column.setLength(1); + column.setNullable(false); + table.addColumn(column); + + column.setName("PNUM4"); + column.setPrimaryKey(false); + column.setType(NdbDictionary::Column::Unsigned); + column.setLength(1); + column.setNullable(false); + table.addColumn(column); + + column.setName("AGE"); + column.setPrimaryKey(false); + column.setType(NdbDictionary::Column::Unsigned); + column.setLength(1); + column.setNullable(false); + table.addColumn(column); + + column.setName("STRING_AGE"); + column.setPrimaryKey(false); + column.setType(NdbDictionary::Column::Char); + column.setLength(1); + column.setLength(256); + column.setNullable(false); + table.addColumn(column); + + if ((res = dict->createTable(table)) == -1) { + error_handler(dict->getNdbError()); + } + else + ndbout << "Created table" << ((longKey)?" with long key":"") <createIndex(index)) == -1) { + error_handler(dict->getNdbError()); + } + after = NdbTick_CurrentMillisecond(); + ndbout << "Created index " << indexName << ", " << after - before << " msec" << endl; + } +} + +static void insertTable(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool oneTrans, bool twoKey, bool longKey) +{ + Uint64 tbefore, tafter, before, after; + NdbConnection *myTrans; + NdbOperation *myOp; + char name[] = "Kalle0000000"; + + tbefore = NdbTick_CurrentMillisecond(); + if (oneTrans) myTrans = myNdb.startTransaction(); + for (unsigned int i = 0; igetNdbOperation("PERSON"); + if (myOp == NULL) + error_handler4(__LINE__, myTrans->getNdbError()); + + myOp->insertTuple(); + sprintf(name, "Kalle%.7i", i); + if (longKey) + memcpy(longName, name, strlen(name)); + if (myOp->equal("NAME", (longKey)?longName:name) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + if (twoKey) + if (myOp->equal("KEY2", i) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + if (myOp->setValue("PNUM1", 17) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + if (myOp->setValue("PNUM2", 18)) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + if (myOp->setValue("PNUM3", 19)) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + if (myOp->setValue("PNUM4", 20)) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + if (myOp->setValue("AGE", ((i % 2) == 0)?66:99) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + if (myOp->setValue("STRING_AGE", ((i % 2) == 0)?sixtysix:ninetynine) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + } + if (noOfOperations == 1) + printf("Trying to insert person %s\n", name); + else + printf("Trying to insert %u persons\n", noOfOperations); + before = NdbTick_CurrentMillisecond(); + if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1) + { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + after = NdbTick_CurrentMillisecond(); + if (noOfOperations == 1) + printf("Inserted person %s, %u msec\n", name, (Uint32) after - before); + else + printf("Inserted %u persons, %u msec\n", noOfOperations, (Uint32) after - before); + if (!oneTrans) myNdb.closeTransaction(myTrans); + } + if (oneTrans) { + if (myTrans->execute( Commit ) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + } + myNdb.closeTransaction(myTrans); + } + tafter = NdbTick_CurrentMillisecond(); + + ndbout << "Inserted "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl; +} + +static void updateTable(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool oneTrans, bool twoKey, bool longKey) +{ + Uint64 tbefore, tafter, before, after; + NdbConnection *myTrans; + NdbOperation *myOp; + char name[] = "Kalle0000000"; + + tbefore = NdbTick_CurrentMillisecond(); + if (oneTrans) myTrans = myNdb.startTransaction(); + for (unsigned int i = 0; igetNdbOperation("PERSON"); + if (myOp == NULL) + error_handler4(__LINE__, myTrans->getNdbError()); + + myOp->updateTuple(); + sprintf(name, "Kalle%.7i", i); + if (longKey) + memcpy(longName, name, strlen(name)); + if (myOp->equal("NAME", (longKey)?longName:name) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + if (twoKey) + if (myOp->equal("KEY2", i) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + if (myOp->setValue("PNUM1", 77) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + if (myOp->setValue("PNUM2", 88)) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + if (myOp->setValue("PNUM4", 99)) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + if (myOp->setValue("AGE", 100) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + if (myOp->setValue("STRING_AGE", hundred) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + } + if (noOfOperations == 1) + printf("Trying to update person %s\n", name); + else + printf("Trying to update %u persons\n", noOfOperations); + before = NdbTick_CurrentMillisecond(); + if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1) + { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + after = NdbTick_CurrentMillisecond(); + if (noOfOperations == 1) + printf("Updated person %s, %u msec\n", name, (Uint32) after - before); + else + printf("Update %u persons, %u msec\n", noOfOperations, (Uint32) after - before); + if (!oneTrans) myNdb.closeTransaction(myTrans); + } + if (oneTrans) { + if (myTrans->execute( Commit ) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + } + myNdb.closeTransaction(myTrans); + } + tafter = NdbTick_CurrentMillisecond(); + + ndbout << "Updated "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl; +} + +static void deleteTable(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool oneTrans, bool twoKey, bool longKey) +{ + Uint64 tbefore, tafter, before, after; + NdbConnection *myTrans; + NdbOperation *myOp; + char name[] = "Kalle0000000"; + + tbefore = NdbTick_CurrentMillisecond(); + if (oneTrans) myTrans = myNdb.startTransaction(); + for (unsigned int i = 0; igetNdbOperation("PERSON"); + if (myOp == NULL) + error_handler4(__LINE__, myTrans->getNdbError()); + + myOp->deleteTuple(); + sprintf(name, "Kalle%.7i", i); + if (longKey) + memcpy(longName, name, strlen(name)); + if (myOp->equal("NAME", (longKey)?longName:name) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + if (twoKey) + if (myOp->equal("KEY2", i) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + } + if (noOfOperations == 1) + printf("Trying to delete person %s\n", name); + else + printf("Trying to delete %u persons\n", noOfOperations); + before = NdbTick_CurrentMillisecond(); + if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1) + { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + after = NdbTick_CurrentMillisecond(); + if (noOfOperations == 1) + printf("Deleted person %s, %u msec\n", name, (Uint32) after - before); + else + printf("Deleted %u persons, %u msec\n", noOfOperations, (Uint32) after - before); + + if (!oneTrans) myNdb.closeTransaction(myTrans); + } + if (oneTrans) { + if (myTrans->execute( Commit ) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + } + myNdb.closeTransaction(myTrans); + } + tafter = NdbTick_CurrentMillisecond(); + + ndbout << "Deleted "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl; +} + +static void readTable(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool oneTrans, bool twoKey, bool longKey) +{ + Uint64 tbefore, tafter, before, after; + NdbConnection *myTrans; + NdbOperation *myOp; + char name[] = "Kalle0000000"; + NdbRecAttr* myRecAttrArr[MAX_NO_PARALLEL_OPERATIONS]; + + tbefore = NdbTick_CurrentMillisecond(); + if (oneTrans) myTrans = myNdb.startTransaction(); + for (unsigned int i = 0; igetNdbOperation("PERSON"); + if (myOp == NULL) + error_handler4(__LINE__, myTrans->getNdbError()); + + myOp->readTuple(); + sprintf(name, "Kalle%.7i", i); + if (longKey) + memcpy(longName, name, strlen(name)); + if (myOp->equal("NAME", (longKey)?longName:name) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + if (twoKey) + if (myOp->equal("KEY2", i) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + myRecAttrArr[j-1] = myOp->getValue("PNUM2", NULL); + } + if (noOfOperations == 1) + printf("Trying to read person %s\n", name); + else + printf("Trying to read %u persons\n", noOfOperations); + before = NdbTick_CurrentMillisecond(); + if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1) + { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + after = NdbTick_CurrentMillisecond(); + if (noOfOperations == 1) + printf("Read person %s, %u msec\n", name, (Uint32) after - before); + else + printf("Read %u persons, %u msec\n", noOfOperations, (Uint32) after - before); + for(unsigned int j = 0; ju_32_value()); + if (!oneTrans) myNdb.closeTransaction(myTrans); + } + if (oneTrans) { + if (myTrans->execute( Commit ) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + } + myNdb.closeTransaction(myTrans); + } + tafter = NdbTick_CurrentMillisecond(); + + ndbout << "Read "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl; +} + +static void readIndex(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool includePrimary, bool oneTrans, bool longKey) +{ + Uint64 tbefore, tafter, before, after; + NdbConnection *myTrans; + NdbIndexOperation *myOp; + char indexName[] = "PNUMINDEX0000"; + char name[] = "Kalle0000000"; + NdbRecAttr* myRecAttrArr[MAX_NO_PARALLEL_OPERATIONS]; + + tbefore = NdbTick_CurrentMillisecond(); + if (oneTrans) myTrans = myNdb.startTransaction(); + for (unsigned int i = 0; igetNdbIndexOperation(indexName, "PERSON"); + if (myOp == NULL) + error_handler4(__LINE__, myTrans->getNdbError()); + + myOp->readTuple(); + if (includePrimary) { + sprintf(name, "Kalle%.7i", i); + if (longKey) + memcpy(longName, name, strlen(name)); + if (myOp->equal("NAME", (longKey)?longName:name) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + } + if (myOp->equal("PNUM1", 17) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + if (myOp->equal("PNUM3", 19) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + myRecAttrArr[j-1] = myOp->getValue("PNUM2", NULL); + } + if (noOfOperations == 1) + printf("Trying to read person %s\n", name); + else + printf("Trying to read %u persons\n", noOfOperations); + before = NdbTick_CurrentMillisecond(); + if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1) + { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + after = NdbTick_CurrentMillisecond(); + if (noOfOperations == 1) + printf("Read person %s, %u msec\n", name, (Uint32) after - before); + else + printf("Read %u persons, %u msec\n", noOfOperations, (Uint32) after - before); + for(unsigned int j = 0; ju_32_value()); + if (!oneTrans) myNdb.closeTransaction(myTrans); + } + if (oneTrans) { + if (myTrans->execute( Commit ) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + } + myNdb.closeTransaction(myTrans); + } + tafter = NdbTick_CurrentMillisecond(); + + ndbout << "Read "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl; +} + +static void updateIndex(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool includePrimary, bool oneTrans, bool longKey) +{ + Uint64 tbefore, tafter, before, after; + NdbConnection *myTrans; + NdbIndexOperation *myOp; + char indexName[] = "PNUMINDEX0000"; + char name[] = "Kalle0000000"; + + tbefore = NdbTick_CurrentMillisecond(); + if (oneTrans) myTrans = myNdb.startTransaction(); + for (unsigned int i = 0; igetNdbIndexOperation(indexName, "PERSON"); + if (myOp == NULL) + error_handler4(__LINE__, myTrans->getNdbError()); + + myOp->updateTuple(); + if (includePrimary) { + sprintf(name, "Kalle%.7i", i); + if (longKey) + memcpy(longName, name, strlen(name)); + if (myOp->equal("NAME", (longKey)?longName:name) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + } + if (myOp->equal("PNUM1", 17) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + if (myOp->equal("PNUM3", 19) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + // Update index itself, should be possible + if (myOp->setValue("PNUM1", 77) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + if (myOp->setValue("PNUM2", 88)) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + if (myOp->setValue("PNUM4", 99)) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + if (myOp->setValue("AGE", 100) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + if (myOp->setValue("STRING_AGE", hundred) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + } + if (noOfOperations == 1) + printf("Trying to update person %s\n", name); + else + printf("Trying to update %u persons\n", noOfOperations); + before = NdbTick_CurrentMillisecond(); + if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1) + { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + after = NdbTick_CurrentMillisecond(); + if (noOfOperations == 1) + printf("Updated person %s, %u msec\n", name, (Uint32) after - before); + else + printf("Updated %u persons, %u msec\n", noOfOperations, (Uint32) after - before); + if (!oneTrans) myNdb.closeTransaction(myTrans); + } + if (oneTrans) { + if (myTrans->execute( Commit ) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + } + myNdb.closeTransaction(myTrans); + } + tafter = NdbTick_CurrentMillisecond(); + + ndbout << "Updated "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl; +} + +static void deleteIndex(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool includePrimary, bool oneTrans, bool longKey) +{ + Uint64 tbefore, tafter, before, after; + NdbConnection *myTrans; + NdbIndexOperation *myOp; + char indexName[] = "PNUMINDEX0000"; + char name[] = "Kalle0000000"; + + tbefore = NdbTick_CurrentMillisecond(); + if (oneTrans) myTrans = myNdb.startTransaction(); + for (unsigned int i = 0; igetNdbIndexOperation(indexName, "PERSON"); + if (myOp == NULL) + error_handler4(__LINE__, myTrans->getNdbError()); + + myOp->deleteTuple(); + if (includePrimary) { + sprintf(name, "Kalle%.7i", i); + if (longKey) + memcpy(longName, name, strlen(name)); + if (myOp->equal("NAME", (longKey)?longName:name) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + } + if (myOp->equal("PNUM1", 17) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + if (myOp->equal("PNUM3", 19) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + } + if (noOfOperations == 1) + printf("Trying to delete person %s\n", name); + else + printf("Trying to delete %u persons\n", noOfOperations); + before = NdbTick_CurrentMillisecond(); + if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1) + { + error_handler4(__LINE__, myTrans->getNdbError()); + myNdb.closeTransaction(myTrans); + break; + } + after = NdbTick_CurrentMillisecond(); + if (noOfOperations == 1) + printf("Deleted person %s, %u msec\n", name, (Uint32) after - before); + else + printf("Deleted %u persons, %u msec\n", noOfOperations, (Uint32) after - before); + if (!oneTrans) myNdb.closeTransaction(myTrans); + } + if (oneTrans) { + if (myTrans->execute( Commit ) == -1) { + error_handler4(__LINE__, myTrans->getNdbError()); + } + myNdb.closeTransaction(myTrans); + } + tafter = NdbTick_CurrentMillisecond(); + + ndbout << "Deleted "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl; +} + +static void dropIndex(Ndb &myNdb, unsigned int noOfIndexes) +{ + for(unsigned int indexNum = 0; indexNum < noOfIndexes; indexNum++) { + char indexName[255]; + sprintf(indexName, "PNUMINDEX%.4u", indexNum); + const Uint64 before = NdbTick_CurrentMillisecond(); + const int retVal = myNdb.getDictionary()->dropIndex(indexName, "PERSON"); + const Uint64 after = NdbTick_CurrentMillisecond(); + + if(retVal == 0){ + ndbout << "Dropped index " << indexName << ", " + << after - before << " msec" << endl; + } else { + ndbout << "Failed to drop index " << indexName << endl; + ndbout << myNdb.getDictionary()->getNdbError() << endl; + } + } +} + +NDB_COMMAND(indexTest, "indexTest", "indexTest", "indexTest", 65535) +{ + bool createTableOp, createIndexOp, dropIndexOp, insertOp, updateOp, deleteOp, readOp, readIndexOp, updateIndexOp, deleteIndexOp, twoKey, longKey; + unsigned int noOfTuples = 1; + unsigned int noOfOperations = 1; + unsigned int noOfIndexes = 1; + int i = 1; + Ndb myNdb( "TEST_DB" ); + int check; + bool storeInACC = false; + bool includePrimary = false; + bool oneTransaction = false; + + createTableOp = createIndexOp = dropIndexOp = insertOp = updateOp = deleteOp = readOp = readIndexOp = updateIndexOp = deleteIndexOp = twoKey = longKey = false; + // Read arguments + if (argc > 1) + while (argc > 1) + { + if (strcmp(argv[i], "-T") == 0) + { + createTableOp = true; + argc -= 1; + i++; + } + else if (strcmp(argv[i], "-c") == 0) + { + createIndexOp = true; + argc -= 1; + i++; + } + else if (strcmp(argv[i], "-X") == 0) + { + dropIndexOp = true; + argc -= 1; + i++; + } + else if (strcmp(argv[i], "-I") == 0) + { + insertOp = true; + argc -= 1; + i++; + } + else if (strcmp(argv[i], "-D") == 0) + { + deleteOp = true; + argc -= 1; + i++; + } + else if (strcmp(argv[i], "-U") == 0) + { + updateOp = true; + argc -= 1; + i++; + } + else if (strcmp(argv[i], "-R") == 0) + { + readOp = true; + argc -= 1; + i++; + } + else if (strcmp(argv[i], "-r") == 0) + { + readIndexOp = true; + argc -= 1; + i++; + } + else if (strcmp(argv[i], "-u") == 0) + { + updateIndexOp = true; + argc -= 1; + i++; + } + else if (strcmp(argv[i], "-d") == 0) + { + deleteIndexOp = true; + argc -= 1; + i++; + } + else if (strcmp(argv[i], "-s") == 0) + { + storeInACC = true; + argc -= 1; + i++; + } + else if (strcmp(argv[i], "-p") == 0) + { + includePrimary = true; + argc -= 1; + i++; + } + else if (strcmp(argv[i], "-L") == 0) + { + longKey = true; + argc -= 1; + i++; + } + else if (strcmp(argv[i], "-1") == 0) + { + oneTransaction = true; + argc -= 1; + i++; + } + else if (strcmp(argv[i], "-2") == 0) + { + twoKey = true; + argc -= 1; + i++; + } + else if (strstr(argv[i], "-n") != 0) + { + noOfTuples = atoi(argv[i]+2); + argc -= 1; + i++; + } + else if (strstr(argv[i], "-o") != 0) + { + noOfOperations = MIN(MAX_NO_PARALLEL_OPERATIONS, atoi(argv[i]+2)); + argc -= 1; + i++; + } + else if (strstr(argv[i], "-m") != 0) + { + noOfIndexes = atoi(argv[i]+2); + argc -= 1; + i++; + } + else if (strstr(argv[i], "-h") != 0) + { + printf("Synopsis:\n"); + printf("index\n"); + printf("\t-T create table\n"); + printf("\t-L include a long attribute in key or index\n"); + printf("\t-2 define primary key with two attributes\n"); + printf("\t-c create index\n"); + printf("\t-p make index unique (include primary key attribute)\n"); + printf("\t-r read using index\n"); + printf("\t-u update using index\n"); + printf("\t-d delete using index\n"); + printf("\t-n do n operations (for -I -r -u -d -R -U -D)\n"); + printf("\t-o (for -I -r -u -d -R -U -D)\n"); + printf("\t-m\n"); + argc -= 1; + i++; + } + else { + char errStr[256]; + + printf(errStr, "Illegal argument: %s", argv[i]); + exit(-1); + } + } + else + { + createTableOp = createIndexOp = dropIndexOp = insertOp = updateOp = deleteOp = true; + } + if (longKey) { + longName = (char *) malloc(1024); + for (int i = 0; i < 1023; i++) + longName[i] = 'x'; + longName[1023] = '\0'; + } + sixtysix = (char *) malloc(256); + for (int i = 0; i < 255; i++) + sixtysix[i] = ' '; + sixtysix[255] = '\0'; + strncpy(sixtysix, "sixtysix", strlen("sixtysix")); + ninetynine = (char *) malloc(256); + for (int i = 0; i < 255; i++) + ninetynine[i] = ' '; + ninetynine[255] = '\0'; + strncpy(ninetynine, "ninetynine", strlen("ninetynine")); + hundred = (char *) malloc(256); + for (int i = 0; i < 255; i++) + hundred[i] = ' '; + hundred[255] = '\0'; + strncpy(hundred, "hundred", strlen("hundred")); + myNdb.init(); + // Wait for Ndb to become ready + if (myNdb.waitUntilReady(30) == 0) + { + if (createTableOp) + createTable(myNdb, storeInACC, twoKey, longKey); + + if (createIndexOp) + createIndex(myNdb, includePrimary, noOfIndexes); + + if (insertOp) + insertTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey); + + if (updateOp) + updateTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey); + + if (deleteOp) + deleteTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey); + + if (readOp) + readTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey); + + if (readIndexOp) + readIndex(myNdb, noOfTuples, noOfOperations, includePrimary, oneTransaction, longKey); + + if (updateIndexOp) + updateIndex(myNdb, noOfTuples, noOfOperations, includePrimary, oneTransaction, longKey); + + if (deleteIndexOp) + deleteIndex(myNdb, noOfTuples, noOfOperations, includePrimary, oneTransaction, longKey); + + if (dropIndexOp) + dropIndex(myNdb, noOfIndexes); + } + + if (testPassed) + { + // Test passed + ndbout << "OK - Test passed" << endl; + } + else + { + // Test failed + ndbout << "FAIL - Test failed" << endl; + exit(-1); + } + return 0; +} + + diff --git a/ndb/test/ndbapi/index2.cpp b/ndb/test/ndbapi/index2.cpp new file mode 100644 index 00000000000..e49113d2f1b --- /dev/null +++ b/ndb/test/ndbapi/index2.cpp @@ -0,0 +1,835 @@ +/* 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 */ + +/* *************************************************** + INDEX TEST 1 + Test index functionality of NDB + + Arguments: + -T create table + -L include a long attribute in key or index + -2 define primary key with two attributes + -c create index + -p make index unique (include primary key attribute) + -r read using index + -u update using index + -d delete using index + -n do n operations (for -I -r -u -d -R -U -D) + -o (for -I -r -u -d -R -U -D) + -m + + Returns: + 0 - Test passed + -1 - Test failed + 1 - Invalid arguments + * *************************************************** */ + +#include + +#include +#include +#include +#include +#include +#include + +#ifndef MIN +#define MIN(x,y) (((x)<(y))?(x):(y)) +#endif + +#define MAX_NO_PARALLEL_OPERATIONS 100 + +bool testPassed = true; + +static void +error_handler(const char* errorText) +{ + // Test failed + ndbout << endl << "ErrorMessage: " << errorText << endl; + testPassed = false; +} + +static void +error_handler4(int line, int status, int classif, int errNo, const char* errorText) +{ + ndbout << endl << "Line " << line << endl; + // Test failed + ndbout << "Status " << status << ", Classification " << classif<< ", Error code " << errNo << "\n" << errorText << endl; + testPassed = false; +} + +static char *longName, *sixtysix, *ninetynine, *hundred; + +static void createTable(Ndb &myNdb, bool storeInACC, bool twoKey, bool longKey) +{ + NdbDictionary::Dictionary* dict = myNdb.getDictionary(); + NdbDictionary::Table table("THE_TABLE"); + NdbDictionary::Column column; + int res; + + column.setName("X"); + column.setPrimaryKey(true); + column.setType(NdbDictionary::Column::Unsigned); + column.setLength(1); + column.setNullable(false); + table.addColumn(column); + + column.setName("Y"); + column.setPrimaryKey(false); + column.setType(NdbDictionary::Column::Unsigned); + column.setLength(1); + column.setNullable(false); + table.addColumn(column); + + if ((res = dict->createTable(table)) == -1) { + error_handler(dict->getNdbError().message); + } + else + ndbout << "Created table" << ((longKey)?" with long key":"") <createIndex(index)) == -1) { + error_handler(dict->getNdbError().message); + } + after = NdbTick_CurrentMillisecond(); + ndbout << "Created index " << indexName << ", " << after - before << " msec"<< endl; + } +} + +static void insertTable(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool oneTrans, bool twoKey, bool longKey) +{ + Uint64 tbefore, tafter, before, after; + NdbConnection *myTrans; + NdbOperation *myOp; + + tbefore = NdbTick_CurrentMillisecond(); + if (oneTrans) myTrans = myNdb.startTransaction(); + for (unsigned int i = 0; igetNdbOperation("THE_TABLE"); + if (myOp == NULL) + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + + myOp->insertTuple(); + if (myOp->equal("X", i) == -1) { + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + myNdb.closeTransaction(myTrans); + break; + } + if (myOp->setValue("Y", i+1) == -1) { + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + myNdb.closeTransaction(myTrans); + break; + } + } + before = NdbTick_CurrentMillisecond(); + if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1) + { + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + myNdb.closeTransaction(myTrans); + break; + } + after = NdbTick_CurrentMillisecond(); + if (noOfOperations == 1) + printf("Inserted 1 tuple, %u msec\n", (Uint32) after - before); + else + printf("Inserted %u tuples, %u msec\n", noOfOperations, (Uint32) after - before); + + if (!oneTrans) myNdb.closeTransaction(myTrans); + } + if (oneTrans) { + if (myTrans->execute( Commit ) == -1) { + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + } + myNdb.closeTransaction(myTrans); + } + tafter = NdbTick_CurrentMillisecond(); + + ndbout << "Inserted "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl; +} + +static void updateTable(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool oneTrans, bool twoKey, bool longKey) +{ + Uint64 tbefore, tafter, before, after; + NdbConnection *myTrans; + NdbOperation *myOp; + + tbefore = NdbTick_CurrentMillisecond(); + if (oneTrans) myTrans = myNdb.startTransaction(); + for (unsigned int i = 0; igetNdbOperation("THE_TABLE"); + if (myOp == NULL) + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + + myOp->updateTuple(); + if (myOp->equal("X", i) == -1) { + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + myNdb.closeTransaction(myTrans); + break; + } + if (myOp->setValue("Y", i+2) == -1) { + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + myNdb.closeTransaction(myTrans); + break; + } + } + before = NdbTick_CurrentMillisecond(); + if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1) + { + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + myNdb.closeTransaction(myTrans); + break; + } + after = NdbTick_CurrentMillisecond(); + if (noOfOperations == 1) + printf("Updated 1 tuple, %u msec\n", (Uint32) after - before); + else + printf("Update %u tuples, %u msec\n", noOfOperations, (Uint32) after - before); + + if (!oneTrans) myNdb.closeTransaction(myTrans); + } + if (oneTrans) { + if (myTrans->execute( Commit ) == -1) { + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + } + myNdb.closeTransaction(myTrans); + } + tafter = NdbTick_CurrentMillisecond(); + + ndbout << "Updated "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl; +} + +static void deleteTable(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool oneTrans, bool twoKey, bool longKey) +{ + Uint64 tbefore, tafter, before, after; + NdbConnection *myTrans; + NdbOperation *myOp; + + tbefore = NdbTick_CurrentMillisecond(); + if (oneTrans) myTrans = myNdb.startTransaction(); + for (unsigned int i = 0; igetNdbOperation("THE_TABLE"); + if (myOp == NULL) + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + + myOp->deleteTuple(); + if (myOp->equal("X", i) == -1) { + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + myNdb.closeTransaction(myTrans); + break; + } + before = NdbTick_CurrentMillisecond(); + if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1) + { + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + myNdb.closeTransaction(myTrans); + break; + } + } + after = NdbTick_CurrentMillisecond(); + if (noOfOperations == 1) + printf("Deleted 1 tuple, %u msec\n", (Uint32) after - before); + else + printf("Deleted %u tuples, %u msec\n", noOfOperations, (Uint32) after - before); + + if (!oneTrans) myNdb.closeTransaction(myTrans); + } + if (oneTrans) { + if (myTrans->execute( Commit ) == -1) { + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + } + myNdb.closeTransaction(myTrans); + } + tafter = NdbTick_CurrentMillisecond(); + + ndbout << "Deleted "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl; +} + +static void readTable(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool oneTrans, bool twoKey, bool longKey) +{ + Uint64 tbefore, tafter, before, after; + NdbConnection *myTrans; + NdbOperation *myOp; + NdbRecAttr* myRecAttrArr[MAX_NO_PARALLEL_OPERATIONS]; + + tbefore = NdbTick_CurrentMillisecond(); + if (oneTrans) myTrans = myNdb.startTransaction(); + for (unsigned int i = 0; igetNdbOperation("THE_TABLE"); + if (myOp == NULL) + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + + myOp->readTuple(); + if (myOp->equal("X", i) == -1) { + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + myNdb.closeTransaction(myTrans); + break; + } + myRecAttrArr[j-1] = myOp->getValue("Y", NULL); + } + before = NdbTick_CurrentMillisecond(); + if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1) + { + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + myNdb.closeTransaction(myTrans); + break; + } + after = NdbTick_CurrentMillisecond(); + if (noOfOperations == 1) + printf("Read 1 tuple, %u msec\n", (Uint32) after - before); + else + printf("Read %u tuples, %u msec\n", noOfOperations, (Uint32) after - before); + for(unsigned int j = 0; ju_32_value()); + if (!oneTrans) myNdb.closeTransaction(myTrans); + } + if (oneTrans) { + if (myTrans->execute( Commit ) == -1) { + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + } + myNdb.closeTransaction(myTrans); + } + tafter = NdbTick_CurrentMillisecond(); + + ndbout << "Read "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl; +} + +static void readIndex(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool includePrimary, bool oneTrans, bool longKey) +{ + Uint64 tbefore, tafter, before, after; + NdbConnection *myTrans; + NdbIndexOperation *myOp; + char indexName[] = "INDEX0000"; + NdbRecAttr* myRecAttrArr[MAX_NO_PARALLEL_OPERATIONS]; + + tbefore = NdbTick_CurrentMillisecond(); + if (oneTrans) myTrans = myNdb.startTransaction(); + for (unsigned int i = 0; igetNdbIndexOperation(indexName, "THE_TABLE"); + if (myOp == NULL) + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + + myOp->readTuple(); + if (includePrimary) { + if (myOp->equal("X", i) == -1) { + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + myNdb.closeTransaction(myTrans); + break; + } + } + if (myOp->equal("Y", i+1) == -1) { + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + myNdb.closeTransaction(myTrans); + break; + } + myRecAttrArr[j-1] = myOp->getValue("Y", NULL); + } + before = NdbTick_CurrentMillisecond(); + if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1) + { + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + myNdb.closeTransaction(myTrans); + break; + } + after = NdbTick_CurrentMillisecond(); + if (noOfOperations == 1) + printf("Read 1 tuple, %u msec\n", (Uint32) after - before); + else + printf("Read %u tuples, %u msec\n", noOfOperations, (Uint32) after - before); + for(unsigned int j = 0; ju_32_value()); + if (!oneTrans) myNdb.closeTransaction(myTrans); + } + if (oneTrans) { + if (myTrans->execute( Commit ) == -1) { + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + } + myNdb.closeTransaction(myTrans); + } + tafter = NdbTick_CurrentMillisecond(); + + ndbout << "Read "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl; +} + +static void updateIndex(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool includePrimary, bool oneTrans, bool longKey) +{ + Uint64 tbefore, tafter, before, after; + NdbConnection *myTrans; + NdbIndexOperation *myOp; + char indexName[] = "INDEX0000"; + + tbefore = NdbTick_CurrentMillisecond(); + if (oneTrans) myTrans = myNdb.startTransaction(); + for (unsigned int i = 0; igetNdbIndexOperation(indexName, "THE_TABLE"); + if (myOp == NULL) + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + + myOp->updateTuple(); + if (includePrimary) { + if (myOp->equal("X", i) == -1) { + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + myNdb.closeTransaction(myTrans); + break; + } + } + if (myOp->equal("Y", i+1) == -1) { + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + myNdb.closeTransaction(myTrans); + break; + } + // Update index itself, should be possible + if (myOp->setValue("Y", i+2) == -1) { + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + myNdb.closeTransaction(myTrans); + break; + } + } + before = NdbTick_CurrentMillisecond(); + if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1) + { + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + myNdb.closeTransaction(myTrans); + break; + } + + after = NdbTick_CurrentMillisecond(); + if (noOfOperations == 1) + printf("Updated 1 tuple, %u msec\n", (Uint32) after - before); + else + printf("Updated %u tuples, %u msec\n", noOfOperations, (Uint32) after - before); + if (!oneTrans) myNdb.closeTransaction(myTrans); + } + if (oneTrans) { + if (myTrans->execute( Commit ) == -1) { + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + } + myNdb.closeTransaction(myTrans); + } + tafter = NdbTick_CurrentMillisecond(); + + ndbout << "Updated "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl; +} + +static void deleteIndex(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool includePrimary, bool oneTrans, bool longKey) +{ + Uint64 tbefore, tafter, before, after; + NdbConnection *myTrans; + NdbIndexOperation *myOp; + char indexName[] = "INDEX0000"; + + tbefore = NdbTick_CurrentMillisecond(); + if (oneTrans) myTrans = myNdb.startTransaction(); + for (unsigned int i = 0; igetNdbIndexOperation(indexName, "THE_TABLE"); + if (myOp == NULL) + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + + myOp->deleteTuple(); + if (includePrimary) { + if (myOp->equal("X", i) == -1) { + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + myNdb.closeTransaction(myTrans); + break; + } + } + if (myOp->equal("Y", i+1) == -1) { + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + myNdb.closeTransaction(myTrans); + break; + } + } + before = NdbTick_CurrentMillisecond(); + if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1) + { + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + myNdb.closeTransaction(myTrans); + break; + } + after = NdbTick_CurrentMillisecond(); + if (noOfOperations == 1) + printf("Deleted 1 tuple, %u msec\n", (Uint32) after - before); + else + printf("Deleted %u tuples, %u msec\n", noOfOperations, (Uint32) after - before); + if (!oneTrans) myNdb.closeTransaction(myTrans); + } + if (oneTrans) { + if (myTrans->execute( Commit ) == -1) { + error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, + myTrans->getNdbError().code, myTrans->getNdbError().message); + } + myNdb.closeTransaction(myTrans); + } + tafter = NdbTick_CurrentMillisecond(); + + ndbout << "Deleted "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl; +} + +static void dropIndex(Ndb &myNdb, unsigned int noOfIndexes) +{ + for(unsigned int indexNum = 0; indexNum < noOfIndexes; indexNum++) { + char indexName[255]; + sprintf(indexName, "INDEX%.4u", indexNum); + const Uint64 before = NdbTick_CurrentMillisecond(); + const int retVal = myNdb.getDictionary()->dropIndex(indexName,"THE_TABLE"); + const Uint64 after = NdbTick_CurrentMillisecond(); + + if(retVal == 0){ + ndbout << "Dropped index " << indexName << ", " + << after - before << " msec" << endl; + } else { + ndbout << "Failed to drop index " << indexName << endl; + ndbout << myNdb.getDictionary()->getNdbError() << endl; + } + } +} + +NDB_COMMAND(indexTest, "indexTest", "indexTest", "indexTest", 65535) +{ + bool createTableOp, createIndexOp, dropIndexOp, insertOp, updateOp, deleteOp, readOp, readIndexOp, updateIndexOp, deleteIndexOp, twoKey, longKey; + unsigned int noOfTuples = 1; + unsigned int noOfOperations = 1; + unsigned int noOfIndexes = 1; + int i = 1; + Ndb myNdb( "TEST_DB" ); + int check; + bool storeInACC = false; + bool includePrimary = false; + bool oneTransaction = false; + + createTableOp = createIndexOp = dropIndexOp = insertOp = updateOp = deleteOp = readOp = readIndexOp = updateIndexOp = deleteIndexOp = twoKey = longKey = false; + // Read arguments + if (argc > 1) + while (argc > 1) + { + if (strcmp(argv[i], "-T") == 0) + { + createTableOp = true; + argc -= 1; + i++; + } + else if (strcmp(argv[i], "-c") == 0) + { + createIndexOp = true; + argc -= 1; + i++; + } + else if (strcmp(argv[i], "-X") == 0) + { + dropIndexOp = true; + argc -= 1; + i++; + } + else if (strcmp(argv[i], "-I") == 0) + { + insertOp = true; + argc -= 1; + i++; + } + else if (strcmp(argv[i], "-D") == 0) + { + deleteOp = true; + argc -= 1; + i++; + } + else if (strcmp(argv[i], "-U") == 0) + { + updateOp = true; + argc -= 1; + i++; + } + else if (strcmp(argv[i], "-R") == 0) + { + readOp = true; + argc -= 1; + i++; + } + else if (strcmp(argv[i], "-r") == 0) + { + readIndexOp = true; + argc -= 1; + i++; + } + else if (strcmp(argv[i], "-u") == 0) + { + updateIndexOp = true; + argc -= 1; + i++; + } + else if (strcmp(argv[i], "-d") == 0) + { + deleteIndexOp = true; + argc -= 1; + i++; + } + else if (strcmp(argv[i], "-s") == 0) + { + storeInACC = true; + argc -= 1; + i++; + } + else if (strcmp(argv[i], "-p") == 0) + { + includePrimary = true; + argc -= 1; + i++; + } + else if (strcmp(argv[i], "-L") == 0) + { + longKey = true; + argc -= 1; + i++; + } + else if (strcmp(argv[i], "-1") == 0) + { + oneTransaction = true; + argc -= 1; + i++; + } + else if (strcmp(argv[i], "-2") == 0) + { + twoKey = true; + argc -= 1; + i++; + } + else if (strstr(argv[i], "-n") != 0) + { + noOfTuples = atoi(argv[i]+2); + argc -= 1; + i++; + } + else if (strstr(argv[i], "-o") != 0) + { + noOfOperations = MIN(MAX_NO_PARALLEL_OPERATIONS, atoi(argv[i]+2)); + argc -= 1; + i++; + } + else if (strstr(argv[i], "-m") != 0) + { + noOfIndexes = atoi(argv[i]+2); + argc -= 1; + i++; + } + else if (strstr(argv[i], "-h") != 0) + { + printf("Synopsis: \ + index\ + -T create table\ + -L include a long attribute in key or index\ + -2 define primary key with two attributes\ + -c create index\ + -p make index unique (include primary key attribute)\ + -r read using index\ + -u update using index\ + -d delete using index\ + -n do n operations (for -I -r -u -d -R -U -D)\ + -o (for -I -r -u -d -R -U -D)\ + -m\n"); + argc -= 1; + i++; + } + else { + char errStr[256]; + + sprintf(errStr, "Illegal argument: %s", argv[i]); + error_handler(errStr); + exit(-1); + } + } + else + { + createTableOp = createIndexOp = dropIndexOp = insertOp = updateOp = deleteOp = true; + } + if (longKey) { + longName = (char *) malloc(1024); + for (int i = 0; i < 1023; i++) + longName[i] = 'x'; + longName[1023] = '\0'; + } + sixtysix = (char *) malloc(256); + for (int i = 0; i < 255; i++) + sixtysix[i] = ' '; + sixtysix[255] = '\0'; + strncpy(sixtysix, "sixtysix", strlen("sixtysix")); + ninetynine = (char *) malloc(256); + for (int i = 0; i < 255; i++) + ninetynine[i] = ' '; + ninetynine[255] = '\0'; + strncpy(ninetynine, "ninetynine", strlen("ninetynine")); + hundred = (char *) malloc(256); + for (int i = 0; i < 255; i++) + hundred[i] = ' '; + hundred[255] = '\0'; + strncpy(hundred, "hundred", strlen("hundred")); + myNdb.init(); + // Wait for Ndb to become ready + if (myNdb.waitUntilReady(30) == 0) + { + if (createTableOp) + createTable(myNdb, storeInACC, twoKey, longKey); + + if (createIndexOp) + createIndex(myNdb, includePrimary, noOfIndexes); + + if (insertOp) + insertTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey); + + if (updateOp) + updateTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey); + + if (deleteOp) + deleteTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey); + + if (readOp) + readTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey); + + if (readIndexOp) + readIndex(myNdb, noOfTuples, noOfOperations, includePrimary, oneTransaction, longKey); + + if (updateIndexOp) + updateIndex(myNdb, noOfTuples, noOfOperations, includePrimary, oneTransaction, longKey); + + if (deleteIndexOp) + deleteIndex(myNdb, noOfTuples, noOfOperations, includePrimary, oneTransaction, longKey); + + if (dropIndexOp) + dropIndex(myNdb, noOfIndexes); + } + + if (testPassed) + { + // Test passed + ndbout << "OK - Test passed" << endl; + } + else + { + // Test failed + ndbout << "FAIL - Test failed" << endl; + exit(-1); + } + return NULL; +} + + diff --git a/ndb/test/ndbapi/indexTest/Makefile b/ndb/test/ndbapi/indexTest/Makefile deleted file mode 100644 index d842e487ee5..00000000000 --- a/ndb/test/ndbapi/indexTest/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := index - -SOURCES := index.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/indexTest/index.cpp b/ndb/test/ndbapi/indexTest/index.cpp deleted file mode 100644 index 508186de529..00000000000 --- a/ndb/test/ndbapi/indexTest/index.cpp +++ /dev/null @@ -1,997 +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 */ - -/* *************************************************** - INDEX TEST 1 - Test index functionality of NDB - - Arguments: - -T create table - -L include a long attribute in key or index - -2 define primary key with two attributes - -c create index - -p make index unique (include primary key attribute) - -r read using index - -u update using index - -d delete using index - -n do n operations (for -I -r -u -d -R -U -D) - -o (for -I -r -u -d -R -U -D) - -m - - Returns: - 0 - Test passed - -1 - Test failed - 1 - Invalid arguments - * *************************************************** */ - -#include - -#include -#include -#include -#include -#include -#include - -#ifndef MIN -#define MIN(x,y) (((x)<(y))?(x):(y)) -#endif - -#define MAX_NO_PARALLEL_OPERATIONS 100 - -bool testPassed = true; - -static void -error_handler(const NdbError & err) -{ - // Test failed - ndbout << endl << err << endl; - testPassed = false; -} - -static void -error_handler4(int line, const NdbError & err){ - ndbout << endl << "Line " << line << endl; - // Test failed - ndbout << err << endl; - testPassed = false; -} - -static char *longName, *sixtysix, *ninetynine, *hundred; - -static void createTable(Ndb &myNdb, bool storeInACC, bool twoKey, bool longKey) -{ - NdbDictionary::Dictionary* dict = myNdb.getDictionary(); - NdbDictionary::Table table("PERSON"); - //NdbDictionary::Column column(); // Bug - NdbDictionary::Column column; - int res; - - column.setName("NAME"); - column.setPrimaryKey(true); - column.setType(NdbDictionary::Column::Char); - column.setLength((longKey)? - 1024 // 1KB => long key - :12); - column.setNullable(false); - table.addColumn(column); - - if (twoKey) { - column.setName("KEY2"); - column.setPrimaryKey(true); - column.setType(NdbDictionary::Column::Unsigned); - column.setLength(1); - column.setNullable(false); - table.addColumn(column); - } - - column.setName("PNUM1"); - column.setPrimaryKey(false); - column.setType(NdbDictionary::Column::Unsigned); - column.setLength(1); - column.setNullable(false); - table.addColumn(column); - - column.setName("PNUM2"); - column.setPrimaryKey(false); - column.setType(NdbDictionary::Column::Unsigned); - column.setLength(1); - column.setNullable(false); - table.addColumn(column); - - column.setName("PNUM3"); - column.setPrimaryKey(false); - column.setType(NdbDictionary::Column::Unsigned); - column.setLength(1); - column.setNullable(false); - table.addColumn(column); - - column.setName("PNUM4"); - column.setPrimaryKey(false); - column.setType(NdbDictionary::Column::Unsigned); - column.setLength(1); - column.setNullable(false); - table.addColumn(column); - - column.setName("AGE"); - column.setPrimaryKey(false); - column.setType(NdbDictionary::Column::Unsigned); - column.setLength(1); - column.setNullable(false); - table.addColumn(column); - - column.setName("STRING_AGE"); - column.setPrimaryKey(false); - column.setType(NdbDictionary::Column::Char); - column.setLength(1); - column.setLength(256); - column.setNullable(false); - table.addColumn(column); - - if ((res = dict->createTable(table)) == -1) { - error_handler(dict->getNdbError()); - } - else - ndbout << "Created table" << ((longKey)?" with long key":"") <createIndex(index)) == -1) { - error_handler(dict->getNdbError()); - } - after = NdbTick_CurrentMillisecond(); - ndbout << "Created index " << indexName << ", " << after - before << " msec" << endl; - } -} - -static void insertTable(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool oneTrans, bool twoKey, bool longKey) -{ - Uint64 tbefore, tafter, before, after; - NdbConnection *myTrans; - NdbOperation *myOp; - char name[] = "Kalle0000000"; - - tbefore = NdbTick_CurrentMillisecond(); - if (oneTrans) myTrans = myNdb.startTransaction(); - for (unsigned int i = 0; igetNdbOperation("PERSON"); - if (myOp == NULL) - error_handler4(__LINE__, myTrans->getNdbError()); - - myOp->insertTuple(); - sprintf(name, "Kalle%.7i", i); - if (longKey) - memcpy(longName, name, strlen(name)); - if (myOp->equal("NAME", (longKey)?longName:name) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - if (twoKey) - if (myOp->equal("KEY2", i) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - if (myOp->setValue("PNUM1", 17) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - if (myOp->setValue("PNUM2", 18)) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - if (myOp->setValue("PNUM3", 19)) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - if (myOp->setValue("PNUM4", 20)) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - if (myOp->setValue("AGE", ((i % 2) == 0)?66:99) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - if (myOp->setValue("STRING_AGE", ((i % 2) == 0)?sixtysix:ninetynine) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - } - if (noOfOperations == 1) - printf("Trying to insert person %s\n", name); - else - printf("Trying to insert %u persons\n", noOfOperations); - before = NdbTick_CurrentMillisecond(); - if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1) - { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - after = NdbTick_CurrentMillisecond(); - if (noOfOperations == 1) - printf("Inserted person %s, %u msec\n", name, (Uint32) after - before); - else - printf("Inserted %u persons, %u msec\n", noOfOperations, (Uint32) after - before); - if (!oneTrans) myNdb.closeTransaction(myTrans); - } - if (oneTrans) { - if (myTrans->execute( Commit ) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - } - myNdb.closeTransaction(myTrans); - } - tafter = NdbTick_CurrentMillisecond(); - - ndbout << "Inserted "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl; -} - -static void updateTable(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool oneTrans, bool twoKey, bool longKey) -{ - Uint64 tbefore, tafter, before, after; - NdbConnection *myTrans; - NdbOperation *myOp; - char name[] = "Kalle0000000"; - - tbefore = NdbTick_CurrentMillisecond(); - if (oneTrans) myTrans = myNdb.startTransaction(); - for (unsigned int i = 0; igetNdbOperation("PERSON"); - if (myOp == NULL) - error_handler4(__LINE__, myTrans->getNdbError()); - - myOp->updateTuple(); - sprintf(name, "Kalle%.7i", i); - if (longKey) - memcpy(longName, name, strlen(name)); - if (myOp->equal("NAME", (longKey)?longName:name) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - if (twoKey) - if (myOp->equal("KEY2", i) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - if (myOp->setValue("PNUM1", 77) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - if (myOp->setValue("PNUM2", 88)) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - if (myOp->setValue("PNUM4", 99)) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - if (myOp->setValue("AGE", 100) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - if (myOp->setValue("STRING_AGE", hundred) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - } - if (noOfOperations == 1) - printf("Trying to update person %s\n", name); - else - printf("Trying to update %u persons\n", noOfOperations); - before = NdbTick_CurrentMillisecond(); - if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1) - { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - after = NdbTick_CurrentMillisecond(); - if (noOfOperations == 1) - printf("Updated person %s, %u msec\n", name, (Uint32) after - before); - else - printf("Update %u persons, %u msec\n", noOfOperations, (Uint32) after - before); - if (!oneTrans) myNdb.closeTransaction(myTrans); - } - if (oneTrans) { - if (myTrans->execute( Commit ) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - } - myNdb.closeTransaction(myTrans); - } - tafter = NdbTick_CurrentMillisecond(); - - ndbout << "Updated "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl; -} - -static void deleteTable(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool oneTrans, bool twoKey, bool longKey) -{ - Uint64 tbefore, tafter, before, after; - NdbConnection *myTrans; - NdbOperation *myOp; - char name[] = "Kalle0000000"; - - tbefore = NdbTick_CurrentMillisecond(); - if (oneTrans) myTrans = myNdb.startTransaction(); - for (unsigned int i = 0; igetNdbOperation("PERSON"); - if (myOp == NULL) - error_handler4(__LINE__, myTrans->getNdbError()); - - myOp->deleteTuple(); - sprintf(name, "Kalle%.7i", i); - if (longKey) - memcpy(longName, name, strlen(name)); - if (myOp->equal("NAME", (longKey)?longName:name) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - if (twoKey) - if (myOp->equal("KEY2", i) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - } - if (noOfOperations == 1) - printf("Trying to delete person %s\n", name); - else - printf("Trying to delete %u persons\n", noOfOperations); - before = NdbTick_CurrentMillisecond(); - if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1) - { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - after = NdbTick_CurrentMillisecond(); - if (noOfOperations == 1) - printf("Deleted person %s, %u msec\n", name, (Uint32) after - before); - else - printf("Deleted %u persons, %u msec\n", noOfOperations, (Uint32) after - before); - - if (!oneTrans) myNdb.closeTransaction(myTrans); - } - if (oneTrans) { - if (myTrans->execute( Commit ) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - } - myNdb.closeTransaction(myTrans); - } - tafter = NdbTick_CurrentMillisecond(); - - ndbout << "Deleted "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl; -} - -static void readTable(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool oneTrans, bool twoKey, bool longKey) -{ - Uint64 tbefore, tafter, before, after; - NdbConnection *myTrans; - NdbOperation *myOp; - char name[] = "Kalle0000000"; - NdbRecAttr* myRecAttrArr[MAX_NO_PARALLEL_OPERATIONS]; - - tbefore = NdbTick_CurrentMillisecond(); - if (oneTrans) myTrans = myNdb.startTransaction(); - for (unsigned int i = 0; igetNdbOperation("PERSON"); - if (myOp == NULL) - error_handler4(__LINE__, myTrans->getNdbError()); - - myOp->readTuple(); - sprintf(name, "Kalle%.7i", i); - if (longKey) - memcpy(longName, name, strlen(name)); - if (myOp->equal("NAME", (longKey)?longName:name) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - if (twoKey) - if (myOp->equal("KEY2", i) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - myRecAttrArr[j-1] = myOp->getValue("PNUM2", NULL); - } - if (noOfOperations == 1) - printf("Trying to read person %s\n", name); - else - printf("Trying to read %u persons\n", noOfOperations); - before = NdbTick_CurrentMillisecond(); - if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1) - { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - after = NdbTick_CurrentMillisecond(); - if (noOfOperations == 1) - printf("Read person %s, %u msec\n", name, (Uint32) after - before); - else - printf("Read %u persons, %u msec\n", noOfOperations, (Uint32) after - before); - for(unsigned int j = 0; ju_32_value()); - if (!oneTrans) myNdb.closeTransaction(myTrans); - } - if (oneTrans) { - if (myTrans->execute( Commit ) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - } - myNdb.closeTransaction(myTrans); - } - tafter = NdbTick_CurrentMillisecond(); - - ndbout << "Read "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl; -} - -static void readIndex(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool includePrimary, bool oneTrans, bool longKey) -{ - Uint64 tbefore, tafter, before, after; - NdbConnection *myTrans; - NdbIndexOperation *myOp; - char indexName[] = "PNUMINDEX0000"; - char name[] = "Kalle0000000"; - NdbRecAttr* myRecAttrArr[MAX_NO_PARALLEL_OPERATIONS]; - - tbefore = NdbTick_CurrentMillisecond(); - if (oneTrans) myTrans = myNdb.startTransaction(); - for (unsigned int i = 0; igetNdbIndexOperation(indexName, "PERSON"); - if (myOp == NULL) - error_handler4(__LINE__, myTrans->getNdbError()); - - myOp->readTuple(); - if (includePrimary) { - sprintf(name, "Kalle%.7i", i); - if (longKey) - memcpy(longName, name, strlen(name)); - if (myOp->equal("NAME", (longKey)?longName:name) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - } - if (myOp->equal("PNUM1", 17) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - if (myOp->equal("PNUM3", 19) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - myRecAttrArr[j-1] = myOp->getValue("PNUM2", NULL); - } - if (noOfOperations == 1) - printf("Trying to read person %s\n", name); - else - printf("Trying to read %u persons\n", noOfOperations); - before = NdbTick_CurrentMillisecond(); - if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1) - { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - after = NdbTick_CurrentMillisecond(); - if (noOfOperations == 1) - printf("Read person %s, %u msec\n", name, (Uint32) after - before); - else - printf("Read %u persons, %u msec\n", noOfOperations, (Uint32) after - before); - for(unsigned int j = 0; ju_32_value()); - if (!oneTrans) myNdb.closeTransaction(myTrans); - } - if (oneTrans) { - if (myTrans->execute( Commit ) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - } - myNdb.closeTransaction(myTrans); - } - tafter = NdbTick_CurrentMillisecond(); - - ndbout << "Read "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl; -} - -static void updateIndex(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool includePrimary, bool oneTrans, bool longKey) -{ - Uint64 tbefore, tafter, before, after; - NdbConnection *myTrans; - NdbIndexOperation *myOp; - char indexName[] = "PNUMINDEX0000"; - char name[] = "Kalle0000000"; - - tbefore = NdbTick_CurrentMillisecond(); - if (oneTrans) myTrans = myNdb.startTransaction(); - for (unsigned int i = 0; igetNdbIndexOperation(indexName, "PERSON"); - if (myOp == NULL) - error_handler4(__LINE__, myTrans->getNdbError()); - - myOp->updateTuple(); - if (includePrimary) { - sprintf(name, "Kalle%.7i", i); - if (longKey) - memcpy(longName, name, strlen(name)); - if (myOp->equal("NAME", (longKey)?longName:name) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - } - if (myOp->equal("PNUM1", 17) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - if (myOp->equal("PNUM3", 19) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - // Update index itself, should be possible - if (myOp->setValue("PNUM1", 77) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - if (myOp->setValue("PNUM2", 88)) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - if (myOp->setValue("PNUM4", 99)) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - if (myOp->setValue("AGE", 100) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - if (myOp->setValue("STRING_AGE", hundred) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - } - if (noOfOperations == 1) - printf("Trying to update person %s\n", name); - else - printf("Trying to update %u persons\n", noOfOperations); - before = NdbTick_CurrentMillisecond(); - if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1) - { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - after = NdbTick_CurrentMillisecond(); - if (noOfOperations == 1) - printf("Updated person %s, %u msec\n", name, (Uint32) after - before); - else - printf("Updated %u persons, %u msec\n", noOfOperations, (Uint32) after - before); - if (!oneTrans) myNdb.closeTransaction(myTrans); - } - if (oneTrans) { - if (myTrans->execute( Commit ) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - } - myNdb.closeTransaction(myTrans); - } - tafter = NdbTick_CurrentMillisecond(); - - ndbout << "Updated "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl; -} - -static void deleteIndex(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool includePrimary, bool oneTrans, bool longKey) -{ - Uint64 tbefore, tafter, before, after; - NdbConnection *myTrans; - NdbIndexOperation *myOp; - char indexName[] = "PNUMINDEX0000"; - char name[] = "Kalle0000000"; - - tbefore = NdbTick_CurrentMillisecond(); - if (oneTrans) myTrans = myNdb.startTransaction(); - for (unsigned int i = 0; igetNdbIndexOperation(indexName, "PERSON"); - if (myOp == NULL) - error_handler4(__LINE__, myTrans->getNdbError()); - - myOp->deleteTuple(); - if (includePrimary) { - sprintf(name, "Kalle%.7i", i); - if (longKey) - memcpy(longName, name, strlen(name)); - if (myOp->equal("NAME", (longKey)?longName:name) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - } - if (myOp->equal("PNUM1", 17) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - if (myOp->equal("PNUM3", 19) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - } - if (noOfOperations == 1) - printf("Trying to delete person %s\n", name); - else - printf("Trying to delete %u persons\n", noOfOperations); - before = NdbTick_CurrentMillisecond(); - if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1) - { - error_handler4(__LINE__, myTrans->getNdbError()); - myNdb.closeTransaction(myTrans); - break; - } - after = NdbTick_CurrentMillisecond(); - if (noOfOperations == 1) - printf("Deleted person %s, %u msec\n", name, (Uint32) after - before); - else - printf("Deleted %u persons, %u msec\n", noOfOperations, (Uint32) after - before); - if (!oneTrans) myNdb.closeTransaction(myTrans); - } - if (oneTrans) { - if (myTrans->execute( Commit ) == -1) { - error_handler4(__LINE__, myTrans->getNdbError()); - } - myNdb.closeTransaction(myTrans); - } - tafter = NdbTick_CurrentMillisecond(); - - ndbout << "Deleted "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl; -} - -static void dropIndex(Ndb &myNdb, unsigned int noOfIndexes) -{ - for(unsigned int indexNum = 0; indexNum < noOfIndexes; indexNum++) { - char indexName[255]; - sprintf(indexName, "PNUMINDEX%.4u", indexNum); - const Uint64 before = NdbTick_CurrentMillisecond(); - const int retVal = myNdb.getDictionary()->dropIndex(indexName, "PERSON"); - const Uint64 after = NdbTick_CurrentMillisecond(); - - if(retVal == 0){ - ndbout << "Dropped index " << indexName << ", " - << after - before << " msec" << endl; - } else { - ndbout << "Failed to drop index " << indexName << endl; - ndbout << myNdb.getDictionary()->getNdbError() << endl; - } - } -} - -NDB_COMMAND(indexTest, "indexTest", "indexTest", "indexTest", 65535) -{ - bool createTableOp, createIndexOp, dropIndexOp, insertOp, updateOp, deleteOp, readOp, readIndexOp, updateIndexOp, deleteIndexOp, twoKey, longKey; - unsigned int noOfTuples = 1; - unsigned int noOfOperations = 1; - unsigned int noOfIndexes = 1; - int i = 1; - Ndb myNdb( "TEST_DB" ); - int check; - bool storeInACC = false; - bool includePrimary = false; - bool oneTransaction = false; - - createTableOp = createIndexOp = dropIndexOp = insertOp = updateOp = deleteOp = readOp = readIndexOp = updateIndexOp = deleteIndexOp = twoKey = longKey = false; - // Read arguments - if (argc > 1) - while (argc > 1) - { - if (strcmp(argv[i], "-T") == 0) - { - createTableOp = true; - argc -= 1; - i++; - } - else if (strcmp(argv[i], "-c") == 0) - { - createIndexOp = true; - argc -= 1; - i++; - } - else if (strcmp(argv[i], "-X") == 0) - { - dropIndexOp = true; - argc -= 1; - i++; - } - else if (strcmp(argv[i], "-I") == 0) - { - insertOp = true; - argc -= 1; - i++; - } - else if (strcmp(argv[i], "-D") == 0) - { - deleteOp = true; - argc -= 1; - i++; - } - else if (strcmp(argv[i], "-U") == 0) - { - updateOp = true; - argc -= 1; - i++; - } - else if (strcmp(argv[i], "-R") == 0) - { - readOp = true; - argc -= 1; - i++; - } - else if (strcmp(argv[i], "-r") == 0) - { - readIndexOp = true; - argc -= 1; - i++; - } - else if (strcmp(argv[i], "-u") == 0) - { - updateIndexOp = true; - argc -= 1; - i++; - } - else if (strcmp(argv[i], "-d") == 0) - { - deleteIndexOp = true; - argc -= 1; - i++; - } - else if (strcmp(argv[i], "-s") == 0) - { - storeInACC = true; - argc -= 1; - i++; - } - else if (strcmp(argv[i], "-p") == 0) - { - includePrimary = true; - argc -= 1; - i++; - } - else if (strcmp(argv[i], "-L") == 0) - { - longKey = true; - argc -= 1; - i++; - } - else if (strcmp(argv[i], "-1") == 0) - { - oneTransaction = true; - argc -= 1; - i++; - } - else if (strcmp(argv[i], "-2") == 0) - { - twoKey = true; - argc -= 1; - i++; - } - else if (strstr(argv[i], "-n") != 0) - { - noOfTuples = atoi(argv[i]+2); - argc -= 1; - i++; - } - else if (strstr(argv[i], "-o") != 0) - { - noOfOperations = MIN(MAX_NO_PARALLEL_OPERATIONS, atoi(argv[i]+2)); - argc -= 1; - i++; - } - else if (strstr(argv[i], "-m") != 0) - { - noOfIndexes = atoi(argv[i]+2); - argc -= 1; - i++; - } - else if (strstr(argv[i], "-h") != 0) - { - printf("Synopsis:\n"); - printf("index\n"); - printf("\t-T create table\n"); - printf("\t-L include a long attribute in key or index\n"); - printf("\t-2 define primary key with two attributes\n"); - printf("\t-c create index\n"); - printf("\t-p make index unique (include primary key attribute)\n"); - printf("\t-r read using index\n"); - printf("\t-u update using index\n"); - printf("\t-d delete using index\n"); - printf("\t-n do n operations (for -I -r -u -d -R -U -D)\n"); - printf("\t-o (for -I -r -u -d -R -U -D)\n"); - printf("\t-m\n"); - argc -= 1; - i++; - } - else { - char errStr[256]; - - printf(errStr, "Illegal argument: %s", argv[i]); - exit(-1); - } - } - else - { - createTableOp = createIndexOp = dropIndexOp = insertOp = updateOp = deleteOp = true; - } - if (longKey) { - longName = (char *) malloc(1024); - for (int i = 0; i < 1023; i++) - longName[i] = 'x'; - longName[1023] = '\0'; - } - sixtysix = (char *) malloc(256); - for (int i = 0; i < 255; i++) - sixtysix[i] = ' '; - sixtysix[255] = '\0'; - strncpy(sixtysix, "sixtysix", strlen("sixtysix")); - ninetynine = (char *) malloc(256); - for (int i = 0; i < 255; i++) - ninetynine[i] = ' '; - ninetynine[255] = '\0'; - strncpy(ninetynine, "ninetynine", strlen("ninetynine")); - hundred = (char *) malloc(256); - for (int i = 0; i < 255; i++) - hundred[i] = ' '; - hundred[255] = '\0'; - strncpy(hundred, "hundred", strlen("hundred")); - myNdb.init(); - // Wait for Ndb to become ready - if (myNdb.waitUntilReady(30) == 0) - { - if (createTableOp) - createTable(myNdb, storeInACC, twoKey, longKey); - - if (createIndexOp) - createIndex(myNdb, includePrimary, noOfIndexes); - - if (insertOp) - insertTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey); - - if (updateOp) - updateTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey); - - if (deleteOp) - deleteTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey); - - if (readOp) - readTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey); - - if (readIndexOp) - readIndex(myNdb, noOfTuples, noOfOperations, includePrimary, oneTransaction, longKey); - - if (updateIndexOp) - updateIndex(myNdb, noOfTuples, noOfOperations, includePrimary, oneTransaction, longKey); - - if (deleteIndexOp) - deleteIndex(myNdb, noOfTuples, noOfOperations, includePrimary, oneTransaction, longKey); - - if (dropIndexOp) - dropIndex(myNdb, noOfIndexes); - } - - if (testPassed) - { - // Test passed - ndbout << "OK - Test passed" << endl; - } - else - { - // Test failed - ndbout << "FAIL - Test failed" << endl; - exit(-1); - } - return 0; -} - - diff --git a/ndb/test/ndbapi/indexTest2/Makefile b/ndb/test/ndbapi/indexTest2/Makefile deleted file mode 100644 index ad78fd51986..00000000000 --- a/ndb/test/ndbapi/indexTest2/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := index2 - -SOURCES := index2.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/indexTest2/index2.cpp b/ndb/test/ndbapi/indexTest2/index2.cpp deleted file mode 100644 index e49113d2f1b..00000000000 --- a/ndb/test/ndbapi/indexTest2/index2.cpp +++ /dev/null @@ -1,835 +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 */ - -/* *************************************************** - INDEX TEST 1 - Test index functionality of NDB - - Arguments: - -T create table - -L include a long attribute in key or index - -2 define primary key with two attributes - -c create index - -p make index unique (include primary key attribute) - -r read using index - -u update using index - -d delete using index - -n do n operations (for -I -r -u -d -R -U -D) - -o (for -I -r -u -d -R -U -D) - -m - - Returns: - 0 - Test passed - -1 - Test failed - 1 - Invalid arguments - * *************************************************** */ - -#include - -#include -#include -#include -#include -#include -#include - -#ifndef MIN -#define MIN(x,y) (((x)<(y))?(x):(y)) -#endif - -#define MAX_NO_PARALLEL_OPERATIONS 100 - -bool testPassed = true; - -static void -error_handler(const char* errorText) -{ - // Test failed - ndbout << endl << "ErrorMessage: " << errorText << endl; - testPassed = false; -} - -static void -error_handler4(int line, int status, int classif, int errNo, const char* errorText) -{ - ndbout << endl << "Line " << line << endl; - // Test failed - ndbout << "Status " << status << ", Classification " << classif<< ", Error code " << errNo << "\n" << errorText << endl; - testPassed = false; -} - -static char *longName, *sixtysix, *ninetynine, *hundred; - -static void createTable(Ndb &myNdb, bool storeInACC, bool twoKey, bool longKey) -{ - NdbDictionary::Dictionary* dict = myNdb.getDictionary(); - NdbDictionary::Table table("THE_TABLE"); - NdbDictionary::Column column; - int res; - - column.setName("X"); - column.setPrimaryKey(true); - column.setType(NdbDictionary::Column::Unsigned); - column.setLength(1); - column.setNullable(false); - table.addColumn(column); - - column.setName("Y"); - column.setPrimaryKey(false); - column.setType(NdbDictionary::Column::Unsigned); - column.setLength(1); - column.setNullable(false); - table.addColumn(column); - - if ((res = dict->createTable(table)) == -1) { - error_handler(dict->getNdbError().message); - } - else - ndbout << "Created table" << ((longKey)?" with long key":"") <createIndex(index)) == -1) { - error_handler(dict->getNdbError().message); - } - after = NdbTick_CurrentMillisecond(); - ndbout << "Created index " << indexName << ", " << after - before << " msec"<< endl; - } -} - -static void insertTable(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool oneTrans, bool twoKey, bool longKey) -{ - Uint64 tbefore, tafter, before, after; - NdbConnection *myTrans; - NdbOperation *myOp; - - tbefore = NdbTick_CurrentMillisecond(); - if (oneTrans) myTrans = myNdb.startTransaction(); - for (unsigned int i = 0; igetNdbOperation("THE_TABLE"); - if (myOp == NULL) - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - - myOp->insertTuple(); - if (myOp->equal("X", i) == -1) { - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - myNdb.closeTransaction(myTrans); - break; - } - if (myOp->setValue("Y", i+1) == -1) { - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - myNdb.closeTransaction(myTrans); - break; - } - } - before = NdbTick_CurrentMillisecond(); - if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1) - { - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - myNdb.closeTransaction(myTrans); - break; - } - after = NdbTick_CurrentMillisecond(); - if (noOfOperations == 1) - printf("Inserted 1 tuple, %u msec\n", (Uint32) after - before); - else - printf("Inserted %u tuples, %u msec\n", noOfOperations, (Uint32) after - before); - - if (!oneTrans) myNdb.closeTransaction(myTrans); - } - if (oneTrans) { - if (myTrans->execute( Commit ) == -1) { - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - } - myNdb.closeTransaction(myTrans); - } - tafter = NdbTick_CurrentMillisecond(); - - ndbout << "Inserted "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl; -} - -static void updateTable(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool oneTrans, bool twoKey, bool longKey) -{ - Uint64 tbefore, tafter, before, after; - NdbConnection *myTrans; - NdbOperation *myOp; - - tbefore = NdbTick_CurrentMillisecond(); - if (oneTrans) myTrans = myNdb.startTransaction(); - for (unsigned int i = 0; igetNdbOperation("THE_TABLE"); - if (myOp == NULL) - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - - myOp->updateTuple(); - if (myOp->equal("X", i) == -1) { - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - myNdb.closeTransaction(myTrans); - break; - } - if (myOp->setValue("Y", i+2) == -1) { - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - myNdb.closeTransaction(myTrans); - break; - } - } - before = NdbTick_CurrentMillisecond(); - if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1) - { - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - myNdb.closeTransaction(myTrans); - break; - } - after = NdbTick_CurrentMillisecond(); - if (noOfOperations == 1) - printf("Updated 1 tuple, %u msec\n", (Uint32) after - before); - else - printf("Update %u tuples, %u msec\n", noOfOperations, (Uint32) after - before); - - if (!oneTrans) myNdb.closeTransaction(myTrans); - } - if (oneTrans) { - if (myTrans->execute( Commit ) == -1) { - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - } - myNdb.closeTransaction(myTrans); - } - tafter = NdbTick_CurrentMillisecond(); - - ndbout << "Updated "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl; -} - -static void deleteTable(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool oneTrans, bool twoKey, bool longKey) -{ - Uint64 tbefore, tafter, before, after; - NdbConnection *myTrans; - NdbOperation *myOp; - - tbefore = NdbTick_CurrentMillisecond(); - if (oneTrans) myTrans = myNdb.startTransaction(); - for (unsigned int i = 0; igetNdbOperation("THE_TABLE"); - if (myOp == NULL) - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - - myOp->deleteTuple(); - if (myOp->equal("X", i) == -1) { - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - myNdb.closeTransaction(myTrans); - break; - } - before = NdbTick_CurrentMillisecond(); - if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1) - { - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - myNdb.closeTransaction(myTrans); - break; - } - } - after = NdbTick_CurrentMillisecond(); - if (noOfOperations == 1) - printf("Deleted 1 tuple, %u msec\n", (Uint32) after - before); - else - printf("Deleted %u tuples, %u msec\n", noOfOperations, (Uint32) after - before); - - if (!oneTrans) myNdb.closeTransaction(myTrans); - } - if (oneTrans) { - if (myTrans->execute( Commit ) == -1) { - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - } - myNdb.closeTransaction(myTrans); - } - tafter = NdbTick_CurrentMillisecond(); - - ndbout << "Deleted "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl; -} - -static void readTable(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool oneTrans, bool twoKey, bool longKey) -{ - Uint64 tbefore, tafter, before, after; - NdbConnection *myTrans; - NdbOperation *myOp; - NdbRecAttr* myRecAttrArr[MAX_NO_PARALLEL_OPERATIONS]; - - tbefore = NdbTick_CurrentMillisecond(); - if (oneTrans) myTrans = myNdb.startTransaction(); - for (unsigned int i = 0; igetNdbOperation("THE_TABLE"); - if (myOp == NULL) - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - - myOp->readTuple(); - if (myOp->equal("X", i) == -1) { - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - myNdb.closeTransaction(myTrans); - break; - } - myRecAttrArr[j-1] = myOp->getValue("Y", NULL); - } - before = NdbTick_CurrentMillisecond(); - if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1) - { - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - myNdb.closeTransaction(myTrans); - break; - } - after = NdbTick_CurrentMillisecond(); - if (noOfOperations == 1) - printf("Read 1 tuple, %u msec\n", (Uint32) after - before); - else - printf("Read %u tuples, %u msec\n", noOfOperations, (Uint32) after - before); - for(unsigned int j = 0; ju_32_value()); - if (!oneTrans) myNdb.closeTransaction(myTrans); - } - if (oneTrans) { - if (myTrans->execute( Commit ) == -1) { - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - } - myNdb.closeTransaction(myTrans); - } - tafter = NdbTick_CurrentMillisecond(); - - ndbout << "Read "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl; -} - -static void readIndex(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool includePrimary, bool oneTrans, bool longKey) -{ - Uint64 tbefore, tafter, before, after; - NdbConnection *myTrans; - NdbIndexOperation *myOp; - char indexName[] = "INDEX0000"; - NdbRecAttr* myRecAttrArr[MAX_NO_PARALLEL_OPERATIONS]; - - tbefore = NdbTick_CurrentMillisecond(); - if (oneTrans) myTrans = myNdb.startTransaction(); - for (unsigned int i = 0; igetNdbIndexOperation(indexName, "THE_TABLE"); - if (myOp == NULL) - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - - myOp->readTuple(); - if (includePrimary) { - if (myOp->equal("X", i) == -1) { - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - myNdb.closeTransaction(myTrans); - break; - } - } - if (myOp->equal("Y", i+1) == -1) { - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - myNdb.closeTransaction(myTrans); - break; - } - myRecAttrArr[j-1] = myOp->getValue("Y", NULL); - } - before = NdbTick_CurrentMillisecond(); - if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1) - { - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - myNdb.closeTransaction(myTrans); - break; - } - after = NdbTick_CurrentMillisecond(); - if (noOfOperations == 1) - printf("Read 1 tuple, %u msec\n", (Uint32) after - before); - else - printf("Read %u tuples, %u msec\n", noOfOperations, (Uint32) after - before); - for(unsigned int j = 0; ju_32_value()); - if (!oneTrans) myNdb.closeTransaction(myTrans); - } - if (oneTrans) { - if (myTrans->execute( Commit ) == -1) { - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - } - myNdb.closeTransaction(myTrans); - } - tafter = NdbTick_CurrentMillisecond(); - - ndbout << "Read "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl; -} - -static void updateIndex(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool includePrimary, bool oneTrans, bool longKey) -{ - Uint64 tbefore, tafter, before, after; - NdbConnection *myTrans; - NdbIndexOperation *myOp; - char indexName[] = "INDEX0000"; - - tbefore = NdbTick_CurrentMillisecond(); - if (oneTrans) myTrans = myNdb.startTransaction(); - for (unsigned int i = 0; igetNdbIndexOperation(indexName, "THE_TABLE"); - if (myOp == NULL) - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - - myOp->updateTuple(); - if (includePrimary) { - if (myOp->equal("X", i) == -1) { - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - myNdb.closeTransaction(myTrans); - break; - } - } - if (myOp->equal("Y", i+1) == -1) { - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - myNdb.closeTransaction(myTrans); - break; - } - // Update index itself, should be possible - if (myOp->setValue("Y", i+2) == -1) { - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - myNdb.closeTransaction(myTrans); - break; - } - } - before = NdbTick_CurrentMillisecond(); - if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1) - { - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - myNdb.closeTransaction(myTrans); - break; - } - - after = NdbTick_CurrentMillisecond(); - if (noOfOperations == 1) - printf("Updated 1 tuple, %u msec\n", (Uint32) after - before); - else - printf("Updated %u tuples, %u msec\n", noOfOperations, (Uint32) after - before); - if (!oneTrans) myNdb.closeTransaction(myTrans); - } - if (oneTrans) { - if (myTrans->execute( Commit ) == -1) { - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - } - myNdb.closeTransaction(myTrans); - } - tafter = NdbTick_CurrentMillisecond(); - - ndbout << "Updated "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl; -} - -static void deleteIndex(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool includePrimary, bool oneTrans, bool longKey) -{ - Uint64 tbefore, tafter, before, after; - NdbConnection *myTrans; - NdbIndexOperation *myOp; - char indexName[] = "INDEX0000"; - - tbefore = NdbTick_CurrentMillisecond(); - if (oneTrans) myTrans = myNdb.startTransaction(); - for (unsigned int i = 0; igetNdbIndexOperation(indexName, "THE_TABLE"); - if (myOp == NULL) - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - - myOp->deleteTuple(); - if (includePrimary) { - if (myOp->equal("X", i) == -1) { - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - myNdb.closeTransaction(myTrans); - break; - } - } - if (myOp->equal("Y", i+1) == -1) { - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - myNdb.closeTransaction(myTrans); - break; - } - } - before = NdbTick_CurrentMillisecond(); - if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1) - { - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - myNdb.closeTransaction(myTrans); - break; - } - after = NdbTick_CurrentMillisecond(); - if (noOfOperations == 1) - printf("Deleted 1 tuple, %u msec\n", (Uint32) after - before); - else - printf("Deleted %u tuples, %u msec\n", noOfOperations, (Uint32) after - before); - if (!oneTrans) myNdb.closeTransaction(myTrans); - } - if (oneTrans) { - if (myTrans->execute( Commit ) == -1) { - error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification, - myTrans->getNdbError().code, myTrans->getNdbError().message); - } - myNdb.closeTransaction(myTrans); - } - tafter = NdbTick_CurrentMillisecond(); - - ndbout << "Deleted "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl; -} - -static void dropIndex(Ndb &myNdb, unsigned int noOfIndexes) -{ - for(unsigned int indexNum = 0; indexNum < noOfIndexes; indexNum++) { - char indexName[255]; - sprintf(indexName, "INDEX%.4u", indexNum); - const Uint64 before = NdbTick_CurrentMillisecond(); - const int retVal = myNdb.getDictionary()->dropIndex(indexName,"THE_TABLE"); - const Uint64 after = NdbTick_CurrentMillisecond(); - - if(retVal == 0){ - ndbout << "Dropped index " << indexName << ", " - << after - before << " msec" << endl; - } else { - ndbout << "Failed to drop index " << indexName << endl; - ndbout << myNdb.getDictionary()->getNdbError() << endl; - } - } -} - -NDB_COMMAND(indexTest, "indexTest", "indexTest", "indexTest", 65535) -{ - bool createTableOp, createIndexOp, dropIndexOp, insertOp, updateOp, deleteOp, readOp, readIndexOp, updateIndexOp, deleteIndexOp, twoKey, longKey; - unsigned int noOfTuples = 1; - unsigned int noOfOperations = 1; - unsigned int noOfIndexes = 1; - int i = 1; - Ndb myNdb( "TEST_DB" ); - int check; - bool storeInACC = false; - bool includePrimary = false; - bool oneTransaction = false; - - createTableOp = createIndexOp = dropIndexOp = insertOp = updateOp = deleteOp = readOp = readIndexOp = updateIndexOp = deleteIndexOp = twoKey = longKey = false; - // Read arguments - if (argc > 1) - while (argc > 1) - { - if (strcmp(argv[i], "-T") == 0) - { - createTableOp = true; - argc -= 1; - i++; - } - else if (strcmp(argv[i], "-c") == 0) - { - createIndexOp = true; - argc -= 1; - i++; - } - else if (strcmp(argv[i], "-X") == 0) - { - dropIndexOp = true; - argc -= 1; - i++; - } - else if (strcmp(argv[i], "-I") == 0) - { - insertOp = true; - argc -= 1; - i++; - } - else if (strcmp(argv[i], "-D") == 0) - { - deleteOp = true; - argc -= 1; - i++; - } - else if (strcmp(argv[i], "-U") == 0) - { - updateOp = true; - argc -= 1; - i++; - } - else if (strcmp(argv[i], "-R") == 0) - { - readOp = true; - argc -= 1; - i++; - } - else if (strcmp(argv[i], "-r") == 0) - { - readIndexOp = true; - argc -= 1; - i++; - } - else if (strcmp(argv[i], "-u") == 0) - { - updateIndexOp = true; - argc -= 1; - i++; - } - else if (strcmp(argv[i], "-d") == 0) - { - deleteIndexOp = true; - argc -= 1; - i++; - } - else if (strcmp(argv[i], "-s") == 0) - { - storeInACC = true; - argc -= 1; - i++; - } - else if (strcmp(argv[i], "-p") == 0) - { - includePrimary = true; - argc -= 1; - i++; - } - else if (strcmp(argv[i], "-L") == 0) - { - longKey = true; - argc -= 1; - i++; - } - else if (strcmp(argv[i], "-1") == 0) - { - oneTransaction = true; - argc -= 1; - i++; - } - else if (strcmp(argv[i], "-2") == 0) - { - twoKey = true; - argc -= 1; - i++; - } - else if (strstr(argv[i], "-n") != 0) - { - noOfTuples = atoi(argv[i]+2); - argc -= 1; - i++; - } - else if (strstr(argv[i], "-o") != 0) - { - noOfOperations = MIN(MAX_NO_PARALLEL_OPERATIONS, atoi(argv[i]+2)); - argc -= 1; - i++; - } - else if (strstr(argv[i], "-m") != 0) - { - noOfIndexes = atoi(argv[i]+2); - argc -= 1; - i++; - } - else if (strstr(argv[i], "-h") != 0) - { - printf("Synopsis: \ - index\ - -T create table\ - -L include a long attribute in key or index\ - -2 define primary key with two attributes\ - -c create index\ - -p make index unique (include primary key attribute)\ - -r read using index\ - -u update using index\ - -d delete using index\ - -n do n operations (for -I -r -u -d -R -U -D)\ - -o (for -I -r -u -d -R -U -D)\ - -m\n"); - argc -= 1; - i++; - } - else { - char errStr[256]; - - sprintf(errStr, "Illegal argument: %s", argv[i]); - error_handler(errStr); - exit(-1); - } - } - else - { - createTableOp = createIndexOp = dropIndexOp = insertOp = updateOp = deleteOp = true; - } - if (longKey) { - longName = (char *) malloc(1024); - for (int i = 0; i < 1023; i++) - longName[i] = 'x'; - longName[1023] = '\0'; - } - sixtysix = (char *) malloc(256); - for (int i = 0; i < 255; i++) - sixtysix[i] = ' '; - sixtysix[255] = '\0'; - strncpy(sixtysix, "sixtysix", strlen("sixtysix")); - ninetynine = (char *) malloc(256); - for (int i = 0; i < 255; i++) - ninetynine[i] = ' '; - ninetynine[255] = '\0'; - strncpy(ninetynine, "ninetynine", strlen("ninetynine")); - hundred = (char *) malloc(256); - for (int i = 0; i < 255; i++) - hundred[i] = ' '; - hundred[255] = '\0'; - strncpy(hundred, "hundred", strlen("hundred")); - myNdb.init(); - // Wait for Ndb to become ready - if (myNdb.waitUntilReady(30) == 0) - { - if (createTableOp) - createTable(myNdb, storeInACC, twoKey, longKey); - - if (createIndexOp) - createIndex(myNdb, includePrimary, noOfIndexes); - - if (insertOp) - insertTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey); - - if (updateOp) - updateTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey); - - if (deleteOp) - deleteTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey); - - if (readOp) - readTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey); - - if (readIndexOp) - readIndex(myNdb, noOfTuples, noOfOperations, includePrimary, oneTransaction, longKey); - - if (updateIndexOp) - updateIndex(myNdb, noOfTuples, noOfOperations, includePrimary, oneTransaction, longKey); - - if (deleteIndexOp) - deleteIndex(myNdb, noOfTuples, noOfOperations, includePrimary, oneTransaction, longKey); - - if (dropIndexOp) - dropIndex(myNdb, noOfIndexes); - } - - if (testPassed) - { - // Test passed - ndbout << "OK - Test passed" << endl; - } - else - { - // Test failed - ndbout << "FAIL - Test failed" << endl; - exit(-1); - } - return NULL; -} - - diff --git a/ndb/test/ndbapi/initronja.cpp b/ndb/test/ndbapi/initronja.cpp new file mode 100644 index 00000000000..f3f4d9628e2 --- /dev/null +++ b/ndb/test/ndbapi/initronja.cpp @@ -0,0 +1,349 @@ +/* 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 */ + + +/* *************************************************** + INITRONJA + Initialise benchmark for Ronja Database + * *************************************************** */ + +#include "NdbApi.hpp" +#include +#include +#include +#include + +#define MAXSTRLEN 16 +#define MAXATTR 64 +#define MAXTABLES 64 +#define MAXTHREADS 256 +#define MAXATTRSIZE 8000 + +static unsigned int tNoOfRecords; +static unsigned int tNoOfLoops; +static unsigned int tNoOfTables; +static int tAttributeSize; +static int tNodeId; +static unsigned int tValue; +static unsigned int tNoOfOperations; +static char tableName[MAXTABLES][MAXSTRLEN]; +static char attrName[MAXATTR][MAXSTRLEN]; + +inline int InsertRecords(Ndb*, int) ; + +NDB_COMMAND(initronja, "initronja", "initronja", "initronja", 65535){ + + Ndb* pNdb = NULL ; + NdbSchemaCon *MySchemaTransaction = NULL ; + NdbSchemaOp *MySchemaOp = NULL ; + + + int check, status, i, j, cont ; + check = status = i = j = cont = 0 ; + tNoOfRecords = 500 ; + tNoOfLoops = tNoOfRecords / 10; + + i = 1; + while (argc > 1){ + + if (strcmp(argv[i], "-r") == 0){ + if( NULL == argv[i+1] ) goto error_input ; + tNoOfRecords = atoi(argv[i+1]); + tNoOfRecords = tNoOfRecords - (tNoOfRecords % 10); + tNoOfLoops = tNoOfRecords / 10; + if ((tNoOfRecords < 1) || (tNoOfRecords > 1000000000)) goto error_input; + }else{ + goto error_input; + } + + argc -= 2; + i = i + 2; // + } + + pNdb = new Ndb( "TEST_DB" ) ; + ndbout << "Initialisation started. " << endl; + pNdb->init(); + ndbout << "Initialisation completed. " << endl; + + tNodeId = pNdb->getNodeId(); + ndbout << endl << "Initial loading of Ronja Database" << endl; + ndbout << " NdbAPI node with id = " << tNodeId << endl; + + if (pNdb->waitUntilReady(30) != 0) { + ndbout << "Benchmark failed - NDB is not ready" << endl; + delete pNdb ; + return NDBT_ProgramExit(NDBT_FAILED) ; + }//if + + ndbout << endl << "Creating the table SHORT_REC" << "..." << endl; + + MySchemaTransaction = pNdb->startSchemaTransaction(); + if(!MySchemaTransaction) goto error_handler; + MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); + if(!MySchemaOp) goto error_handler; +#if defined NDB_OSE || defined NDB_SOFTOSE + check = MySchemaOp->createTable( "SHORT_REC" + ,8 // Table Size + ,TupleKey // Key Type + ,40 // Nr of Pages + ,All + ,6 + ,78 + ,80 + ,1 + ,false); +#else + check = MySchemaOp->createTable( "SHORT_REC" + ,8 // Table Size + ,TupleKey // Key Type + ,40 // Nr of Pages + ); +#endif + if (check == -1) goto error_handler; + + ndbout << "Key attribute..." ; + check = MySchemaOp->createAttribute( (char*)"Key", TupleKey, 32, 1, + UnSigned, MMBased, NotNullAttribute ); + if (check == -1) goto error_handler; + ndbout << "\t\tOK" << endl ; + + ndbout << "Flip attribute..." ; + check = MySchemaOp->createAttribute("Flip", NoKey, 32, 1, + UnSigned, MMBased, NotNullAttribute ); + if (check == -1) goto error_handler; + ndbout << "\t\tOK" << endl ; + + ndbout << "Count attribute..." ; + check = MySchemaOp->createAttribute("Count", NoKey, 32, 1, + UnSigned, MMBased, NotNullAttribute ); + if (check == -1) goto error_handler; + ndbout << "\t\tOK" << endl ; + + ndbout << "Placeholder attribute..." ; + check = MySchemaOp->createAttribute("Placeholder", NoKey, 8, 90, + UnSigned, MMBased, NotNullAttribute ); + if (check == -1) goto error_handler; + ndbout << "\tOK" << endl ; + + if (MySchemaTransaction->execute() == -1) { + if(721 == MySchemaOp->getNdbError().code){ + ndbout << "Table SHORT_REC already exists" << endl ; + }else{ + ndbout << MySchemaTransaction->getNdbError() << endl; + } + }else{ + ndbout << "SHORT_REC created " << endl; + }// if + + pNdb->closeSchemaTransaction(MySchemaTransaction); + + ndbout << endl << "Creating the table LONG_REC..." << endl; + + MySchemaTransaction = pNdb->startSchemaTransaction(); + if(!MySchemaTransaction) goto error_handler; + + MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); + if(!MySchemaOp) goto error_handler; +#if defined NDB_OSE || defined NDB_SOFTOSE + check = MySchemaOp->createTable( "LONG_REC" + ,8 // Table Size + ,TupleKey // Key Type + ,40 // Nr of Pages + ,All + ,6 + ,78 + ,80 + ,1 + ,false); +#else + check = MySchemaOp->createTable( "LONG_REC" + ,8 // Table Size + ,TupleKey // Key Type + ,40 // Nr of Pages + ); +#endif + + if (check == -1) goto error_handler; + + ndbout << "Key attribute..." ; + check = MySchemaOp->createAttribute( (char*)"Key", TupleKey, 32, 1, + UnSigned, MMBased, NotNullAttribute ); + if (check == -1) goto error_handler; + ndbout << "\t\tOK" << endl ; + + ndbout << "Flip attribute..." ; + check = MySchemaOp->createAttribute("Flip", NoKey, 32, 1, + UnSigned, MMBased, NotNullAttribute ); + if (check == -1) goto error_handler; + ndbout << "\t\tOK" << endl ; + + ndbout << "Count attribute..." ; + check = MySchemaOp->createAttribute("Count", NoKey, 32, 1, + UnSigned, MMBased, NotNullAttribute ); + if (check == -1) goto error_handler; + ndbout << "\t\tOK" << endl ; + + ndbout << "Placeholder attribute..." ; + check = MySchemaOp->createAttribute("Placeholder", NoKey, 8, 1014, + UnSigned, MMBased, NotNullAttribute ); + if (check == -1) goto error_handler; + ndbout << "\tOK" << endl ; + + if (MySchemaTransaction->execute() == -1) { + if(721 == MySchemaOp->getNdbError().code){ + ndbout << "Table LONG_REC already exists" << endl ; + }else{ + ndbout << MySchemaTransaction->getNdbError() << endl; + } + }else{ + ndbout << "LONG_REC created" << endl; + }// if + + pNdb->closeSchemaTransaction(MySchemaTransaction); + + + check = InsertRecords(pNdb, tNoOfRecords); + + delete pNdb ; + + if(-1 == check){ + ndbout << endl << "Initial loading of Ronja Database failed" << endl; + return NDBT_ProgramExit(NDBT_FAILED) ; + }else{ + ndbout << endl << "Initial loading of Ronja Database completed" << endl; + return NDBT_ProgramExit(NDBT_OK) ; + } + + + + + +error_handler: + ndbout << "SchemaTransaction returned error:" ; + ndbout << MySchemaTransaction->getNdbError() << endl; + pNdb->closeSchemaTransaction(MySchemaTransaction); + delete pNdb ; + NDBT_ProgramExit(NDBT_FAILED) ; + exit(-1); + +error_input: + ndbout << endl << " Ivalid parameter(s)" << endl; + ndbout << " Usage: initronja [-r n] , where 'n' is the number of records to be inserted" << endl; + ndbout << " If omitted, 500 records will be created by default" << endl; + ndbout << " Note: use this number in combination with '-r' argument when running 'benchronja'" << endl << endl; + NDBT_ProgramExit(NDBT_WRONGARGS) ; + exit(1); +} +//////////////////////////////////////// + +inline int InsertRecords(Ndb* pNdb, int nNoRecords){ + + NdbConnection *MyTransaction = NULL ; + NdbOperation* MyOperation[10]; + + int Tsuccess = 0 ; + int loop_count_ops = 2 * tNoOfLoops; + int loop_count_tables = 10; + int loop_count_attributes = 0 ; + int check = 0; + int count = 0 ; + int count_tables = 0; + int count_attributes = 0 ; + int i = 0 ; + int tType = 0 ; + unsigned int attrValue[1000]; + unsigned int setAttrValue = 0; + unsigned int keyValue[3]; + + for (i = 0; i < 1000; i ++) attrValue[i] = 1; + + for (count=0 ; count < loop_count_ops ; count++){ + if ((((count / 100)* 100) == count) && (count != 0)){ + ndbout << "1000 records inserted again, " << (count/100) << "000 records now inserted" << endl; + } + + MyTransaction = pNdb->startTransaction(); + if(!MyTransaction){ + ndbout << "startTransaction: " << pNdb->getNdbError(); + ndbout << " count = " << count << endl; + return -1 ; + } + + for (count_tables = 0; count_tables < loop_count_tables; count_tables++) { + if (count < tNoOfLoops) { + keyValue[0] = count*10 + count_tables ; + MyOperation[count_tables] = MyTransaction->getNdbOperation("SHORT_REC") ; + }else{ + keyValue[0] = (count - tNoOfLoops)*10 + count_tables; + MyOperation[count_tables] = MyTransaction->getNdbOperation("LONG_REC"); + }//if + + if (!MyOperation[count_tables]) goto error_handler1; + + check = MyOperation[count_tables]->insertTuple(); + if (check == -1) goto error_handler2; + + check = MyOperation[count_tables]->equal("Key",(char*)&keyValue[0]); + if (check == -1) goto error_handler4; + + check = MyOperation[count_tables]->setValue("Flip",(char*)&setAttrValue); + if (check == -1) goto error_handler5; + + check = MyOperation[count_tables]->setValue("Count",(char*)&setAttrValue); + if (check == -1) goto error_handler5; + + check = MyOperation[count_tables]->setValue("Placeholder",(char*)&attrValue[0]); + if (check == -1) goto error_handler5; + }//for + + if (MyTransaction->execute( Commit ) == -1){ + ndbout << MyTransaction->getNdbError()<< endl ; + ndbout << "count = " << count << endl; + }//if + + pNdb->closeTransaction(MyTransaction) ; + }//for + return 0; + +error_handler1: + ndbout << "Error occured in getNdbOperation " << endl; + ndbout << MyTransaction->getNdbError() << endl; + pNdb->closeTransaction(MyTransaction); + return -1 ; + +error_handler2: + ndbout << "Error occured in defining operation " << endl; + ndbout << MyOperation[count_tables]->getNdbError() << endl; + pNdb->closeTransaction(MyTransaction); + return -1 ; + +error_handler3: + pNdb->closeTransaction(MyTransaction); + return -1 ; + +error_handler4: + ndbout << "Error occured in equal " << endl; + ndbout << MyOperation[count_tables]->getNdbError() << endl; + pNdb->closeTransaction(MyTransaction); + return -1 ; + +error_handler5: + ndbout << "Error occured in get/setValue " << endl; + ndbout << MyOperation[count_tables]->getNdbError() << endl; + pNdb->closeTransaction(MyTransaction); + return -1 ; + +} diff --git a/ndb/test/ndbapi/interpreterInTup.cpp b/ndb/test/ndbapi/interpreterInTup.cpp new file mode 100644 index 00000000000..a2352edf707 --- /dev/null +++ b/ndb/test/ndbapi/interpreterInTup.cpp @@ -0,0 +1,1524 @@ +/* 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 */ + +/* *************************************************** + TEST OF INTERPRETER IN TUP + Verify that the interpreter in TUP is able to + handle and execute all the commands that the + NdbApi can isssue + + Arguments: + + operationType 1 openScanRead, + 2 openScanExclusive, + 3 interpretedUpdateTuple, + 4 interpretedDirtyUpdate, + 5 interpretedDeleteTuple + 6 deleteTuple + 7 insertTuple + 8 updateTuple + 9 writeTuple + 10 readTuple + 11 readTupleExclusive + 12 simpleRead + 13 dirtyRead + 14 dirtyUpdate + 15 dirtyWrite + + tupTest 1 exitMethods + 2 incValue + 3 subValue + 4 readAttr + 5 writeAttr + 6 loadConst + 7 branch + 8 branchIfNull + 9 addReg + 10 subReg + 11 subroutineWithBranchLabel + + scanTest Number of the test within each tupTest + +* *************************************************** */ + +#include +#include +#include +#include +#include + +#define MAXATTR 3 +#define MAXTABLES 12 +#define MAXSTRLEN 8 +#define NUMBEROFRECORDS 1000 + +typedef enum { + FAIL = 0, + NO_FAIL, + UNDEF +} TTYPE; + +inline void setAttrNames() ; +inline void setTableNames() ; +void error_handler(const NdbError & err, TTYPE); +void create_table(Ndb*); +void write_rows(Ndb*); +void update_rows(Ndb*, int, int); +void delete_rows(Ndb*, int, int); +void verify_deleted(Ndb*); +void read_and_verify_rows(Ndb*, bool pre); +void scan_rows(Ndb*, int, int, int); +TTYPE t_exitMethods(int, NdbOperation*, int); +TTYPE t_incValue(int, NdbOperation*); +TTYPE t_subValue(int, NdbOperation*); +TTYPE t_readAttr(int, NdbOperation*); +TTYPE t_writeAttr(int, NdbOperation*); +TTYPE t_loadConst(int, NdbOperation*, int); +TTYPE t_branch(int, NdbOperation*); +TTYPE t_branchIfNull(int, NdbOperation*); +TTYPE t_addReg(int, NdbOperation*); +TTYPE t_subReg(int, NdbOperation*); +TTYPE t_subroutineWithBranchLabel(int, NdbOperation*); + +char tableName[MAXTABLES][MAXSTRLEN+1] = {0}; +char attrName[MAXATTR][MAXSTRLEN+1] = {0}; +int attrValue[NUMBEROFRECORDS] = {0}; +int pkValue[NUMBEROFRECORDS] = {0}; +const int tAttributeSize = 1 ; +const int nRecords = 20 ; +int bTestPassed = 0; + + + +int main(int argc, const char** argv) { + + int tTableId = 0; + int operationType = 0; + int tupTest = 0 ; + int scanTest = 0 ; + bool loop = 0 ; + + Ndb* pNdb = new Ndb("TEST_DB"); + pNdb->init(); + + if (argc != 4 || sscanf(argv[1],"%d", &operationType) != 1) { + operationType = 1 ; + } + if (argc != 4 || sscanf(argv[2],"%d", &tupTest) != 1) { + tupTest = 1 ; + } + if (argc != 4 || sscanf(argv[3],"%d", &scanTest) != 1) { + scanTest = 1 ; + } + + ndbout << endl + << "Test the interpreter in TUP using SimpleTable with\n" + << nRecords << " records" << endl << endl ; + + if (pNdb->waitUntilReady(30) != 0) { + ndbout << "NDB is not ready" << endl; + return -1; + } + + // Init the pk and attr values. + for (int i = 0; i < NUMBEROFRECORDS; i ++) + pkValue[i] = attrValue[i] = i ; + + setAttrNames() ; + setTableNames() ; + + const void * p = NDBT_Table::discoverTableFromDb(pNdb, tableName[0]); + if (p != 0){ + create_table(pNdb); + } + + write_rows(pNdb); + + ndbout << endl << "Starting interpreter in TUP test." << endl << "Operation type: " ; + + switch(operationType) { + case 1: + ndbout << "openScanRead" << endl; + scan_rows(pNdb, operationType, tupTest, scanTest); + break; + case 2: + ndbout << "openScanExclusive" << endl; + scan_rows(pNdb, operationType, tupTest, scanTest); + break; + case 3: + ndbout << "interpretedUpdateTuple" << endl; + update_rows(pNdb, tupTest, operationType); + break; + case 4: + ndbout << "interpretedDirtyUpdate" << endl; + update_rows(pNdb, tupTest, operationType); + break; + case 5: + ndbout << "interpretedDeleteTuple" << endl; + delete_rows(pNdb, tupTest, operationType); + break; + case 6: + ndbout << "deleteTuple" << endl; + break; + case 7: + ndbout << "insertTuple" << endl; + break; + case 8: + ndbout << "updateTuple" << endl; + break; + case 9: + ndbout << "writeTuple" << endl; + break; + case 10: + ndbout << "readTuple" << endl; + break; + case 11: + ndbout << "readTupleExclusive" << endl; + break; + case 12: + ndbout << "simpleRead" << endl; + break; + case 13: + ndbout << "dirtyRead" << endl; + break; + case 14: + ndbout << "dirtyUpdate" << endl; + break; + case 15: + ndbout << "dirtyWrite" << endl; + break; + default: + break ; + + } + +// read_and_verify_rows(pNdb, false); + +// delete_rows(pNdb, 0, 0) ; + delete pNdb ; + + if (bTestPassed == 0) { + ndbout << "OK: test passed" << endl; + exit(0); + }else{ + ndbout << "FAIL: test failed" << endl; + exit(-1); + } +} + +void error_handler(const NdbError & err, TTYPE type_expected) { + + ndbout << err << endl ; + + switch (type_expected){ + case NO_FAIL: + bTestPassed = -1 ; + break ; + case FAIL: + ndbout << "OK: error is expected" << endl; + break ; + case UNDEF: + ndbout << "assumed OK: expected result undefined" << endl ; + break ; + default: + break ; + } +} + +void create_table(Ndb* pMyNdb) { + + /**************************************************************** + * Create SimpleTable and Attributes. + * + * create table SimpleTable1( + * col0 int, + * col1 int not null, + * col2 int not null, + * col3 int not null ... 129) + * + ***************************************************************/ + + int check = -1 ; + NdbSchemaCon *MySchemaTransaction = NULL ; + NdbSchemaOp *MySchemaOp = NULL ; + + ndbout << endl << "Creating " << tableName[0] << " ... " << endl; + + MySchemaTransaction = pMyNdb->startSchemaTransaction(); + if(!MySchemaTransaction) error_handler(MySchemaTransaction->getNdbError(), NO_FAIL); + + MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); + if( !MySchemaOp ) error_handler(MySchemaTransaction->getNdbError(), NO_FAIL); + // Create table + check = MySchemaOp->createTable( tableName[0], + 8, // Table size + TupleKey, // Key Type + 40 // Nr of Pages + ); + + if( check == -1 ) error_handler(MySchemaTransaction->getNdbError(), NO_FAIL); + + ndbout << "Creating attributes ... " << flush; + + // Create first column, primary key + check = MySchemaOp->createAttribute( attrName[0], + TupleKey, + 32, + 1/*3, tAttributeSize */, + UnSigned, + MMBased, + NotNullAttribute ); + + if( check == -1 ) error_handler(MySchemaTransaction->getNdbError(), NO_FAIL); + + // create the 2 .. n columns. + for ( int i = 1; i < MAXATTR; i++ ){ + check = MySchemaOp->createAttribute( attrName[i], + NoKey, + 32, + tAttributeSize, + UnSigned, + MMBased, + NotNullAttribute ); + + if( check == -1 ) error_handler(MySchemaTransaction->getNdbError(), NO_FAIL); + } + + ndbout << "OK" << endl; + + if( MySchemaTransaction->execute() == -1 ) { + ndbout << MySchemaTransaction->getNdbError() << endl; + }else{ + ndbout << tableName[0] << " created" << endl; + } + + pMyNdb->closeSchemaTransaction(MySchemaTransaction); + + return; + +} + + + +void write_rows (Ndb* pMyNdb) { + + /**************************************************************** + * Insert rows into SimpleTable + * + ***************************************************************/ + + int check = -1 ; + int loop_count_ops = nRecords ; + NdbOperation *MyOperation = NULL ; + NdbConnection *MyTransaction = NULL ; + + ndbout << endl << "Writing records ..." << flush; + + for (int count=0 ; count < loop_count_ops ; count++){ + MyTransaction = pMyNdb->startTransaction(); + if (!MyTransaction) { + error_handler(pMyNdb->getNdbError(), NO_FAIL); + }//if + + MyOperation = MyTransaction->getNdbOperation(tableName[0]); + if (!MyOperation) { + error_handler(pMyNdb->getNdbError(), NO_FAIL); + }//if + + check = MyOperation->writeTuple(); + if( check == -1 ) error_handler(MyTransaction->getNdbError(), NO_FAIL); + + check = MyOperation->equal( attrName[0],(char*)&pkValue[count] ); + if( check == -1 ) error_handler(MyTransaction->getNdbError(), NO_FAIL); + + // Update the columns, index column already ok. + for (int i = 1 ; i < MAXATTR; i++){ + if ((i == 2) && (count > 4)){ + check = MyOperation->setValue(attrName[i], (char*)&attrValue[count + 1]); + }else{ + check = MyOperation->setValue(attrName[i], (char*)&attrValue[count]); + } + if( check == -1 ) error_handler(MyTransaction->getNdbError(), NO_FAIL); + } + check = MyTransaction->execute( Commit ); + if(check == -1 ) error_handler(MyTransaction->getNdbError(), NO_FAIL); + + pMyNdb->closeTransaction(MyTransaction); + } + ndbout <<" \tOK" << endl; + return; +} + +void verify_deleted(Ndb* pMyNdb) { + + int check = -1 ; + int loop_count_ops = nRecords; + NdbRecAttr* tTmp; + int readValue[MAXATTR]; + NdbConnection* pMyTransaction = NULL ; + NdbOperation* pMyOperation = NULL ; + + ndbout << "Verifying deleted records..."<< flush; + + for (int count=0 ; count < loop_count_ops ; count++){ + + NdbConnection* pMyTransaction = pMyNdb->startTransaction(); + if (!pMyTransaction) error_handler(pMyNdb->getNdbError(), NO_FAIL); + + pMyOperation = pMyTransaction->getNdbOperation(tableName[0]); + if (!pMyOperation) error_handler(pMyNdb->getNdbError(), NO_FAIL); + + check = pMyOperation->readTuple(); + if( check == -1 ) error_handler( pMyTransaction->getNdbError(), NO_FAIL); + + check = pMyOperation->equal( attrName[0],(char*)&pkValue[count] ); + if( check == -1 ) error_handler( pMyTransaction->getNdbError(), NO_FAIL); + + // Exepect to receive an error + if(pMyTransaction->execute(Commit) != -1) + if( 626 == pMyTransaction->getNdbError().code){ + ndbout << pMyTransaction->getNdbError() << endl ; + ndbout << "OK" << endl ; + }else{ + error_handler(pMyTransaction->getNdbError(), NO_FAIL) ; + } + + pMyNdb->closeTransaction(pMyTransaction); + } + + ndbout << "OK" << endl; + return; +}; + +void read_and_verify_rows(Ndb* pMyNdb, bool pre) { + + int check = -1 ; + int loop_count_ops = nRecords; + char expectedCOL1[NUMBEROFRECORDS] = {0} ; + char expectedCOL2[NUMBEROFRECORDS] = {0} ; + NdbConnection *pMyTransaction = NULL ; + NdbOperation *MyOp = NULL ; + NdbRecAttr* tTmp = NULL ; + int readValue[MAXATTR] = {0} ; + + ndbout << "Verifying records...\n"<< endl; + + for (int count=0 ; count < loop_count_ops ; count++){ + + pMyTransaction = pMyNdb->startTransaction(); + if (!pMyTransaction) error_handler(pMyNdb->getNdbError(), NO_FAIL); + + MyOp = pMyTransaction->getNdbOperation(tableName[0]); + if (!MyOp) error_handler( pMyTransaction->getNdbError(), NO_FAIL); + + + check = MyOp->readTuple(); + if( check == -1 ) error_handler( MyOp->getNdbError(), NO_FAIL); + + check = MyOp->equal( attrName[0],(char*)&pkValue[count] ); + if( check == -1 ) error_handler( MyOp->getNdbError(), NO_FAIL); + + for (int count_attributes = 1; count_attributes < MAXATTR; count_attributes++){ + + tTmp = MyOp->getValue( (char*)attrName[count_attributes], (char*)&readValue[count_attributes] ); + if(!tTmp) error_handler( MyOp->getNdbError(), NO_FAIL); + } + + if( pMyTransaction->execute( Commit ) == -1 ) { + error_handler(pMyTransaction->getNdbError(), NO_FAIL); + } else { + if (pre) { + expectedCOL1[count] = readValue[1]; + expectedCOL2[count] = readValue[2]; + } + + ndbout << attrName[1] << "\t " << readValue[1] << "\t " + << attrName[2] << "\t " << readValue[2] << endl; + } + + pMyNdb->closeTransaction(pMyTransaction); + + } + + ndbout << "\nOK\n" << endl; + + return; + +}; + +TTYPE t_exitMethods(int nCalls, NdbOperation * pOp, int opType) { + + ndbout << "Defining exitMethods test " << nCalls << ": " << endl ;; + TTYPE ret_val = NO_FAIL ; + + switch(nCalls){ + case 1: // exit_nok if attr value matches + pOp->read_attr("COL1", 1); + pOp->load_const_u32(2, 14); + pOp->branch_eq(1, 2, 0); + pOp->interpret_exit_ok() ; + pOp->def_label(0); + pOp->interpret_exit_nok(); + break; + case 2: // exit_ok if attr value doesn't match + pOp->read_attr("COL1", 1); + pOp->load_const_u32(2, 14); + pOp->branch_eq(1, 2, 0); + pOp->interpret_exit_nok() ; + pOp->def_label(0); + if (opType == 3) { + // For update transactions use incValue to update the tuple + Uint32 val32 = 5; + pOp->incValue("COL2", val32); + } + pOp->interpret_exit_ok(); + break ; + case 3: // Non-existent value (128): exit_ok if if the value matches + pOp->read_attr("COL1", 1); + pOp->load_const_u32(2, 128); + pOp->branch_eq(1, 2, 0); + pOp->interpret_exit_nok(); + pOp->def_label(0); + pOp->interpret_exit_ok(); + ret_val = FAIL ; + break; + case 4: // Non-existent value (128): exit_nok if the value matches + pOp->read_attr("COL1", 1); + pOp->load_const_u32(2, 128); + pOp->branch_eq(1, 2, 0); + pOp->interpret_exit_ok(); + pOp->def_label(0); + pOp->interpret_exit_nok(); + ret_val = FAIL ; + break; + case 5: // exit_nok of the value matches + pOp->read_attr("COL1", 1); + pOp->load_const_u32(2, 2); + pOp->branch_eq(1, 2, 0); + pOp->interpret_exit_ok(); + pOp->def_label(0); + pOp->interpret_exit_nok(); + break ; + case 6: // exit_ok of the value matches + pOp->read_attr("COL1", 1); + pOp->load_const_u32(2, 2); + pOp->branch_eq(1, 2, 0); + pOp->interpret_exit_nok(); + pOp->def_label(0); + if (opType == 3) { + // For update transactions use incValue to update the tuple + Uint32 val32 = 5; + pOp->incValue("COL2", val32); + } + pOp->interpret_exit_ok(); + break; + case 7: // exit_nok if the value matches + pOp->read_attr("COL1", 1); + pOp->load_const_u32(2, 6); + pOp->branch_eq(1, 2, 0); + pOp->interpret_exit_ok(); + pOp->def_label(0); + pOp->interpret_exit_nok(); + break; + case 8: // exit_ok if the value matches + pOp->read_attr("COL1", 1); + pOp->load_const_u32(2, 6); + pOp->branch_ne(1, 2, 0); + pOp->interpret_exit_nok(); + pOp->def_label(0); + if (opType == 3) { + // For update transactions use incValue to update the tuple + Uint32 val32 = 5; + pOp->incValue("COL2", val32); + } + pOp->interpret_exit_ok(); + break ; + case 9: // exit_nok if the value matches + pOp->read_attr("COL1", 1); + pOp->load_const_u32(2, 8); + pOp->branch_eq(1, 2, 0); + pOp->interpret_exit_ok(); + pOp->def_label(0); + pOp->interpret_exit_nok(); + break; + case 10: // exit_ok if the value matches + pOp->read_attr("COL1", 1); + pOp->load_const_u32(2, 8); + pOp->branch_eq(1, 2, 0); + pOp->interpret_exit_nok(); + pOp->def_label(0); + if (opType == 3) { + // For update transactions use incValue to update the tuple + Uint32 val32 = 5; + pOp->incValue("COL2", val32); + } + pOp->interpret_exit_ok(); + break; + case 11: // exit_nok if the value matches + pOp->read_attr("COL1", 1); + pOp->load_const_u32(2, 10); + pOp->branch_eq(1, 2, 0); + pOp->interpret_exit_ok(); + pOp->def_label(0); + pOp->interpret_exit_nok(); + break; + case 12: + pOp->read_attr("COL1", 1); + pOp->load_const_u32(2, 10); + pOp->branch_eq(1, 2, 0); + pOp->interpret_exit_nok(); + pOp->def_label(0); + if (opType == 3) { + // For update transactions use incValue to update the tuple + Uint32 val32 = 5; + pOp->incValue("COL2", val32); + } + pOp->interpret_exit_ok(); + break; + case 13: + pOp->read_attr("COL1", 1); + pOp->load_const_u32(2, 10); + pOp->branch_eq(1, 2, 0); + pOp->interpret_exit_ok(); + pOp->def_label(0); + pOp->interpret_exit_nok(); + break; + case 14: // exit_nok if the value matches + pOp->read_attr("COL1", 1); + pOp->load_const_u32(2, 12); + pOp->branch_eq(1, 2, 0); + pOp->interpret_exit_ok(); + pOp->def_label(0); + pOp->interpret_exit_nok(); + break; + case 15: // exit_ok if the value matches + pOp->read_attr("COL1", 1); + pOp->load_const_u32(2, 12); + pOp->branch_eq(1, 2, 0); + pOp->interpret_exit_nok(); + pOp->def_label(0); + if (opType == 3) { + // For update transactions use incValue to update the tuple + Uint32 val32 = 5; + pOp->incValue("COL2", val32); + } + pOp->interpret_exit_ok(); + case 16: + pOp->interpret_exit_nok(); + ret_val = FAIL ; + break; + case 17: + pOp->interpret_exit_ok(); + break ; + case 18: + pOp->interpret_exit_nok(); + ret_val = FAIL ; + break ; + default: + break ; + } + return ret_val; +} + +TTYPE t_incValue(int nCalls, NdbOperation* pOp) { + + ndbout << "Defining incValue test " << nCalls << ": "; + TTYPE ret_val = NO_FAIL; + + Uint32 val32 = 5; + Uint64 val64 = 5; + Uint32 attr0 = 0; + Uint32 attr1 = 1; + Uint32 attr20 = 20; + + switch(nCalls) { + case 1: + pOp->incValue(attrName[1], val32); + break; + case 2: + pOp->incValue(attr1, val32); + break; + case 3: + pOp->incValue(attrName[1], val64); + break; + case 4: + pOp->incValue(attr1, val64); + break; + case 5: + pOp->incValue(attrName[0], val32); + ret_val = FAIL ; + break; + case 6: + pOp->incValue(attrName[0], val64); + ret_val = FAIL ; + break; + case 7: + pOp->incValue(attr0, val32); + ret_val = FAIL ; + break; + case 8: + pOp->incValue(attr0, val64); + ret_val = FAIL ; + break; + case 9: + pOp->incValue("COL20", val32); + ret_val = FAIL ; + break; + case 10: + pOp->incValue("COL20", val64); + ret_val = FAIL ; + break; + case 11: + pOp->incValue(attr20, val32); + ret_val = FAIL ; + break; + case 12: + pOp->incValue(attr20, val64); + ret_val = FAIL ; + break; + default: + break ; + } + return ret_val; +} + +TTYPE t_subValue(int nCalls, NdbOperation* pOp) { + + ndbout << "Defining subValue test " << nCalls << ": "; + + Uint32 val32 = 5; + Uint64 val64 = 5; + Uint32 attr0 = 0; + Uint32 attr1 = 1; + Uint32 attr20 = 20; + + TTYPE ret_val = NO_FAIL; + + switch(nCalls) { + case 1: + pOp->subValue("COL2", val32); + break; + case 2: + pOp->subValue(attr1, val32); + break; + case 3: + pOp->subValue("COL0", val32); + ret_val = FAIL ; + break; + case 4: + pOp->subValue(attr0, val32); + ret_val = FAIL ; + break; + case 5: + pOp->subValue("COL20", val32); + ret_val = FAIL ; + break; + case 6: + pOp->subValue(attr20, val32); + ret_val = FAIL ; + break; + case 7: + // Missing implementation + //pOp->subValue("COL20", val64); + ndbout << "Missing implementation" << endl; + break; + case 8: + // Missing implementation + //pOp->subValue("COL2", val64); + ndbout << "Missing implementation" << endl; + break; + case 9: + // Missing implementation + //pOp->subValue("COL0", val64); + ndbout << "Missing implementation" << endl; + break; + case 10: + // Missing implementation + //pOp->subValue(attr1, val64); + ndbout << "Missing implementation" << endl; + break; + case 11: + // Missing implementation + //pOp->subValue(attr0, val64); + ndbout << "Missing implementation" << endl; + break; + case 12: + // Missing implementation + //pOp->subValue(attr20, val64); + ndbout << "Missing implementation" << endl; + break; + default: + break ; + } + return ret_val ; +} + +TTYPE t_readAttr(int nCalls, NdbOperation* pOp) { + + ndbout << "Defining readAttr test " << nCalls << ": "; + + Uint32 attr0 = 0; + Uint32 attr1 = 1; + Uint32 attr20 = 20; + TTYPE ret_val = NO_FAIL; + + switch(nCalls) { + case 1: + pOp->read_attr("COL1", 1); + break; + case 2: + pOp->read_attr(attr1, 1); + ret_val = NO_FAIL ; + break; + case 3: + pOp->read_attr("COL0", 1); + ret_val = NO_FAIL ; + break; + case 4: + pOp->read_attr(attr0, 1); + ret_val = NO_FAIL ; + break; + case 5: + pOp->read_attr("COL20", 1); + ret_val = FAIL ; + break; + case 6: + pOp->read_attr(20, 1); + ret_val = FAIL ; + break; + case 7: + pOp->read_attr("COL1", 8); + ret_val = FAIL ; + break; + case 8: + pOp->read_attr(attr1, 8); + ret_val = FAIL ; + break; + default: + break ; + } + return ret_val; +} + +TTYPE t_writeAttr(int nCalls, NdbOperation* pOp) { + + ndbout << "Defining writeAttr test " << nCalls << ": "; + + pOp->load_const_u32(1, 5); + + Uint32 attr0 = 0; + Uint32 attr1 = 1; + Uint32 attr20 = 20; + TTYPE ret_val = NO_FAIL ; + + switch(nCalls) { + case 1: + pOp->write_attr("COL1", 1); + break; + case 2: + pOp->write_attr(attr1, 1); + break; + case 3: + pOp->write_attr("COL0", 1); + ret_val = FAIL ; + break; + case 4: + pOp->write_attr(attr0, 1); + ret_val = FAIL ; + break; + case 5: + pOp->write_attr("COL20", 1); + ret_val = FAIL ; + break; + case 6: + pOp->write_attr(20, 1); + ret_val = FAIL ; + break; + case 7: + pOp->write_attr("COL1", 2); + ret_val = FAIL ; + break; + case 8: + pOp->write_attr(attr1, 2); + ret_val = FAIL ; + break; + case 9: + pOp->write_attr("COL1", 8); + ret_val = FAIL ; + break; + case 10: + pOp->write_attr(attr1, 8); + ret_val = FAIL ; + break; + default: + break ; + } + return ret_val ; +} + +TTYPE t_loadConst(int nCalls, NdbOperation* pOp, int opType) { + + ndbout << "Defining loadConst test " << nCalls << " : "; + TTYPE ret_val = NO_FAIL ; + + switch(nCalls) { + case 1: + // Loading null into a valid register + pOp->load_const_null(1); + break; + case 2: + // Loading null into an invalid register + pOp->load_const_null(8); + ret_val = FAIL ; + break; + case 3: + // Test loading a 32-bit value (>65536) + pOp->load_const_u32(1, 65600); + break; + case 4: + // Test loading a 16-bit value (<65536) + pOp->load_const_u32(1, 65500); + break; + case 5: + // Test by loading to a non-valid register + pOp->load_const_u32(8, 2); + ret_val = FAIL ; + break; + case 6: + // Test by loading a 64-bit value + pOp->load_const_u64(1, 65600); + break; + case 7: + // Test by loading a non-valid register + pOp->load_const_u64(8, 2); + ret_val = FAIL ; + break; + case 8: + // Test by loading a valid register with -1 + pOp->load_const_u64(1, -1); + ret_val = FAIL ; + break; + + default: + break ; + } + + if (opType == 3 && FAIL != ret_val) + pOp->write_attr("COL1", 1); + return ret_val; +} + +TTYPE t_branch(int nCalls, NdbOperation* pOp) { + + ndbout << "Defining branch test " << nCalls << ": " ; + + TTYPE ret_val = NO_FAIL ; + Uint32 val32=5; + + pOp->read_attr("COL1", 1); + pOp->load_const_u32(2, val32); + + switch(nCalls) { + case 1: + pOp->branch_eq(1, 2, 0); + pOp->interpret_exit_nok(); + pOp->def_label(0); + pOp->interpret_exit_ok(); + break; + case 2: + pOp->branch_eq(2, 1, 0); + pOp->interpret_exit_nok(); + pOp->def_label(0); + pOp->interpret_exit_ok(); + break; + case 3: + pOp->branch_eq(1, 1, 0); + pOp->interpret_exit_nok(); + pOp->def_label(0); + pOp->interpret_exit_ok(); + break; + default: + //ndbout << "t_branch: default case (no test case)" << endl ; + //return ret_val = NO_FAIL ; + break ; + } + return ret_val; +} + +TTYPE t_branchIfNull(int nCalls, NdbOperation* pOp) { + + TTYPE ret_val = NO_FAIL; + ndbout << "Defining branchIfNull test " << nCalls << ": " << endl ; + + switch(nCalls) { + case 1: + pOp->load_const_u32(1, 1); + pOp->branch_ne_null(1, 0); + pOp->interpret_exit_nok(); + pOp->def_label(0); + pOp->interpret_exit_ok(); + break; + case 2: + pOp->load_const_null(1); + pOp->branch_ne_null(1, 0); + pOp->interpret_exit_ok(); + pOp->def_label(0); + pOp->interpret_exit_nok(); + break; + case 3: + pOp->load_const_u32(1, 1); + pOp->branch_eq_null(1, 0); + pOp->interpret_exit_ok(); + pOp->def_label(0); + pOp->interpret_exit_nok(); + break; + case 4: + pOp->load_const_null(1); + pOp->branch_ne_null(1, 0); + pOp->interpret_exit_ok(); + pOp->def_label(0); + pOp->interpret_exit_nok(); + break; + case 5: + // Test with a non-initialized register + pOp->branch_ne_null(3, 0); + pOp->interpret_exit_ok(); + pOp->def_label(0); + pOp->interpret_exit_nok(); + ret_val = FAIL ; + break; + case 6: + // Test with a non-existing register + pOp->branch_ne_null(8, 0); + pOp->interpret_exit_ok(); + pOp->def_label(0); + pOp->interpret_exit_nok(); + ret_val = FAIL ; + break; + case 7: + // Test with a non-initialized register + pOp->branch_eq_null(3, 0); + pOp->interpret_exit_ok(); + pOp->def_label(0); + pOp->interpret_exit_nok(); + ret_val = FAIL ; + break; + case 8: + // Test with a non-existing register + pOp->branch_ne_null(8, 0); + pOp->interpret_exit_ok(); + pOp->def_label(0); + pOp->interpret_exit_nok(); + ret_val = FAIL ; + break; + default: + break ; + } + + return ret_val; +} + +TTYPE t_addReg(int nCalls, NdbOperation* pOp) { + + TTYPE ret_val = NO_FAIL ; + + ndbout << "Defining addReg test " << nCalls << ": "; + + pOp->load_const_u32(1, 65500); + pOp->load_const_u32(2, 500); + pOp->load_const_u64(3, 65600); + pOp->load_const_u64(4, 95600); + + switch(nCalls) { + case 1: + pOp->add_reg(1, 2, 5); + break; + case 2: + pOp->add_reg(1, 3, 5); + break; + case 3: + pOp->add_reg(3, 1, 5); + break; + case 4: + pOp->add_reg(3, 4, 5); + break; + case 5: + pOp->add_reg(1, 6, 5); + break; + case 6: + pOp->add_reg(6, 1, 5); + break; + case 7: // illegal register + pOp->add_reg(1, 8, 5); + ret_val = FAIL ; + break; + case 8: // another illegal register + pOp->add_reg(8, 1, 5); + ret_val = FAIL ; + break; + case 9: // and another one + pOp->add_reg(1, 2, 8); + ret_val = FAIL ; + break; + default: + break ; + } + pOp->load_const_u32(7, 65000); + pOp->branch_eq(5, 7, 0); + pOp->interpret_exit_nok(); + pOp->def_label(0); + pOp->interpret_exit_ok(); + + return ret_val ; +} + +TTYPE t_subReg(int nCalls, NdbOperation* pOp) { + + TTYPE ret_val = NO_FAIL ; + ndbout << "Defining subReg test: " << nCalls << endl; + + pOp->load_const_u32(1, 65500); + pOp->load_const_u32(2, 500); + pOp->load_const_u64(3, 65600); + pOp->load_const_u64(4, 95600); + + switch(nCalls) { + case 1: + pOp->sub_reg(1, 2, 5); + pOp->load_const_u32(7, 65000); + break; + case 2: + pOp->sub_reg(1, 3, 5); + pOp->load_const_u64(7, (Uint64)-100); + break; + case 3: + pOp->sub_reg(3, 1, 5); + pOp->load_const_u64(7, (Uint64)100); + break; + case 4: + pOp->sub_reg(3, 4, 5); + pOp->load_const_u64(7, (Uint64)-30000); + break; + case 5: + pOp->sub_reg(1, 6, 5); + pOp->load_const_u64(7, 0); + ret_val = FAIL ; + break; + case 6: + pOp->sub_reg(6, 1, 5); + pOp->load_const_u64(7, 0); + ret_val = FAIL ; + break; + case 7: + pOp->sub_reg(1, 8, 5); + pOp->load_const_u64(7, 0); + ret_val = FAIL ; + break; + case 8: + pOp->sub_reg(8, 1, 5); + pOp->load_const_u64(7, 0); + ret_val = FAIL ; + break; + case 9: + pOp->sub_reg(1, 2, 8); + pOp->load_const_u32(7, (Uint32)65000); + ret_val = FAIL; + break; + default: + //ndbout << "t_subReg: default case (no test case)" << endl ; + //return ret_val = NO_FAIL ; + break ; + } + pOp->branch_eq(5, 7, 0); + pOp->interpret_exit_nok() ; + pOp->def_label(0); + pOp->interpret_exit_ok() ; + + return ret_val; +} + +TTYPE t_subroutineWithBranchLabel(int nCalls, NdbOperation* pOp) { + + TTYPE ret_val = NO_FAIL ; + ndbout << "Defining subroutineWithBranchLabel test:" << nCalls << endl; + + pOp->load_const_u32(1, 65500); + pOp->load_const_u32(2, 500); + pOp->load_const_u64(3, 65600); + pOp->load_const_u64(4, 95600); + pOp->load_const_u32(7, 65000); + pOp->call_sub(0) ; + + switch(nCalls) { + case 1: + pOp->def_subroutine(0) ; + pOp->add_reg(1, 2, 5); + break; + case 2: + pOp->def_subroutine(0) ; + pOp->add_reg(1, 3, 5); + break; + case 3: + pOp->def_subroutine(0) ; + pOp->add_reg(3, 1, 5); + break; + case 4: + pOp->def_subroutine(0) ; + pOp->add_reg(3, 4, 5); + break; + case 5: + pOp->def_subroutine(0) ; + pOp->add_reg(1, 6, 5); + break; + case 6: + pOp->def_subroutine(0) ; + pOp->add_reg(6, 1, 5); + break; + case 7: // illegal register + pOp->def_subroutine(0) ; + pOp->add_reg(1, 8, 5); + ret_val = FAIL ; + break; + case 8: // another illegal register + pOp->def_subroutine(0) ; + pOp->add_reg(8, 1, 5); + ret_val = FAIL ; + break; + case 9: // and another one + pOp->def_subroutine(0) ; + pOp->add_reg(1, 2, 8); + ret_val = FAIL ; + break; + case 10: // test subroutine nesting + for(int sub = 0; sub < 25 ; ++sub){ + pOp->call_sub(sub) ; + pOp->def_subroutine(sub + 1) ; + pOp->interpret_exit_ok() ; + pOp->ret_sub() ; + } + ret_val = FAIL ; + default: + break ; + } + + pOp->branch_label(0) ; + pOp->interpret_exit_nok() ; + pOp->def_label(0) ; + pOp->interpret_exit_ok() ; + pOp->ret_sub() ; + + return ret_val ; +} + + +void scan_rows(Ndb* pMyNdb, int opType, int tupleType, int scanType) { + + int check = -1 ; + int loop_count_ops = nRecords ; + int eOf = -1 ; + int readValue = 0 ; + int readValue2 = 0 ; + int scanCount = 0 ; + NdbRecAttr* tTmp = NULL ; + TTYPE fail = NO_FAIL ; + + for (int count=0 ; count < loop_count_ops ; count++) { + NdbConnection* MyTransaction = pMyNdb->startTransaction(); + if (!MyTransaction) error_handler(pMyNdb->getNdbError(), NO_FAIL); + + NdbOperation* MyOperation = MyTransaction->getNdbOperation(tableName[0]); + if (!MyOperation) error_handler(pMyNdb->getNdbError(), NO_FAIL); + + if (opType == 1) + // Open for scan read, Creates the SCAN_TABREQ and if needed + // SCAN_TABINFO signals. + check = MyOperation->openScanRead(1); + else if (opType == 2) + // Open for scan with update of rows. + check = MyOperation->openScanExclusive(1); + + // Create ATTRINFO signal(s) for interpreted program used for + // defining search criteria and column values that should be returned. + + scanCount = count+1 ; + + switch(tupleType) { + case 1: + fail = t_exitMethods(scanCount, MyOperation, opType); + break; + case 2: + fail = t_incValue(scanCount, MyOperation); + break; + case 3: + fail = t_subValue(scanCount, MyOperation); + break; + case 4: + fail = t_readAttr(scanCount, MyOperation); + break; + case 5: + fail = t_writeAttr(scanCount, MyOperation); + break; + case 6: + fail = t_loadConst(scanCount, MyOperation, opType); + break; + case 7: + fail = t_branch(scanCount, MyOperation); + break; + case 8: + fail = t_branchIfNull(scanCount, MyOperation); + break; + case 9: + fail = t_addReg(scanCount, MyOperation); + break; + case 10: + fail = t_subReg(scanCount, MyOperation); + break; + case 11: + fail = t_subroutineWithBranchLabel(scanCount, MyOperation); + break; + default: + break ; + } + + if(11 != tupleType) MyOperation->getValue(attrName[1], (char*)&readValue); + + // Sends the SCAN_TABREQ, (SCAN_TABINFO) and ATTRINFO signals and then + // reads the answer in TRANSID_AI. Confirmation is received through SCAN_TABCONF or + // SCAN_TABREF if failure. + check = MyTransaction->executeScan(); + if (check == -1) { + //ndbout << endl << "executeScan returned: " << MyTransaction->getNdbError() << endl; + error_handler(MyTransaction->getNdbError(), fail) ; + pMyNdb->closeTransaction(MyTransaction); + }else{ + // Sends the SCAN_NEXTREQ signal(s) and reads the answer in TRANS_ID signals. + // SCAN_TABCONF or SCAN_TABREF is the confirmation. + while (eOf = MyTransaction->nextScanResult() == 0) { + ndbout << readValue <<"; "; + // Here we call takeOverScanOp for update of the tuple. + } + ndbout << endl ; + + pMyNdb->closeTransaction(MyTransaction); + if (eOf == -1) { + ndbout << endl << "nextScanResult returned: "<< MyTransaction->getNdbError() << endl; + } else { + ndbout << "OK" << endl; + } + } + } + return; + +}; + + +void update_rows(Ndb* pMyNdb, int tupleType, int opType) { + /**************************************************************** + * Update rows in SimpleTable + * Only updates the first 3 cols. + ***************************************************************/ + + int check = -1 ; + int loop_count_ops = nRecords ; + int readValue[MAXATTR] = {0} ; + TTYPE ret_val = NO_FAIL ; + NdbConnection *MyTransaction = NULL ; + NdbOperation *MyOperation = NULL ; + + ndbout << "Updating records ..." << endl << endl; + + for (int count=0 ; count < loop_count_ops ; count++){ + + MyTransaction = pMyNdb->startTransaction(); + if (!MyTransaction) { + error_handler(pMyNdb->getNdbError(), NO_FAIL); + return; + }//if + + MyOperation = MyTransaction->getNdbOperation(tableName[0]); + if (MyOperation == NULL) { + error_handler(pMyNdb->getNdbError(), NO_FAIL); + return; + }//if + + // if (operationType == 3) + check = MyOperation->interpretedUpdateTuple(); + // else if (operationType == 4) + // check = MyOperation->interpretedDirtyUpdate(); + if( check == -1 ) + error_handler(MyTransaction->getNdbError(), NO_FAIL); + + check = MyOperation->equal( attrName[0], (char*)&pkValue[count] ); + if( check == -1 ) + error_handler(MyTransaction->getNdbError(), NO_FAIL); + + switch(tupleType) { + case 1: + ret_val = t_exitMethods(count+1, MyOperation, opType); + break; + case 2: + ret_val = t_incValue(count+1, MyOperation); + break; + case 3: + ret_val = t_subValue(count+1, MyOperation); + break; + case 4: + ret_val = t_readAttr(count+1, MyOperation); + break; + case 5: + ret_val = t_writeAttr(count+1, MyOperation); + break; + case 6: + ret_val = t_loadConst(count+1, MyOperation, opType); + break; + case 7: + ret_val = t_branch(count+1, MyOperation); + break; + case 8: + ret_val = t_branchIfNull(count+1, MyOperation); + break; + case 9: + ret_val = t_addReg(count+1, MyOperation); + break; + case 10: + ret_val = t_subReg(count+1, MyOperation); + break; + case 11: + ret_val = t_subroutineWithBranchLabel(count+1, MyOperation); + break; + default: + break ; + } + + MyOperation->getValue("COL1", (char*)&readValue); + + if (MyTransaction->execute( Commit ) == -1 ) { + error_handler(MyTransaction->getNdbError(), ret_val); + }else if (NO_FAIL == ret_val ) { + ndbout << "OK" << endl; + } else { + bTestPassed = -1; + ndbout << "Test passed when expected to fail" << endl; + }//if + pMyNdb->closeTransaction(MyTransaction); + + } + + ndbout << "Finished updating records" << endl; + return; +}; + +void delete_rows(Ndb* pMyNdb, int tupleTest, int opType) { + + /**************************************************************** + * Delete rows from SimpleTable + * + ***************************************************************/ + + int check = 1 ; + int loop_count_ops = nRecords ; + int readValue[MAXATTR] = {0}; + NdbConnection *MyTransaction = NULL ; + NdbOperation *MyOperation = NULL ; + TTYPE ret_val = NO_FAIL ; + + ndbout << "Deleting records ..."<< endl << endl; + + for (int count=0 ; count < loop_count_ops ; count++) { + + MyTransaction = pMyNdb->startTransaction(); + if (!MyTransaction) error_handler(pMyNdb->getNdbError(), NO_FAIL) ; + + MyOperation = MyTransaction->getNdbOperation(tableName[0]); + if (!MyOperation) error_handler(pMyNdb->getNdbError(), NO_FAIL) ; + + check = MyOperation->interpretedDeleteTuple(); + if( check == -1 ) error_handler(MyTransaction->getNdbError(), NO_FAIL) ; + + check = MyOperation->equal( attrName[0], (char*)&pkValue[count] ); + if( check == -1 ) error_handler(MyTransaction->getNdbError(), NO_FAIL) ; + + switch(tupleTest) { + case 1: + ret_val = t_exitMethods(count+1, MyOperation, opType); + break; + case 2: + ret_val = t_incValue(count+1, MyOperation); + break; + case 3: + ret_val = t_subValue(count+1, MyOperation); + break; + case 4: + ret_val = t_readAttr(count+1, MyOperation); + break; + case 5: + ret_val = t_writeAttr(count+1, MyOperation); + break; + case 6: + ret_val = t_loadConst(count+1, MyOperation, opType); + break; + case 7: + ret_val = t_branch(count+1, MyOperation); + break; + case 8: + ret_val = t_branchIfNull(count+1, MyOperation); + break; + case 9: + ret_val = t_addReg(count+1, MyOperation); + break; + case 10: + ret_val = t_subReg(count+1, MyOperation); + break; + case 11: + ret_val = t_subroutineWithBranchLabel(count+1, MyOperation); + break; + default: + break ; + } + + if(11 != tupleTest)MyOperation->getValue(attrName[1], (char*)&readValue) ; + + if (MyTransaction->execute( Commit ) == -1 ) { + error_handler(MyTransaction->getNdbError(), ret_val); + } else if (NO_FAIL == ret_val /*|| UNDEF == ret_val*/ ) { + ndbout << "OK" << endl; + } else { + bTestPassed = -1; + ndbout << "Test passed when expected to fail" << endl; + }//if + ndbout << endl; + pMyNdb->closeTransaction(MyTransaction); + } + + ndbout << "Finished deleting records" << endl; + return; + +}; + + +inline void setAttrNames(){ + for (int i = 0; i < MAXATTR; i++){ + snprintf(attrName[i], MAXSTRLEN, "COL%d", i); + } +} + + +inline void setTableNames(){ + for (int i = 0; i < MAXTABLES; i++){ + snprintf(tableName[i], MAXSTRLEN, "TAB%d", i); + } +} + diff --git a/ndb/test/ndbapi/interpreterInTup/Makefile b/ndb/test/ndbapi/interpreterInTup/Makefile deleted file mode 100644 index 074adbf674a..00000000000 --- a/ndb/test/ndbapi/interpreterInTup/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - - -BIN_TARGET := interpreterInTup - -SOURCES := interpreterInTup.cc - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/interpreterInTup/interpreterInTup.cpp b/ndb/test/ndbapi/interpreterInTup/interpreterInTup.cpp deleted file mode 100644 index a2352edf707..00000000000 --- a/ndb/test/ndbapi/interpreterInTup/interpreterInTup.cpp +++ /dev/null @@ -1,1524 +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 */ - -/* *************************************************** - TEST OF INTERPRETER IN TUP - Verify that the interpreter in TUP is able to - handle and execute all the commands that the - NdbApi can isssue - - Arguments: - - operationType 1 openScanRead, - 2 openScanExclusive, - 3 interpretedUpdateTuple, - 4 interpretedDirtyUpdate, - 5 interpretedDeleteTuple - 6 deleteTuple - 7 insertTuple - 8 updateTuple - 9 writeTuple - 10 readTuple - 11 readTupleExclusive - 12 simpleRead - 13 dirtyRead - 14 dirtyUpdate - 15 dirtyWrite - - tupTest 1 exitMethods - 2 incValue - 3 subValue - 4 readAttr - 5 writeAttr - 6 loadConst - 7 branch - 8 branchIfNull - 9 addReg - 10 subReg - 11 subroutineWithBranchLabel - - scanTest Number of the test within each tupTest - -* *************************************************** */ - -#include -#include -#include -#include -#include - -#define MAXATTR 3 -#define MAXTABLES 12 -#define MAXSTRLEN 8 -#define NUMBEROFRECORDS 1000 - -typedef enum { - FAIL = 0, - NO_FAIL, - UNDEF -} TTYPE; - -inline void setAttrNames() ; -inline void setTableNames() ; -void error_handler(const NdbError & err, TTYPE); -void create_table(Ndb*); -void write_rows(Ndb*); -void update_rows(Ndb*, int, int); -void delete_rows(Ndb*, int, int); -void verify_deleted(Ndb*); -void read_and_verify_rows(Ndb*, bool pre); -void scan_rows(Ndb*, int, int, int); -TTYPE t_exitMethods(int, NdbOperation*, int); -TTYPE t_incValue(int, NdbOperation*); -TTYPE t_subValue(int, NdbOperation*); -TTYPE t_readAttr(int, NdbOperation*); -TTYPE t_writeAttr(int, NdbOperation*); -TTYPE t_loadConst(int, NdbOperation*, int); -TTYPE t_branch(int, NdbOperation*); -TTYPE t_branchIfNull(int, NdbOperation*); -TTYPE t_addReg(int, NdbOperation*); -TTYPE t_subReg(int, NdbOperation*); -TTYPE t_subroutineWithBranchLabel(int, NdbOperation*); - -char tableName[MAXTABLES][MAXSTRLEN+1] = {0}; -char attrName[MAXATTR][MAXSTRLEN+1] = {0}; -int attrValue[NUMBEROFRECORDS] = {0}; -int pkValue[NUMBEROFRECORDS] = {0}; -const int tAttributeSize = 1 ; -const int nRecords = 20 ; -int bTestPassed = 0; - - - -int main(int argc, const char** argv) { - - int tTableId = 0; - int operationType = 0; - int tupTest = 0 ; - int scanTest = 0 ; - bool loop = 0 ; - - Ndb* pNdb = new Ndb("TEST_DB"); - pNdb->init(); - - if (argc != 4 || sscanf(argv[1],"%d", &operationType) != 1) { - operationType = 1 ; - } - if (argc != 4 || sscanf(argv[2],"%d", &tupTest) != 1) { - tupTest = 1 ; - } - if (argc != 4 || sscanf(argv[3],"%d", &scanTest) != 1) { - scanTest = 1 ; - } - - ndbout << endl - << "Test the interpreter in TUP using SimpleTable with\n" - << nRecords << " records" << endl << endl ; - - if (pNdb->waitUntilReady(30) != 0) { - ndbout << "NDB is not ready" << endl; - return -1; - } - - // Init the pk and attr values. - for (int i = 0; i < NUMBEROFRECORDS; i ++) - pkValue[i] = attrValue[i] = i ; - - setAttrNames() ; - setTableNames() ; - - const void * p = NDBT_Table::discoverTableFromDb(pNdb, tableName[0]); - if (p != 0){ - create_table(pNdb); - } - - write_rows(pNdb); - - ndbout << endl << "Starting interpreter in TUP test." << endl << "Operation type: " ; - - switch(operationType) { - case 1: - ndbout << "openScanRead" << endl; - scan_rows(pNdb, operationType, tupTest, scanTest); - break; - case 2: - ndbout << "openScanExclusive" << endl; - scan_rows(pNdb, operationType, tupTest, scanTest); - break; - case 3: - ndbout << "interpretedUpdateTuple" << endl; - update_rows(pNdb, tupTest, operationType); - break; - case 4: - ndbout << "interpretedDirtyUpdate" << endl; - update_rows(pNdb, tupTest, operationType); - break; - case 5: - ndbout << "interpretedDeleteTuple" << endl; - delete_rows(pNdb, tupTest, operationType); - break; - case 6: - ndbout << "deleteTuple" << endl; - break; - case 7: - ndbout << "insertTuple" << endl; - break; - case 8: - ndbout << "updateTuple" << endl; - break; - case 9: - ndbout << "writeTuple" << endl; - break; - case 10: - ndbout << "readTuple" << endl; - break; - case 11: - ndbout << "readTupleExclusive" << endl; - break; - case 12: - ndbout << "simpleRead" << endl; - break; - case 13: - ndbout << "dirtyRead" << endl; - break; - case 14: - ndbout << "dirtyUpdate" << endl; - break; - case 15: - ndbout << "dirtyWrite" << endl; - break; - default: - break ; - - } - -// read_and_verify_rows(pNdb, false); - -// delete_rows(pNdb, 0, 0) ; - delete pNdb ; - - if (bTestPassed == 0) { - ndbout << "OK: test passed" << endl; - exit(0); - }else{ - ndbout << "FAIL: test failed" << endl; - exit(-1); - } -} - -void error_handler(const NdbError & err, TTYPE type_expected) { - - ndbout << err << endl ; - - switch (type_expected){ - case NO_FAIL: - bTestPassed = -1 ; - break ; - case FAIL: - ndbout << "OK: error is expected" << endl; - break ; - case UNDEF: - ndbout << "assumed OK: expected result undefined" << endl ; - break ; - default: - break ; - } -} - -void create_table(Ndb* pMyNdb) { - - /**************************************************************** - * Create SimpleTable and Attributes. - * - * create table SimpleTable1( - * col0 int, - * col1 int not null, - * col2 int not null, - * col3 int not null ... 129) - * - ***************************************************************/ - - int check = -1 ; - NdbSchemaCon *MySchemaTransaction = NULL ; - NdbSchemaOp *MySchemaOp = NULL ; - - ndbout << endl << "Creating " << tableName[0] << " ... " << endl; - - MySchemaTransaction = pMyNdb->startSchemaTransaction(); - if(!MySchemaTransaction) error_handler(MySchemaTransaction->getNdbError(), NO_FAIL); - - MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); - if( !MySchemaOp ) error_handler(MySchemaTransaction->getNdbError(), NO_FAIL); - // Create table - check = MySchemaOp->createTable( tableName[0], - 8, // Table size - TupleKey, // Key Type - 40 // Nr of Pages - ); - - if( check == -1 ) error_handler(MySchemaTransaction->getNdbError(), NO_FAIL); - - ndbout << "Creating attributes ... " << flush; - - // Create first column, primary key - check = MySchemaOp->createAttribute( attrName[0], - TupleKey, - 32, - 1/*3, tAttributeSize */, - UnSigned, - MMBased, - NotNullAttribute ); - - if( check == -1 ) error_handler(MySchemaTransaction->getNdbError(), NO_FAIL); - - // create the 2 .. n columns. - for ( int i = 1; i < MAXATTR; i++ ){ - check = MySchemaOp->createAttribute( attrName[i], - NoKey, - 32, - tAttributeSize, - UnSigned, - MMBased, - NotNullAttribute ); - - if( check == -1 ) error_handler(MySchemaTransaction->getNdbError(), NO_FAIL); - } - - ndbout << "OK" << endl; - - if( MySchemaTransaction->execute() == -1 ) { - ndbout << MySchemaTransaction->getNdbError() << endl; - }else{ - ndbout << tableName[0] << " created" << endl; - } - - pMyNdb->closeSchemaTransaction(MySchemaTransaction); - - return; - -} - - - -void write_rows (Ndb* pMyNdb) { - - /**************************************************************** - * Insert rows into SimpleTable - * - ***************************************************************/ - - int check = -1 ; - int loop_count_ops = nRecords ; - NdbOperation *MyOperation = NULL ; - NdbConnection *MyTransaction = NULL ; - - ndbout << endl << "Writing records ..." << flush; - - for (int count=0 ; count < loop_count_ops ; count++){ - MyTransaction = pMyNdb->startTransaction(); - if (!MyTransaction) { - error_handler(pMyNdb->getNdbError(), NO_FAIL); - }//if - - MyOperation = MyTransaction->getNdbOperation(tableName[0]); - if (!MyOperation) { - error_handler(pMyNdb->getNdbError(), NO_FAIL); - }//if - - check = MyOperation->writeTuple(); - if( check == -1 ) error_handler(MyTransaction->getNdbError(), NO_FAIL); - - check = MyOperation->equal( attrName[0],(char*)&pkValue[count] ); - if( check == -1 ) error_handler(MyTransaction->getNdbError(), NO_FAIL); - - // Update the columns, index column already ok. - for (int i = 1 ; i < MAXATTR; i++){ - if ((i == 2) && (count > 4)){ - check = MyOperation->setValue(attrName[i], (char*)&attrValue[count + 1]); - }else{ - check = MyOperation->setValue(attrName[i], (char*)&attrValue[count]); - } - if( check == -1 ) error_handler(MyTransaction->getNdbError(), NO_FAIL); - } - check = MyTransaction->execute( Commit ); - if(check == -1 ) error_handler(MyTransaction->getNdbError(), NO_FAIL); - - pMyNdb->closeTransaction(MyTransaction); - } - ndbout <<" \tOK" << endl; - return; -} - -void verify_deleted(Ndb* pMyNdb) { - - int check = -1 ; - int loop_count_ops = nRecords; - NdbRecAttr* tTmp; - int readValue[MAXATTR]; - NdbConnection* pMyTransaction = NULL ; - NdbOperation* pMyOperation = NULL ; - - ndbout << "Verifying deleted records..."<< flush; - - for (int count=0 ; count < loop_count_ops ; count++){ - - NdbConnection* pMyTransaction = pMyNdb->startTransaction(); - if (!pMyTransaction) error_handler(pMyNdb->getNdbError(), NO_FAIL); - - pMyOperation = pMyTransaction->getNdbOperation(tableName[0]); - if (!pMyOperation) error_handler(pMyNdb->getNdbError(), NO_FAIL); - - check = pMyOperation->readTuple(); - if( check == -1 ) error_handler( pMyTransaction->getNdbError(), NO_FAIL); - - check = pMyOperation->equal( attrName[0],(char*)&pkValue[count] ); - if( check == -1 ) error_handler( pMyTransaction->getNdbError(), NO_FAIL); - - // Exepect to receive an error - if(pMyTransaction->execute(Commit) != -1) - if( 626 == pMyTransaction->getNdbError().code){ - ndbout << pMyTransaction->getNdbError() << endl ; - ndbout << "OK" << endl ; - }else{ - error_handler(pMyTransaction->getNdbError(), NO_FAIL) ; - } - - pMyNdb->closeTransaction(pMyTransaction); - } - - ndbout << "OK" << endl; - return; -}; - -void read_and_verify_rows(Ndb* pMyNdb, bool pre) { - - int check = -1 ; - int loop_count_ops = nRecords; - char expectedCOL1[NUMBEROFRECORDS] = {0} ; - char expectedCOL2[NUMBEROFRECORDS] = {0} ; - NdbConnection *pMyTransaction = NULL ; - NdbOperation *MyOp = NULL ; - NdbRecAttr* tTmp = NULL ; - int readValue[MAXATTR] = {0} ; - - ndbout << "Verifying records...\n"<< endl; - - for (int count=0 ; count < loop_count_ops ; count++){ - - pMyTransaction = pMyNdb->startTransaction(); - if (!pMyTransaction) error_handler(pMyNdb->getNdbError(), NO_FAIL); - - MyOp = pMyTransaction->getNdbOperation(tableName[0]); - if (!MyOp) error_handler( pMyTransaction->getNdbError(), NO_FAIL); - - - check = MyOp->readTuple(); - if( check == -1 ) error_handler( MyOp->getNdbError(), NO_FAIL); - - check = MyOp->equal( attrName[0],(char*)&pkValue[count] ); - if( check == -1 ) error_handler( MyOp->getNdbError(), NO_FAIL); - - for (int count_attributes = 1; count_attributes < MAXATTR; count_attributes++){ - - tTmp = MyOp->getValue( (char*)attrName[count_attributes], (char*)&readValue[count_attributes] ); - if(!tTmp) error_handler( MyOp->getNdbError(), NO_FAIL); - } - - if( pMyTransaction->execute( Commit ) == -1 ) { - error_handler(pMyTransaction->getNdbError(), NO_FAIL); - } else { - if (pre) { - expectedCOL1[count] = readValue[1]; - expectedCOL2[count] = readValue[2]; - } - - ndbout << attrName[1] << "\t " << readValue[1] << "\t " - << attrName[2] << "\t " << readValue[2] << endl; - } - - pMyNdb->closeTransaction(pMyTransaction); - - } - - ndbout << "\nOK\n" << endl; - - return; - -}; - -TTYPE t_exitMethods(int nCalls, NdbOperation * pOp, int opType) { - - ndbout << "Defining exitMethods test " << nCalls << ": " << endl ;; - TTYPE ret_val = NO_FAIL ; - - switch(nCalls){ - case 1: // exit_nok if attr value matches - pOp->read_attr("COL1", 1); - pOp->load_const_u32(2, 14); - pOp->branch_eq(1, 2, 0); - pOp->interpret_exit_ok() ; - pOp->def_label(0); - pOp->interpret_exit_nok(); - break; - case 2: // exit_ok if attr value doesn't match - pOp->read_attr("COL1", 1); - pOp->load_const_u32(2, 14); - pOp->branch_eq(1, 2, 0); - pOp->interpret_exit_nok() ; - pOp->def_label(0); - if (opType == 3) { - // For update transactions use incValue to update the tuple - Uint32 val32 = 5; - pOp->incValue("COL2", val32); - } - pOp->interpret_exit_ok(); - break ; - case 3: // Non-existent value (128): exit_ok if if the value matches - pOp->read_attr("COL1", 1); - pOp->load_const_u32(2, 128); - pOp->branch_eq(1, 2, 0); - pOp->interpret_exit_nok(); - pOp->def_label(0); - pOp->interpret_exit_ok(); - ret_val = FAIL ; - break; - case 4: // Non-existent value (128): exit_nok if the value matches - pOp->read_attr("COL1", 1); - pOp->load_const_u32(2, 128); - pOp->branch_eq(1, 2, 0); - pOp->interpret_exit_ok(); - pOp->def_label(0); - pOp->interpret_exit_nok(); - ret_val = FAIL ; - break; - case 5: // exit_nok of the value matches - pOp->read_attr("COL1", 1); - pOp->load_const_u32(2, 2); - pOp->branch_eq(1, 2, 0); - pOp->interpret_exit_ok(); - pOp->def_label(0); - pOp->interpret_exit_nok(); - break ; - case 6: // exit_ok of the value matches - pOp->read_attr("COL1", 1); - pOp->load_const_u32(2, 2); - pOp->branch_eq(1, 2, 0); - pOp->interpret_exit_nok(); - pOp->def_label(0); - if (opType == 3) { - // For update transactions use incValue to update the tuple - Uint32 val32 = 5; - pOp->incValue("COL2", val32); - } - pOp->interpret_exit_ok(); - break; - case 7: // exit_nok if the value matches - pOp->read_attr("COL1", 1); - pOp->load_const_u32(2, 6); - pOp->branch_eq(1, 2, 0); - pOp->interpret_exit_ok(); - pOp->def_label(0); - pOp->interpret_exit_nok(); - break; - case 8: // exit_ok if the value matches - pOp->read_attr("COL1", 1); - pOp->load_const_u32(2, 6); - pOp->branch_ne(1, 2, 0); - pOp->interpret_exit_nok(); - pOp->def_label(0); - if (opType == 3) { - // For update transactions use incValue to update the tuple - Uint32 val32 = 5; - pOp->incValue("COL2", val32); - } - pOp->interpret_exit_ok(); - break ; - case 9: // exit_nok if the value matches - pOp->read_attr("COL1", 1); - pOp->load_const_u32(2, 8); - pOp->branch_eq(1, 2, 0); - pOp->interpret_exit_ok(); - pOp->def_label(0); - pOp->interpret_exit_nok(); - break; - case 10: // exit_ok if the value matches - pOp->read_attr("COL1", 1); - pOp->load_const_u32(2, 8); - pOp->branch_eq(1, 2, 0); - pOp->interpret_exit_nok(); - pOp->def_label(0); - if (opType == 3) { - // For update transactions use incValue to update the tuple - Uint32 val32 = 5; - pOp->incValue("COL2", val32); - } - pOp->interpret_exit_ok(); - break; - case 11: // exit_nok if the value matches - pOp->read_attr("COL1", 1); - pOp->load_const_u32(2, 10); - pOp->branch_eq(1, 2, 0); - pOp->interpret_exit_ok(); - pOp->def_label(0); - pOp->interpret_exit_nok(); - break; - case 12: - pOp->read_attr("COL1", 1); - pOp->load_const_u32(2, 10); - pOp->branch_eq(1, 2, 0); - pOp->interpret_exit_nok(); - pOp->def_label(0); - if (opType == 3) { - // For update transactions use incValue to update the tuple - Uint32 val32 = 5; - pOp->incValue("COL2", val32); - } - pOp->interpret_exit_ok(); - break; - case 13: - pOp->read_attr("COL1", 1); - pOp->load_const_u32(2, 10); - pOp->branch_eq(1, 2, 0); - pOp->interpret_exit_ok(); - pOp->def_label(0); - pOp->interpret_exit_nok(); - break; - case 14: // exit_nok if the value matches - pOp->read_attr("COL1", 1); - pOp->load_const_u32(2, 12); - pOp->branch_eq(1, 2, 0); - pOp->interpret_exit_ok(); - pOp->def_label(0); - pOp->interpret_exit_nok(); - break; - case 15: // exit_ok if the value matches - pOp->read_attr("COL1", 1); - pOp->load_const_u32(2, 12); - pOp->branch_eq(1, 2, 0); - pOp->interpret_exit_nok(); - pOp->def_label(0); - if (opType == 3) { - // For update transactions use incValue to update the tuple - Uint32 val32 = 5; - pOp->incValue("COL2", val32); - } - pOp->interpret_exit_ok(); - case 16: - pOp->interpret_exit_nok(); - ret_val = FAIL ; - break; - case 17: - pOp->interpret_exit_ok(); - break ; - case 18: - pOp->interpret_exit_nok(); - ret_val = FAIL ; - break ; - default: - break ; - } - return ret_val; -} - -TTYPE t_incValue(int nCalls, NdbOperation* pOp) { - - ndbout << "Defining incValue test " << nCalls << ": "; - TTYPE ret_val = NO_FAIL; - - Uint32 val32 = 5; - Uint64 val64 = 5; - Uint32 attr0 = 0; - Uint32 attr1 = 1; - Uint32 attr20 = 20; - - switch(nCalls) { - case 1: - pOp->incValue(attrName[1], val32); - break; - case 2: - pOp->incValue(attr1, val32); - break; - case 3: - pOp->incValue(attrName[1], val64); - break; - case 4: - pOp->incValue(attr1, val64); - break; - case 5: - pOp->incValue(attrName[0], val32); - ret_val = FAIL ; - break; - case 6: - pOp->incValue(attrName[0], val64); - ret_val = FAIL ; - break; - case 7: - pOp->incValue(attr0, val32); - ret_val = FAIL ; - break; - case 8: - pOp->incValue(attr0, val64); - ret_val = FAIL ; - break; - case 9: - pOp->incValue("COL20", val32); - ret_val = FAIL ; - break; - case 10: - pOp->incValue("COL20", val64); - ret_val = FAIL ; - break; - case 11: - pOp->incValue(attr20, val32); - ret_val = FAIL ; - break; - case 12: - pOp->incValue(attr20, val64); - ret_val = FAIL ; - break; - default: - break ; - } - return ret_val; -} - -TTYPE t_subValue(int nCalls, NdbOperation* pOp) { - - ndbout << "Defining subValue test " << nCalls << ": "; - - Uint32 val32 = 5; - Uint64 val64 = 5; - Uint32 attr0 = 0; - Uint32 attr1 = 1; - Uint32 attr20 = 20; - - TTYPE ret_val = NO_FAIL; - - switch(nCalls) { - case 1: - pOp->subValue("COL2", val32); - break; - case 2: - pOp->subValue(attr1, val32); - break; - case 3: - pOp->subValue("COL0", val32); - ret_val = FAIL ; - break; - case 4: - pOp->subValue(attr0, val32); - ret_val = FAIL ; - break; - case 5: - pOp->subValue("COL20", val32); - ret_val = FAIL ; - break; - case 6: - pOp->subValue(attr20, val32); - ret_val = FAIL ; - break; - case 7: - // Missing implementation - //pOp->subValue("COL20", val64); - ndbout << "Missing implementation" << endl; - break; - case 8: - // Missing implementation - //pOp->subValue("COL2", val64); - ndbout << "Missing implementation" << endl; - break; - case 9: - // Missing implementation - //pOp->subValue("COL0", val64); - ndbout << "Missing implementation" << endl; - break; - case 10: - // Missing implementation - //pOp->subValue(attr1, val64); - ndbout << "Missing implementation" << endl; - break; - case 11: - // Missing implementation - //pOp->subValue(attr0, val64); - ndbout << "Missing implementation" << endl; - break; - case 12: - // Missing implementation - //pOp->subValue(attr20, val64); - ndbout << "Missing implementation" << endl; - break; - default: - break ; - } - return ret_val ; -} - -TTYPE t_readAttr(int nCalls, NdbOperation* pOp) { - - ndbout << "Defining readAttr test " << nCalls << ": "; - - Uint32 attr0 = 0; - Uint32 attr1 = 1; - Uint32 attr20 = 20; - TTYPE ret_val = NO_FAIL; - - switch(nCalls) { - case 1: - pOp->read_attr("COL1", 1); - break; - case 2: - pOp->read_attr(attr1, 1); - ret_val = NO_FAIL ; - break; - case 3: - pOp->read_attr("COL0", 1); - ret_val = NO_FAIL ; - break; - case 4: - pOp->read_attr(attr0, 1); - ret_val = NO_FAIL ; - break; - case 5: - pOp->read_attr("COL20", 1); - ret_val = FAIL ; - break; - case 6: - pOp->read_attr(20, 1); - ret_val = FAIL ; - break; - case 7: - pOp->read_attr("COL1", 8); - ret_val = FAIL ; - break; - case 8: - pOp->read_attr(attr1, 8); - ret_val = FAIL ; - break; - default: - break ; - } - return ret_val; -} - -TTYPE t_writeAttr(int nCalls, NdbOperation* pOp) { - - ndbout << "Defining writeAttr test " << nCalls << ": "; - - pOp->load_const_u32(1, 5); - - Uint32 attr0 = 0; - Uint32 attr1 = 1; - Uint32 attr20 = 20; - TTYPE ret_val = NO_FAIL ; - - switch(nCalls) { - case 1: - pOp->write_attr("COL1", 1); - break; - case 2: - pOp->write_attr(attr1, 1); - break; - case 3: - pOp->write_attr("COL0", 1); - ret_val = FAIL ; - break; - case 4: - pOp->write_attr(attr0, 1); - ret_val = FAIL ; - break; - case 5: - pOp->write_attr("COL20", 1); - ret_val = FAIL ; - break; - case 6: - pOp->write_attr(20, 1); - ret_val = FAIL ; - break; - case 7: - pOp->write_attr("COL1", 2); - ret_val = FAIL ; - break; - case 8: - pOp->write_attr(attr1, 2); - ret_val = FAIL ; - break; - case 9: - pOp->write_attr("COL1", 8); - ret_val = FAIL ; - break; - case 10: - pOp->write_attr(attr1, 8); - ret_val = FAIL ; - break; - default: - break ; - } - return ret_val ; -} - -TTYPE t_loadConst(int nCalls, NdbOperation* pOp, int opType) { - - ndbout << "Defining loadConst test " << nCalls << " : "; - TTYPE ret_val = NO_FAIL ; - - switch(nCalls) { - case 1: - // Loading null into a valid register - pOp->load_const_null(1); - break; - case 2: - // Loading null into an invalid register - pOp->load_const_null(8); - ret_val = FAIL ; - break; - case 3: - // Test loading a 32-bit value (>65536) - pOp->load_const_u32(1, 65600); - break; - case 4: - // Test loading a 16-bit value (<65536) - pOp->load_const_u32(1, 65500); - break; - case 5: - // Test by loading to a non-valid register - pOp->load_const_u32(8, 2); - ret_val = FAIL ; - break; - case 6: - // Test by loading a 64-bit value - pOp->load_const_u64(1, 65600); - break; - case 7: - // Test by loading a non-valid register - pOp->load_const_u64(8, 2); - ret_val = FAIL ; - break; - case 8: - // Test by loading a valid register with -1 - pOp->load_const_u64(1, -1); - ret_val = FAIL ; - break; - - default: - break ; - } - - if (opType == 3 && FAIL != ret_val) - pOp->write_attr("COL1", 1); - return ret_val; -} - -TTYPE t_branch(int nCalls, NdbOperation* pOp) { - - ndbout << "Defining branch test " << nCalls << ": " ; - - TTYPE ret_val = NO_FAIL ; - Uint32 val32=5; - - pOp->read_attr("COL1", 1); - pOp->load_const_u32(2, val32); - - switch(nCalls) { - case 1: - pOp->branch_eq(1, 2, 0); - pOp->interpret_exit_nok(); - pOp->def_label(0); - pOp->interpret_exit_ok(); - break; - case 2: - pOp->branch_eq(2, 1, 0); - pOp->interpret_exit_nok(); - pOp->def_label(0); - pOp->interpret_exit_ok(); - break; - case 3: - pOp->branch_eq(1, 1, 0); - pOp->interpret_exit_nok(); - pOp->def_label(0); - pOp->interpret_exit_ok(); - break; - default: - //ndbout << "t_branch: default case (no test case)" << endl ; - //return ret_val = NO_FAIL ; - break ; - } - return ret_val; -} - -TTYPE t_branchIfNull(int nCalls, NdbOperation* pOp) { - - TTYPE ret_val = NO_FAIL; - ndbout << "Defining branchIfNull test " << nCalls << ": " << endl ; - - switch(nCalls) { - case 1: - pOp->load_const_u32(1, 1); - pOp->branch_ne_null(1, 0); - pOp->interpret_exit_nok(); - pOp->def_label(0); - pOp->interpret_exit_ok(); - break; - case 2: - pOp->load_const_null(1); - pOp->branch_ne_null(1, 0); - pOp->interpret_exit_ok(); - pOp->def_label(0); - pOp->interpret_exit_nok(); - break; - case 3: - pOp->load_const_u32(1, 1); - pOp->branch_eq_null(1, 0); - pOp->interpret_exit_ok(); - pOp->def_label(0); - pOp->interpret_exit_nok(); - break; - case 4: - pOp->load_const_null(1); - pOp->branch_ne_null(1, 0); - pOp->interpret_exit_ok(); - pOp->def_label(0); - pOp->interpret_exit_nok(); - break; - case 5: - // Test with a non-initialized register - pOp->branch_ne_null(3, 0); - pOp->interpret_exit_ok(); - pOp->def_label(0); - pOp->interpret_exit_nok(); - ret_val = FAIL ; - break; - case 6: - // Test with a non-existing register - pOp->branch_ne_null(8, 0); - pOp->interpret_exit_ok(); - pOp->def_label(0); - pOp->interpret_exit_nok(); - ret_val = FAIL ; - break; - case 7: - // Test with a non-initialized register - pOp->branch_eq_null(3, 0); - pOp->interpret_exit_ok(); - pOp->def_label(0); - pOp->interpret_exit_nok(); - ret_val = FAIL ; - break; - case 8: - // Test with a non-existing register - pOp->branch_ne_null(8, 0); - pOp->interpret_exit_ok(); - pOp->def_label(0); - pOp->interpret_exit_nok(); - ret_val = FAIL ; - break; - default: - break ; - } - - return ret_val; -} - -TTYPE t_addReg(int nCalls, NdbOperation* pOp) { - - TTYPE ret_val = NO_FAIL ; - - ndbout << "Defining addReg test " << nCalls << ": "; - - pOp->load_const_u32(1, 65500); - pOp->load_const_u32(2, 500); - pOp->load_const_u64(3, 65600); - pOp->load_const_u64(4, 95600); - - switch(nCalls) { - case 1: - pOp->add_reg(1, 2, 5); - break; - case 2: - pOp->add_reg(1, 3, 5); - break; - case 3: - pOp->add_reg(3, 1, 5); - break; - case 4: - pOp->add_reg(3, 4, 5); - break; - case 5: - pOp->add_reg(1, 6, 5); - break; - case 6: - pOp->add_reg(6, 1, 5); - break; - case 7: // illegal register - pOp->add_reg(1, 8, 5); - ret_val = FAIL ; - break; - case 8: // another illegal register - pOp->add_reg(8, 1, 5); - ret_val = FAIL ; - break; - case 9: // and another one - pOp->add_reg(1, 2, 8); - ret_val = FAIL ; - break; - default: - break ; - } - pOp->load_const_u32(7, 65000); - pOp->branch_eq(5, 7, 0); - pOp->interpret_exit_nok(); - pOp->def_label(0); - pOp->interpret_exit_ok(); - - return ret_val ; -} - -TTYPE t_subReg(int nCalls, NdbOperation* pOp) { - - TTYPE ret_val = NO_FAIL ; - ndbout << "Defining subReg test: " << nCalls << endl; - - pOp->load_const_u32(1, 65500); - pOp->load_const_u32(2, 500); - pOp->load_const_u64(3, 65600); - pOp->load_const_u64(4, 95600); - - switch(nCalls) { - case 1: - pOp->sub_reg(1, 2, 5); - pOp->load_const_u32(7, 65000); - break; - case 2: - pOp->sub_reg(1, 3, 5); - pOp->load_const_u64(7, (Uint64)-100); - break; - case 3: - pOp->sub_reg(3, 1, 5); - pOp->load_const_u64(7, (Uint64)100); - break; - case 4: - pOp->sub_reg(3, 4, 5); - pOp->load_const_u64(7, (Uint64)-30000); - break; - case 5: - pOp->sub_reg(1, 6, 5); - pOp->load_const_u64(7, 0); - ret_val = FAIL ; - break; - case 6: - pOp->sub_reg(6, 1, 5); - pOp->load_const_u64(7, 0); - ret_val = FAIL ; - break; - case 7: - pOp->sub_reg(1, 8, 5); - pOp->load_const_u64(7, 0); - ret_val = FAIL ; - break; - case 8: - pOp->sub_reg(8, 1, 5); - pOp->load_const_u64(7, 0); - ret_val = FAIL ; - break; - case 9: - pOp->sub_reg(1, 2, 8); - pOp->load_const_u32(7, (Uint32)65000); - ret_val = FAIL; - break; - default: - //ndbout << "t_subReg: default case (no test case)" << endl ; - //return ret_val = NO_FAIL ; - break ; - } - pOp->branch_eq(5, 7, 0); - pOp->interpret_exit_nok() ; - pOp->def_label(0); - pOp->interpret_exit_ok() ; - - return ret_val; -} - -TTYPE t_subroutineWithBranchLabel(int nCalls, NdbOperation* pOp) { - - TTYPE ret_val = NO_FAIL ; - ndbout << "Defining subroutineWithBranchLabel test:" << nCalls << endl; - - pOp->load_const_u32(1, 65500); - pOp->load_const_u32(2, 500); - pOp->load_const_u64(3, 65600); - pOp->load_const_u64(4, 95600); - pOp->load_const_u32(7, 65000); - pOp->call_sub(0) ; - - switch(nCalls) { - case 1: - pOp->def_subroutine(0) ; - pOp->add_reg(1, 2, 5); - break; - case 2: - pOp->def_subroutine(0) ; - pOp->add_reg(1, 3, 5); - break; - case 3: - pOp->def_subroutine(0) ; - pOp->add_reg(3, 1, 5); - break; - case 4: - pOp->def_subroutine(0) ; - pOp->add_reg(3, 4, 5); - break; - case 5: - pOp->def_subroutine(0) ; - pOp->add_reg(1, 6, 5); - break; - case 6: - pOp->def_subroutine(0) ; - pOp->add_reg(6, 1, 5); - break; - case 7: // illegal register - pOp->def_subroutine(0) ; - pOp->add_reg(1, 8, 5); - ret_val = FAIL ; - break; - case 8: // another illegal register - pOp->def_subroutine(0) ; - pOp->add_reg(8, 1, 5); - ret_val = FAIL ; - break; - case 9: // and another one - pOp->def_subroutine(0) ; - pOp->add_reg(1, 2, 8); - ret_val = FAIL ; - break; - case 10: // test subroutine nesting - for(int sub = 0; sub < 25 ; ++sub){ - pOp->call_sub(sub) ; - pOp->def_subroutine(sub + 1) ; - pOp->interpret_exit_ok() ; - pOp->ret_sub() ; - } - ret_val = FAIL ; - default: - break ; - } - - pOp->branch_label(0) ; - pOp->interpret_exit_nok() ; - pOp->def_label(0) ; - pOp->interpret_exit_ok() ; - pOp->ret_sub() ; - - return ret_val ; -} - - -void scan_rows(Ndb* pMyNdb, int opType, int tupleType, int scanType) { - - int check = -1 ; - int loop_count_ops = nRecords ; - int eOf = -1 ; - int readValue = 0 ; - int readValue2 = 0 ; - int scanCount = 0 ; - NdbRecAttr* tTmp = NULL ; - TTYPE fail = NO_FAIL ; - - for (int count=0 ; count < loop_count_ops ; count++) { - NdbConnection* MyTransaction = pMyNdb->startTransaction(); - if (!MyTransaction) error_handler(pMyNdb->getNdbError(), NO_FAIL); - - NdbOperation* MyOperation = MyTransaction->getNdbOperation(tableName[0]); - if (!MyOperation) error_handler(pMyNdb->getNdbError(), NO_FAIL); - - if (opType == 1) - // Open for scan read, Creates the SCAN_TABREQ and if needed - // SCAN_TABINFO signals. - check = MyOperation->openScanRead(1); - else if (opType == 2) - // Open for scan with update of rows. - check = MyOperation->openScanExclusive(1); - - // Create ATTRINFO signal(s) for interpreted program used for - // defining search criteria and column values that should be returned. - - scanCount = count+1 ; - - switch(tupleType) { - case 1: - fail = t_exitMethods(scanCount, MyOperation, opType); - break; - case 2: - fail = t_incValue(scanCount, MyOperation); - break; - case 3: - fail = t_subValue(scanCount, MyOperation); - break; - case 4: - fail = t_readAttr(scanCount, MyOperation); - break; - case 5: - fail = t_writeAttr(scanCount, MyOperation); - break; - case 6: - fail = t_loadConst(scanCount, MyOperation, opType); - break; - case 7: - fail = t_branch(scanCount, MyOperation); - break; - case 8: - fail = t_branchIfNull(scanCount, MyOperation); - break; - case 9: - fail = t_addReg(scanCount, MyOperation); - break; - case 10: - fail = t_subReg(scanCount, MyOperation); - break; - case 11: - fail = t_subroutineWithBranchLabel(scanCount, MyOperation); - break; - default: - break ; - } - - if(11 != tupleType) MyOperation->getValue(attrName[1], (char*)&readValue); - - // Sends the SCAN_TABREQ, (SCAN_TABINFO) and ATTRINFO signals and then - // reads the answer in TRANSID_AI. Confirmation is received through SCAN_TABCONF or - // SCAN_TABREF if failure. - check = MyTransaction->executeScan(); - if (check == -1) { - //ndbout << endl << "executeScan returned: " << MyTransaction->getNdbError() << endl; - error_handler(MyTransaction->getNdbError(), fail) ; - pMyNdb->closeTransaction(MyTransaction); - }else{ - // Sends the SCAN_NEXTREQ signal(s) and reads the answer in TRANS_ID signals. - // SCAN_TABCONF or SCAN_TABREF is the confirmation. - while (eOf = MyTransaction->nextScanResult() == 0) { - ndbout << readValue <<"; "; - // Here we call takeOverScanOp for update of the tuple. - } - ndbout << endl ; - - pMyNdb->closeTransaction(MyTransaction); - if (eOf == -1) { - ndbout << endl << "nextScanResult returned: "<< MyTransaction->getNdbError() << endl; - } else { - ndbout << "OK" << endl; - } - } - } - return; - -}; - - -void update_rows(Ndb* pMyNdb, int tupleType, int opType) { - /**************************************************************** - * Update rows in SimpleTable - * Only updates the first 3 cols. - ***************************************************************/ - - int check = -1 ; - int loop_count_ops = nRecords ; - int readValue[MAXATTR] = {0} ; - TTYPE ret_val = NO_FAIL ; - NdbConnection *MyTransaction = NULL ; - NdbOperation *MyOperation = NULL ; - - ndbout << "Updating records ..." << endl << endl; - - for (int count=0 ; count < loop_count_ops ; count++){ - - MyTransaction = pMyNdb->startTransaction(); - if (!MyTransaction) { - error_handler(pMyNdb->getNdbError(), NO_FAIL); - return; - }//if - - MyOperation = MyTransaction->getNdbOperation(tableName[0]); - if (MyOperation == NULL) { - error_handler(pMyNdb->getNdbError(), NO_FAIL); - return; - }//if - - // if (operationType == 3) - check = MyOperation->interpretedUpdateTuple(); - // else if (operationType == 4) - // check = MyOperation->interpretedDirtyUpdate(); - if( check == -1 ) - error_handler(MyTransaction->getNdbError(), NO_FAIL); - - check = MyOperation->equal( attrName[0], (char*)&pkValue[count] ); - if( check == -1 ) - error_handler(MyTransaction->getNdbError(), NO_FAIL); - - switch(tupleType) { - case 1: - ret_val = t_exitMethods(count+1, MyOperation, opType); - break; - case 2: - ret_val = t_incValue(count+1, MyOperation); - break; - case 3: - ret_val = t_subValue(count+1, MyOperation); - break; - case 4: - ret_val = t_readAttr(count+1, MyOperation); - break; - case 5: - ret_val = t_writeAttr(count+1, MyOperation); - break; - case 6: - ret_val = t_loadConst(count+1, MyOperation, opType); - break; - case 7: - ret_val = t_branch(count+1, MyOperation); - break; - case 8: - ret_val = t_branchIfNull(count+1, MyOperation); - break; - case 9: - ret_val = t_addReg(count+1, MyOperation); - break; - case 10: - ret_val = t_subReg(count+1, MyOperation); - break; - case 11: - ret_val = t_subroutineWithBranchLabel(count+1, MyOperation); - break; - default: - break ; - } - - MyOperation->getValue("COL1", (char*)&readValue); - - if (MyTransaction->execute( Commit ) == -1 ) { - error_handler(MyTransaction->getNdbError(), ret_val); - }else if (NO_FAIL == ret_val ) { - ndbout << "OK" << endl; - } else { - bTestPassed = -1; - ndbout << "Test passed when expected to fail" << endl; - }//if - pMyNdb->closeTransaction(MyTransaction); - - } - - ndbout << "Finished updating records" << endl; - return; -}; - -void delete_rows(Ndb* pMyNdb, int tupleTest, int opType) { - - /**************************************************************** - * Delete rows from SimpleTable - * - ***************************************************************/ - - int check = 1 ; - int loop_count_ops = nRecords ; - int readValue[MAXATTR] = {0}; - NdbConnection *MyTransaction = NULL ; - NdbOperation *MyOperation = NULL ; - TTYPE ret_val = NO_FAIL ; - - ndbout << "Deleting records ..."<< endl << endl; - - for (int count=0 ; count < loop_count_ops ; count++) { - - MyTransaction = pMyNdb->startTransaction(); - if (!MyTransaction) error_handler(pMyNdb->getNdbError(), NO_FAIL) ; - - MyOperation = MyTransaction->getNdbOperation(tableName[0]); - if (!MyOperation) error_handler(pMyNdb->getNdbError(), NO_FAIL) ; - - check = MyOperation->interpretedDeleteTuple(); - if( check == -1 ) error_handler(MyTransaction->getNdbError(), NO_FAIL) ; - - check = MyOperation->equal( attrName[0], (char*)&pkValue[count] ); - if( check == -1 ) error_handler(MyTransaction->getNdbError(), NO_FAIL) ; - - switch(tupleTest) { - case 1: - ret_val = t_exitMethods(count+1, MyOperation, opType); - break; - case 2: - ret_val = t_incValue(count+1, MyOperation); - break; - case 3: - ret_val = t_subValue(count+1, MyOperation); - break; - case 4: - ret_val = t_readAttr(count+1, MyOperation); - break; - case 5: - ret_val = t_writeAttr(count+1, MyOperation); - break; - case 6: - ret_val = t_loadConst(count+1, MyOperation, opType); - break; - case 7: - ret_val = t_branch(count+1, MyOperation); - break; - case 8: - ret_val = t_branchIfNull(count+1, MyOperation); - break; - case 9: - ret_val = t_addReg(count+1, MyOperation); - break; - case 10: - ret_val = t_subReg(count+1, MyOperation); - break; - case 11: - ret_val = t_subroutineWithBranchLabel(count+1, MyOperation); - break; - default: - break ; - } - - if(11 != tupleTest)MyOperation->getValue(attrName[1], (char*)&readValue) ; - - if (MyTransaction->execute( Commit ) == -1 ) { - error_handler(MyTransaction->getNdbError(), ret_val); - } else if (NO_FAIL == ret_val /*|| UNDEF == ret_val*/ ) { - ndbout << "OK" << endl; - } else { - bTestPassed = -1; - ndbout << "Test passed when expected to fail" << endl; - }//if - ndbout << endl; - pMyNdb->closeTransaction(MyTransaction); - } - - ndbout << "Finished deleting records" << endl; - return; - -}; - - -inline void setAttrNames(){ - for (int i = 0; i < MAXATTR; i++){ - snprintf(attrName[i], MAXSTRLEN, "COL%d", i); - } -} - - -inline void setTableNames(){ - for (int i = 0; i < MAXTABLES; i++){ - snprintf(tableName[i], MAXSTRLEN, "TAB%d", i); - } -} - diff --git a/ndb/test/ndbapi/lmc-bench/Makefile b/ndb/test/ndbapi/lmc-bench/Makefile deleted file mode 100644 index af472b1589f..00000000000 --- a/ndb/test/ndbapi/lmc-bench/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -include .defs.mk - -DIRS := src async-src script - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/test/ndbapi/lmc-bench/async-src/Makefile b/ndb/test/ndbapi/lmc-bench/async-src/Makefile deleted file mode 100644 index 744d6171139..00000000000 --- a/ndb/test/ndbapi/lmc-bench/async-src/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -include .defs.mk - -DIRS = \ - user \ - generator - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/test/ndbapi/lmc-bench/async-src/generator/Makefile b/ndb/test/ndbapi/lmc-bench/async-src/generator/Makefile deleted file mode 100644 index c1f84a3ef70..00000000000 --- a/ndb/test/ndbapi/lmc-bench/async-src/generator/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -SOURCES = mainAsyncGenerator.cpp asyncGenerator.cpp - -CCFLAGS_LOC := -I../include -I../../include - -BIN_TARGET := DbAsyncGenerator -BIN_TARGET_ARCHIVES := lmc_AsyncUser - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/test/ndbapi/lmc-bench/async-src/generator/asyncGenerator.cpp b/ndb/test/ndbapi/lmc-bench/async-src/generator/asyncGenerator.cpp deleted file mode 100644 index 84a93414712..00000000000 --- a/ndb/test/ndbapi/lmc-bench/async-src/generator/asyncGenerator.cpp +++ /dev/null @@ -1,571 +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 */ - -/*************************************************************** -* I N C L U D E D F I L E S * -***************************************************************/ - -#include - -#include "dbGenerator.h" -#include -#include -#include - -/*************************************************************** -* L O C A L C O N S T A N T S * -***************************************************************/ - -/*************************************************************** -* L O C A L D A T A S T R U C T U R E S * -***************************************************************/ - -/*************************************************************** -* L O C A L F U N C T I O N S * -***************************************************************/ - -static void getRandomSubscriberNumber(SubscriberNumber number); -static void getRandomServerId(ServerId *serverId); -static void getRandomChangedBy(ChangedBy changedBy); -static void getRandomChangedTime(ChangedTime changedTime); - -static void clearTransaction(TransactionDefinition *trans); -static void initGeneratorStatistics(GeneratorStatistics *gen); - -static void doOneTransaction(ThreadData * td, - int parallellism, - int millisSendPoll, - int minEventSendPoll, - int forceSendPoll); -static void doTransaction_T1(Ndb * pNDB, ThreadData * td, int async); -static void doTransaction_T2(Ndb * pNDB, ThreadData * td, int async); -static void doTransaction_T3(Ndb * pNDB, ThreadData * td, int async); -static void doTransaction_T4(Ndb * pNDB, ThreadData * td, int async); -static void doTransaction_T5(Ndb * pNDB, ThreadData * td, int async); - -/*************************************************************** -* L O C A L D A T A * -***************************************************************/ - -static SequenceValues transactionDefinition[] = { - {25, 1}, - {25, 2}, - {20, 3}, - {15, 4}, - {15, 5}, - {0, 0} -}; - -static SequenceValues rollbackDefinition[] = { - {98, 0}, - {2 , 1}, - {0, 0} -}; - -static int maxsize = 0; - -/*************************************************************** -* P U B L I C D A T A * -***************************************************************/ - -/*************************************************************** -**************************************************************** -* L O C A L F U N C T I O N S C O D E S E C T I O N * -**************************************************************** -***************************************************************/ - -static void getRandomSubscriberNumber(SubscriberNumber number) -{ - uint32 tmp; - char sbuf[SUBSCRIBER_NUMBER_LENGTH + 1]; - tmp = myRandom48(NO_OF_SUBSCRIBERS); - sprintf(sbuf, "%.*d", SUBSCRIBER_NUMBER_LENGTH, tmp); - memcpy(number, sbuf, SUBSCRIBER_NUMBER_LENGTH); -} - -static void getRandomServerId(ServerId *serverId) -{ - *serverId = myRandom48(NO_OF_SERVERS); -} - -static void getRandomChangedBy(ChangedBy changedBy) -{ - memset(changedBy, myRandom48(26)+'A', CHANGED_BY_LENGTH); - changedBy[CHANGED_BY_LENGTH] = 0; -} - -static void getRandomChangedTime(ChangedTime changedTime) -{ - memset(changedTime, myRandom48(26)+'A', CHANGED_TIME_LENGTH); - changedTime[CHANGED_TIME_LENGTH] = 0; -} - -static void clearTransaction(TransactionDefinition *trans) -{ - trans->count = 0; - trans->branchExecuted = 0; - trans->rollbackExecuted = 0; - trans->latencyCounter = myRandom48(127); - trans->latency.reset(); -} - -static int listFull(SessionList *list) -{ - return(list->numberInList == SESSION_LIST_LENGTH); -} - -static int listEmpty(SessionList *list) -{ - return(list->numberInList == 0); -} - -static void insertSession(SessionList *list, - SubscriberNumber number, - ServerId serverId) -{ - SessionElement *e; - if( listFull(list) ) return; - - e = &list->list[list->writeIndex]; - - strcpy(e->subscriberNumber, number); - e->serverId = serverId; - - list->writeIndex = (list->writeIndex + 1) % SESSION_LIST_LENGTH; - list->numberInList++; - - if( list->numberInList > maxsize ) - maxsize = list->numberInList; -} - -static SessionElement *getNextSession(SessionList *list) -{ - if( listEmpty(list) ) return(0); - - return(&list->list[list->readIndex]); -} - -static void deleteSession(SessionList *list) -{ - if( listEmpty(list) ) return; - - list->readIndex = (list->readIndex + 1) % SESSION_LIST_LENGTH; - list->numberInList--; -} - -static void initGeneratorStatistics(GeneratorStatistics *gen) -{ - int i; - - if( initSequence(&gen->transactionSequence, - transactionDefinition) != 0 ) { - ndbout_c("could not set the transaction types"); - exit(0); - } - - if( initSequence(&gen->rollbackSequenceT4, - rollbackDefinition) != 0 ) { - ndbout_c("could not set the rollback sequence"); - exit(0); - } - - if( initSequence(&gen->rollbackSequenceT5, - rollbackDefinition) != 0 ) { - ndbout_c("could not set the rollback sequence"); - exit(0); - } - - for(i = 0; i < NUM_TRANSACTION_TYPES; i++ ) - clearTransaction(&gen->transactions[i]); - - gen->totalTransactions = 0; - - gen->activeSessions.numberInList = 0; - gen->activeSessions.readIndex = 0; - gen->activeSessions.writeIndex = 0; -} - - -static -void -doOneTransaction(ThreadData * td, int p, int millis, int minEvents, int force) -{ - int i; - unsigned int transactionType; - int async = 1; - if (p == 1) { - async = 0; - }//if - for(i = 0; isendPollNdb(millis, minEvents, force); - }//if -} - -static -void -doTransaction_T1(Ndb * pNDB, ThreadData * td, int async) -{ - /*----------------*/ - /* Init arguments */ - /*----------------*/ - getRandomSubscriberNumber(td->transactionData.number); - getRandomChangedBy(td->transactionData.changed_by); - snprintf(td->transactionData.changed_time, - sizeof(td->transactionData.changed_time), - "%ld - %d", td->changedTime++, myRandom48(65536*1024)); - //getRandomChangedTime(td->transactionData.changed_time); - td->transactionData.location = td->transactionData.changed_by[0]; - - /*-----------------*/ - /* Run transaction */ - /*-----------------*/ - td->runState = Running; - td->generator.transactions[0].startLatency(); - - start_T1(pNDB, td, async); -} - -static -void -doTransaction_T2(Ndb * pNDB, ThreadData * td, int async) -{ - /*----------------*/ - /* Init arguments */ - /*----------------*/ - getRandomSubscriberNumber(td->transactionData.number); - - /*-----------------*/ - /* Run transaction */ - /*-----------------*/ - td->runState = Running; - td->generator.transactions[1].startLatency(); - - start_T2(pNDB, td, async); -} - -static -void -doTransaction_T3(Ndb * pNDB, ThreadData * td, int async) -{ - SessionElement *se; - - /*----------------*/ - /* Init arguments */ - /*----------------*/ - se = getNextSession(&td->generator.activeSessions); - if( se ) { - strcpy(td->transactionData.number, se->subscriberNumber); - td->transactionData.server_id = se->serverId; - td->transactionData.sessionElement = 1; - } else { - getRandomSubscriberNumber(td->transactionData.number); - getRandomServerId(&td->transactionData.server_id); - td->transactionData.sessionElement = 0; - } - - td->transactionData.server_bit = (1 << td->transactionData.server_id); - - /*-----------------*/ - /* Run transaction */ - /*-----------------*/ - td->runState = Running; - td->generator.transactions[2].startLatency(); - start_T3(pNDB, td, async); -} - -static -void -doTransaction_T4(Ndb * pNDB, ThreadData * td, int async) -{ - /*----------------*/ - /* Init arguments */ - /*----------------*/ - getRandomSubscriberNumber(td->transactionData.number); - getRandomServerId(&td->transactionData.server_id); - - td->transactionData.server_bit = (1 << td->transactionData.server_id); - td->transactionData.do_rollback = - getNextRandom(&td->generator.rollbackSequenceT4); - -#if 0 - memset(td->transactionData.session_details, - myRandom48(26)+'A', SESSION_DETAILS_LENGTH); -#endif - td->transactionData.session_details[SESSION_DETAILS_LENGTH] = 0; - - /*-----------------*/ - /* Run transaction */ - /*-----------------*/ - td->runState = Running; - td->generator.transactions[3].startLatency(); - start_T4(pNDB, td, async); -} - -static -void -doTransaction_T5(Ndb * pNDB, ThreadData * td, int async) -{ - SessionElement * se; - se = getNextSession(&td->generator.activeSessions); - if( se ) { - strcpy(td->transactionData.number, se->subscriberNumber); - td->transactionData.server_id = se->serverId; - td->transactionData.sessionElement = 1; - } - else { - getRandomSubscriberNumber(td->transactionData.number); - getRandomServerId(&td->transactionData.server_id); - td->transactionData.sessionElement = 0; - } - - td->transactionData.server_bit = (1 << td->transactionData.server_id); - td->transactionData.do_rollback - = getNextRandom(&td->generator.rollbackSequenceT5); - - /*-----------------*/ - /* Run transaction */ - /*-----------------*/ - td->runState = Running; - td->generator.transactions[4].startLatency(); - start_T5(pNDB, td, async); -} - -void -complete_T1(ThreadData * data){ - data->generator.transactions[0].stopLatency(); - data->generator.transactions[0].count++; - - data->runState = Runnable; - data->generator.totalTransactions++; -} - -void -complete_T2(ThreadData * data){ - data->generator.transactions[1].stopLatency(); - data->generator.transactions[1].count++; - - data->runState = Runnable; - data->generator.totalTransactions++; -} - -void -complete_T3(ThreadData * data){ - - data->generator.transactions[2].stopLatency(); - data->generator.transactions[2].count++; - - if(data->transactionData.branchExecuted) - data->generator.transactions[2].branchExecuted++; - - data->runState = Runnable; - data->generator.totalTransactions++; -} - -void -complete_T4(ThreadData * data){ - - data->generator.transactions[3].stopLatency(); - data->generator.transactions[3].count++; - - if(data->transactionData.branchExecuted) - data->generator.transactions[3].branchExecuted++; - if(data->transactionData.do_rollback) - data->generator.transactions[3].rollbackExecuted++; - - if(data->transactionData.branchExecuted && - !data->transactionData.do_rollback){ - insertSession(&data->generator.activeSessions, - data->transactionData.number, - data->transactionData.server_id); - } - - data->runState = Runnable; - data->generator.totalTransactions++; - -} -void -complete_T5(ThreadData * data){ - - data->generator.transactions[4].stopLatency(); - data->generator.transactions[4].count++; - - if(data->transactionData.branchExecuted) - data->generator.transactions[4].branchExecuted++; - if(data->transactionData.do_rollback) - data->generator.transactions[4].rollbackExecuted++; - - if(data->transactionData.sessionElement && - !data->transactionData.do_rollback){ - deleteSession(&data->generator.activeSessions); - } - - data->runState = Runnable; - data->generator.totalTransactions++; -} - -/*************************************************************** -**************************************************************** -* P U B L I C F U N C T I O N S C O D E S E C T I O N * -**************************************************************** -***************************************************************/ -void -asyncGenerator(ThreadData *data, - int parallellism, - int millisSendPoll, - int minEventSendPoll, - int forceSendPoll) -{ - ThreadData * startUp; - - GeneratorStatistics *st; - double periodStop; - double benchTimeStart; - double benchTimeEnd; - int i, j, done; - - myRandom48Init(data->randomSeed); - - for(i = 0; isendPollNdb(); - } - } - ndbout_c("Benchmark period starts"); - - /*-------------------------*/ - /* normal benchmark period */ - /*-------------------------*/ - benchTimeStart = userGetTime(); - - periodStop = benchTimeStart + (double)data[0].testSeconds; - while(userGetTime() < periodStop) - doOneTransaction(data, parallellism, - millisSendPoll, minEventSendPoll, forceSendPoll); - - benchTimeEnd = userGetTime(); - - ndbout_c("Benchmark period done"); - - /** - * Wait for all transactions - */ - done = 0; - while(!done){ - done = 1; - for(i = 0; isendPollNdb(); - } - } - - /*------------------*/ - /* cool down period */ - /*------------------*/ - periodStop = userGetTime() + (double)data[0].coolDownSeconds; - while(userGetTime() < periodStop){ - doOneTransaction(startUp, parallellism, - millisSendPoll, minEventSendPoll, forceSendPoll); - } - - done = 0; - while(!done){ - done = 1; - for(i = 0; isendPollNdb(); - } - } - - - /*---------------------------------------------------------*/ - /* add the times for all transaction for inner loop timing */ - /*---------------------------------------------------------*/ - for(j = 0; jouterLoopTime = benchTimeEnd - benchTimeStart; - st->outerTps = getTps(st->totalTransactions, st->outerLoopTime); - } - /* ndbout_c("maxsize = %d\n",maxsize); */ - - free(startUp); -} - diff --git a/ndb/test/ndbapi/lmc-bench/async-src/generator/mainAsyncGenerator.cpp b/ndb/test/ndbapi/lmc-bench/async-src/generator/mainAsyncGenerator.cpp deleted file mode 100644 index f613c66d07b..00000000000 --- a/ndb/test/ndbapi/lmc-bench/async-src/generator/mainAsyncGenerator.cpp +++ /dev/null @@ -1,392 +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 */ - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "userInterface.h" -#include "dbGenerator.h" - -static int numProcesses; -static int numSeconds; -static int numWarmSeconds; -static int parallellism; -static int millisSendPoll; -static int minEventSendPoll; -static int forceSendPoll; - -static ThreadData *data; - -static void usage(const char *prog) -{ - const char *progname; - - /*--------------------------------------------*/ - /* Get the name of the program (without path) */ - /*--------------------------------------------*/ - progname = strrchr(prog, '/'); - - if (progname == 0) - progname = prog; - else - ++progname; - - ndbout_c( - "Usage: %s [-proc ] [-warm ] [-time ] [ -p ] " - "[-t ] [ -e ] [ -f ] \n" - " -proc Specifies that is the number of\n" - " threads. The default is 1.\n" - " -time Specifies that the test will run for sec.\n" - " The default is 10 sec\n" - " -warm Specifies the warm-up/cooldown period of " - "sec.\n" - " The default is 10 sec\n" - " -p The no of parallell transactions started by " - "one thread\n" - " -e Minimum no of events before wake up in call to " - "sendPoll\n" - " Default is 1\n" - " -f force parameter to sendPoll\n" - " Default is 0\n", - progname); -} - -static -int -parse_args(int argc, const char **argv) -{ - int i; - - numProcesses = 1; - numSeconds = 10; - numWarmSeconds = 10; - parallellism = 1; - millisSendPoll = 10000; - minEventSendPoll = 1; - forceSendPoll = 0; - - - i = 1; - while (i < argc){ - if (strcmp("-proc",argv[i]) == 0) { - if (i + 1 >= argc) { - return 1; - } - if (sscanf(argv[i+1], "%d", &numProcesses) == -1 || - numProcesses <= 0 || numProcesses > 127) { - ndbout_c("-proc flag requires a positive integer argument [1..127]"); - return 1; - } - i += 2; - } else if (strcmp("-p", argv[i]) == 0){ - if(i + 1 >= argc){ - usage(argv[0]); - return 1; - } - if (sscanf(argv[i+1], "%d", ¶llellism) == -1 || - parallellism <= 0){ - ndbout_c("-p flag requires a positive integer argument"); - return 1; - } - i += 2; - } - else if (strcmp("-time",argv[i]) == 0) { - if (i + 1 >= argc) { - return 1; - } - if (sscanf(argv[i+1], "%d", &numSeconds) == -1 || - numSeconds < 0) { - ndbout_c("-time flag requires a positive integer argument"); - return 1; - } - i += 2; - } - else if (strcmp("-warm",argv[i]) == 0) { - if (i + 1 >= argc) { - return 1; - } - if (sscanf(argv[i+1], "%d", &numWarmSeconds) == -1 || - numWarmSeconds < 0) { - ndbout_c("-warm flag requires a positive integer argument"); - return 1; - } - i += 2; - } - else if (strcmp("-e",argv[i]) == 0) { - if (i + 1 >= argc) { - return 1; - } - if (sscanf(argv[i+1], "%d", &minEventSendPoll) == -1 || - minEventSendPoll < 0) { - ndbout_c("-e flag requires a positive integer argument"); - return 1; - } - i += 2; - } - else if (strcmp("-f",argv[i]) == 0) { - if (i + 1 >= argc) { - usage(argv[0]); - return 1; - } - if (sscanf(argv[i+1], "%d", &forceSendPoll) == -1 || - forceSendPoll < 0) { - ndbout_c("-f flag requires a positive integer argument"); - return 1; - } - i += 2; - } - else { - return 1; - } - } - - if(minEventSendPoll > parallellism){ - ndbout_c("minEventSendPoll(%d) > parallellism(%d)", - minEventSendPoll, parallellism); - ndbout_c("not very good..."); - ndbout_c("very bad..."); - ndbout_c("exiting..."); - return 1; - } - return 0; -} - -static -void -print_transaction(const char *header, - unsigned long totalCount, - TransactionDefinition *trans, - unsigned int printBranch, - unsigned int printRollback) -{ - double f; - - ndbout_c(" %s: %d (%.2f%%) " - "Latency(ms) avg: %d min: %d max: %d std: %d n: %d", - header, - trans->count, - (double)trans->count / (double)totalCount * 100.0, - (int)trans->latency.getMean(), - (int)trans->latency.getMin(), - (int)trans->latency.getMax(), - (int)trans->latency.getStddev(), - (int)trans->latency.getCount() - ); - - if( printBranch ){ - if( trans->count == 0 ) - f = 0.0; - else - f = (double)trans->branchExecuted / (double)trans->count * 100.0; - ndbout_c(" Branches Executed: %d (%.2f%%)", trans->branchExecuted, f); - } - - if( printRollback ){ - if( trans->count == 0 ) - f = 0.0; - else - f = (double)trans->rollbackExecuted / (double)trans->count * 100.0; - ndbout_c(" Rollback Executed: %d (%.2f%%)",trans->rollbackExecuted,f); - } -} - -void -print_stats(const char *title, - unsigned int length, - unsigned int transactionFlag, - GeneratorStatistics *gen, - int numProc, int parallellism) -{ - int i; - char buf[10]; - char name[MAXHOSTNAMELEN]; - - name[0] = 0; - NdbHost_GetHostName(name); - - ndbout_c("\n------ %s ------",title); - ndbout_c("Length : %d %s", - length, - transactionFlag ? "Transactions" : "sec"); - ndbout_c("Processor : %s", name); - ndbout_c("Number of Proc: %d",numProc); - ndbout_c("Parallellism : %d", parallellism); - ndbout_c("\n"); - - if( gen->totalTransactions == 0 ) { - ndbout_c(" No Transactions for this test"); - } - else { - for(i = 0; i < 5; i++) { - sprintf(buf, "T%d",i+1); - print_transaction(buf, - gen->totalTransactions, - &gen->transactions[i], - i >= 2, - i >= 3 ); - } - - ndbout_c("\n"); - ndbout_c(" Overall Statistics:"); - ndbout_c(" Transactions: %d", gen->totalTransactions); - ndbout_c(" Outer : %.0f TPS",gen->outerTps); - ndbout_c("\n"); - } -} - -static -void * -threadRoutine(void *arg) -{ - int i; - ThreadData *data = (ThreadData *)arg; - Ndb * pNDB; - - pNDB = asyncDbConnect(parallellism); - /* NdbSleep_MilliSleep(rand() % 10); */ - - for(i = 0; ipThread = pThread; - } else { - perror("Failed to create thread"); - rc = NDBT_FAILED; - } - } - - showTime(); - - /*--------------------------------*/ - /* Wait for all processes to exit */ - /*--------------------------------*/ - for(i = 0; i < numProcesses; i++) { - NdbThread_WaitFor(data[i*parallellism].pThread, &tmp); - NdbThread_Destroy(&data[i*parallellism].pThread); - } - - ndbout_c("All threads have finished"); - - /*-------------------------------------------*/ - /* Clear all structures for total statistics */ - /*-------------------------------------------*/ - stats.totalTransactions = 0; - stats.outerTps = 0.0; - - for(i = 0; i < NUM_TRANSACTION_TYPES; i++ ) { - stats.transactions[i].count = 0; - stats.transactions[i].branchExecuted = 0; - stats.transactions[i].rollbackExecuted = 0; - stats.transactions[i].latency.reset(); - } - - /*--------------------------------*/ - /* Add the values for all Threads */ - /*--------------------------------*/ - for(i = 0; i < numProcesses; i++) { - for(k = 0; ktotalTransactions; - stats.outerTps += p->outerTps; - - for(j = 0; j < NUM_TRANSACTION_TYPES; j++ ) { - stats.transactions[j].count += - p->transactions[j].count; - stats.transactions[j].branchExecuted += - p->transactions[j].branchExecuted; - stats.transactions[j].rollbackExecuted += - p->transactions[j].rollbackExecuted; - stats.transactions[j].latency += - p->transactions[j].latency; - } - } - } - - print_stats("Test Results", - numSeconds, - 0, - &stats, - numProcesses, - parallellism); - - free(data); - - NDBT_ProgramExit(rc); -} diff --git a/ndb/test/ndbapi/lmc-bench/async-src/include/dbGenerator.h b/ndb/test/ndbapi/lmc-bench/async-src/include/dbGenerator.h deleted file mode 100644 index 2256498e151..00000000000 --- a/ndb/test/ndbapi/lmc-bench/async-src/include/dbGenerator.h +++ /dev/null @@ -1,63 +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 */ - -#ifndef DBGENERATOR_H -#define DBGENERATOR_H - -/*************************************************************** -* I N C L U D E D F I L E S * -***************************************************************/ - -#include "testData.h" -#include "userInterface.h" - -/*************************************************************** -* M A C R O S * -***************************************************************/ - -/***************************************************************/ -/* C O N S T A N T S */ -/***************************************************************/ - -/*************************************************************** -* D A T A S T R U C T U R E S * -***************************************************************/ - -/*************************************************************** -* P U B L I C F U N C T I O N S * -***************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - -extern void asyncGenerator(ThreadData *d, int parallellism, - int millisSendPoll, - int minEventSendPoll, - int forceSendPoll); - -#ifdef __cplusplus -} -#endif - -/*************************************************************** -* E X T E R N A L D A T A * -***************************************************************/ - - - -#endif /* DBGENERATOR_H */ - diff --git a/ndb/test/ndbapi/lmc-bench/async-src/include/testData.h b/ndb/test/ndbapi/lmc-bench/async-src/include/testData.h deleted file mode 100644 index 3db85e7342e..00000000000 --- a/ndb/test/ndbapi/lmc-bench/async-src/include/testData.h +++ /dev/null @@ -1,156 +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 */ - -#ifndef TESTDATA_H -#define TESTDATA_H - -/*************************************************************** -* I N C L U D E D F I L E S * -***************************************************************/ -#include -#include -#include -#include -#include "testDefinitions.h" - -/*************************************************************** -* M A C R O S * -***************************************************************/ - -/***************************************************************/ -/* C O N S T A N T S */ -/***************************************************************/ - -#define NUM_TRANSACTION_TYPES 5 -#define SESSION_LIST_LENGTH 1000 - -/*************************************************************** -* D A T A S T R U C T U R E S * -***************************************************************/ - -typedef struct { - SubscriberNumber subscriberNumber; - ServerId serverId; -} SessionElement; - -typedef struct { - SessionElement list[SESSION_LIST_LENGTH]; - unsigned int readIndex; - unsigned int writeIndex; - unsigned int numberInList; -} SessionList; - -typedef struct { - unsigned int count; - unsigned int branchExecuted; - unsigned int rollbackExecuted; - - /** - * Latency measures - */ - NDB_TICKS startTime; - NDBT_Stats latency; - unsigned int latencyCounter; - - inline void startLatency(){ - if((latencyCounter & 127) == 127) - startTime = NdbTick_CurrentMillisecond(); - } - - inline void stopLatency(){ - if((latencyCounter & 127) == 127){ - const NDB_TICKS tmp = NdbTick_CurrentMillisecond() - startTime; - latency.addObservation(tmp); - } - latencyCounter++; - } -} TransactionDefinition; - -typedef struct { - RandomSequence transactionSequence; - RandomSequence rollbackSequenceT4; - RandomSequence rollbackSequenceT5; - - TransactionDefinition transactions[NUM_TRANSACTION_TYPES]; - - unsigned int totalTransactions; - - double outerLoopTime; - double outerTps; - - SessionList activeSessions; - -} GeneratorStatistics; - -typedef enum{ - Runnable, - Running -} RunState ; - -typedef struct { - SubscriberNumber number; - SubscriberSuffix suffix; - SubscriberName name; - Location location; - ChangedBy changed_by; - ChangedTime changed_time; - ServerId server_id; - ServerBit server_bit; - SessionDetails session_details; - - GroupId group_id; - ActiveSessions sessions; - Permission permission; - - unsigned int do_rollback; - - unsigned int branchExecuted; - unsigned int sessionElement; -} TransactionData ; - -typedef struct { - struct NdbThread* pThread; - - unsigned long randomSeed; - unsigned long changedTime; - - unsigned int warmUpSeconds; - unsigned int testSeconds; - unsigned int coolDownSeconds; - - GeneratorStatistics generator; - - /** - * For async execution - */ - RunState runState; - double startTime; - TransactionData transactionData; - struct Ndb * pNDB; -} ThreadData; - -/*************************************************************** - * P U B L I C F U N C T I O N S * - ***************************************************************/ - -/*************************************************************** - * E X T E R N A L D A T A * - ***************************************************************/ - - - -#endif /* TESTDATA_H */ - diff --git a/ndb/test/ndbapi/lmc-bench/async-src/include/userInterface.h b/ndb/test/ndbapi/lmc-bench/async-src/include/userInterface.h deleted file mode 100644 index 94bd1e80ab3..00000000000 --- a/ndb/test/ndbapi/lmc-bench/async-src/include/userInterface.h +++ /dev/null @@ -1,79 +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 */ - -#ifndef DBINTERFACE_H -#define DBINTERFACE_H - -/***************************************************************/ -/* I N C L U D E D F I L E S */ -/***************************************************************/ - -#include "testDefinitions.h" -#include "testData.h" - -/*************************************************************** -* M A C R O S * -***************************************************************/ - -/***************************************************************/ -/* C O N S T A N T S */ -/***************************************************************/ - -/*-----------------------*/ -/* Default Database Name */ -/*-----------------------*/ -#define DEFAULTDB "TestDbClient" - -/*************************************************************** -* D A T A S T R U C T U R E S * -***************************************************************/ - -/*************************************************************** -* P U B L I C F U N C T I O N S * -***************************************************************/ - -typedef struct Ndb Ndb; - -#ifdef __cplusplus -extern "C" { -#endif - extern void showTime(); - extern double userGetTime(void); - extern Ndb *asyncDbConnect(int parallellism); - extern void asyncDbDisconnect(Ndb* pNDB); - - extern void start_T1(Ndb * uh, ThreadData * data, int async); - extern void start_T2(Ndb * uh, ThreadData * data, int async); - extern void start_T3(Ndb * uh, ThreadData * data, int async); - extern void start_T4(Ndb * uh, ThreadData * data, int async); - extern void start_T5(Ndb * uh, ThreadData * data, int async); - - extern void complete_T1(ThreadData * data); - extern void complete_T2(ThreadData * data); - extern void complete_T3(ThreadData * data); - extern void complete_T4(ThreadData * data); - extern void complete_T5(ThreadData * data); - -#ifdef __cplusplus -} -#endif - -/*************************************************************** -* E X T E R N A L D A T A * -***************************************************************/ - -#endif /* DBINTERFACE_H */ - diff --git a/ndb/test/ndbapi/lmc-bench/async-src/user/Makefile b/ndb/test/ndbapi/lmc-bench/async-src/user/Makefile deleted file mode 100644 index c0b532a8359..00000000000 --- a/ndb/test/ndbapi/lmc-bench/async-src/user/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -ARCHIVE_TARGET := lmc_AsyncUser - -SOURCES := userInterface.C ndb_async2.C - -CCFLAGS_LOC = -I../include -I../../include - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/lmc-bench/async-src/user/macros.h b/ndb/test/ndbapi/lmc-bench/async-src/user/macros.h deleted file mode 100644 index 22b7f564490..00000000000 --- a/ndb/test/ndbapi/lmc-bench/async-src/user/macros.h +++ /dev/null @@ -1,51 +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 */ - -#ifndef MACROS_H -#define MACROS_H - -#include -#include - -#define ERROR(x) {ndbout_c((x));} -#define ERROR1(x,y) {ndbout_c((x), (y));} -#define ERROR2(x,y,z) {ndbout_c((x), (y), (z));} -#define ERROR3(x,y,z,u) {ndbout_c((x), (y), (z), (u));} -#define ERROR4(x,y,z,u,w) {ndbout_c((x), (y), (z), (u), (w));} - -#define INIT_RANDOM(x) srand48((x)) -#define UI_RANDOM(x) ((unsigned int)(lrand48()%(x))) - -#define ASSERT(cond, message) \ - { if(!(cond)) { ERROR(message); exit(-1); }} - -#ifdef DEBUG_ON -#define DEBUG(x) {ndbout_c((x));} -#define DEBUG1(x,y) {ndbout_c((x), (y));} -#define DEBUG2(x,y,z) {ndbout_c((x), (y), (z));} -#define DEBUG3(x,y,z,u) {ndbout_c((x), (y), (z), (u));} -#define DEBUG4(x,y,z,u,w) {ndbout_c((x), (y), (z), (u), (w));} -#define DEBUG5(x,y,z,u,w, v) {ndbout_c((x), (y), (z), (u), (w), (v));} -#else -#define DEBUG(x) -#define DEBUG1(x,y) -#define DEBUG2(x,y,z) -#define DEBUG3(x,y,z,u) -#define DEBUG4(x,y,z,u,w) -#define DEBUG5(x,y,z,u,w, v) -#endif - -#endif diff --git a/ndb/test/ndbapi/lmc-bench/async-src/user/ndb_async1.cpp b/ndb/test/ndbapi/lmc-bench/async-src/user/ndb_async1.cpp deleted file mode 100644 index 2a84f6b2aca..00000000000 --- a/ndb/test/ndbapi/lmc-bench/async-src/user/ndb_async1.cpp +++ /dev/null @@ -1,647 +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 */ - -//#define DEBUG_ON - -#include "userInterface.h" - -#include "macros.h" -#include "ndb_schema.hpp" -#include "ndb_error.hpp" - -#include - -inline -NdbConnection * -startTransaction(Ndb * pNDB, - ServerId inServerId, - const SubscriberNumber inNumber){ - - const int keyDataLenBytes = sizeof(ServerId)+SUBSCRIBER_NUMBER_LENGTH; - const int keyDataLen_64Words = keyDataLenBytes >> 3; - - Uint64 keyDataBuf[keyDataLen_64Words+1]; // The "+1" is for rounding... - - char * keyDataBuf_charP = (char *)&keyDataBuf[0]; - Uint32 * keyDataBuf_wo32P = (Uint32 *)&keyDataBuf[0]; - - // Server Id comes first - keyDataBuf_wo32P[0] = inServerId; - // Then subscriber number - memcpy(&keyDataBuf_charP[sizeof(ServerId)], inNumber, - SUBSCRIBER_NUMBER_LENGTH); - - return pNDB->startTransaction(0, keyDataBuf_charP, keyDataLenBytes); -} - -void T1_Callback(int result, NdbConnection * pCon, void * threadData); -void T2_Callback(int result, NdbConnection * pCon, void * threadData); -void T3_Callback_1(int result, NdbConnection * pCon, void * threadData); -void T3_Callback_2(int result, NdbConnection * pCon, void * threadData); -void T3_Callback_3(int result, NdbConnection * pCon, void * threadData); -void T4_Callback_1(int result, NdbConnection * pCon, void * threadData); -void T4_Callback_2(int result, NdbConnection * pCon, void * threadData); -void T4_Callback_3(int result, NdbConnection * pCon, void * threadData); -void T5_Callback_1(int result, NdbConnection * pCon, void * threadData); -void T5_Callback_2(int result, NdbConnection * pCon, void * threadData); -void T5_Callback_3(int result, NdbConnection * pCon, void * threadData); - -/** - * Transaction 1 - T1 - * - * Update location and changed by/time on a subscriber - * - * Input: - * SubscriberNumber, - * Location, - * ChangedBy, - * ChangedTime - * - * Output: - */ -void -start_T1(Ndb * pNDB, ThreadData * td){ - - DEBUG2("T1(%.*s): - Starting\n", SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number); - - int check; - NdbConnection * pCON = pNDB->startTransaction(); - if (pCON != NULL) { - NdbOperation *MyOp = pCON->getNdbOperation(SUBSCRIBER_TABLE); - if (MyOp != NULL) { - MyOp->updateTuple(); - MyOp->equal(IND_SUBSCRIBER_NUMBER, - td->transactionData.number); - MyOp->setValue(IND_SUBSCRIBER_LOCATION, - (char *)&td->transactionData.location); - MyOp->setValue(IND_SUBSCRIBER_CHANGED_BY, - td->transactionData.changed_by); - MyOp->setValue(IND_SUBSCRIBER_CHANGED_TIME, - td->transactionData.changed_time); - pCON->executeAsynchPrepare( Commit , T1_Callback, td); - } else { - CHECK_NULL(MyOp, "T1: getNdbOperation", pCON); - }//if - } else { - error_handler("T1-1: startTranscation", - pNDB->getNdbErrorString(), - pNDB->getNdbError()); - }//if -} - -void -T1_Callback(int result, NdbConnection * pCON, void * threadData){ - ThreadData * td = (ThreadData *)threadData; - - DEBUG2("T1(%.*s): - Completing\n", SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number); - - CHECK_MINUS_ONE(result, "T1: Commit", - pCON); - td->pNDB->closeTransaction(pCON); - complete_T1(td); -} - -/** - * Transaction 2 - T2 - * - * Read from Subscriber: - * - * Input: - * SubscriberNumber - * - * Output: - * Location - * Changed by - * Changed Timestamp - * Name - */ -void -start_T2(Ndb * pNDB, ThreadData * td){ - - DEBUG3("T2(%.*s, %p): - Starting\n", SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.location); - - int check; - NdbRecAttr * check2; - - NdbConnection * pCON = pNDB->startTransaction(); - if (pCON == NULL) - error_handler("T2-1: startTransaction", - pNDB->getNdbErrorString(), - pNDB->getNdbError()); - - NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOp, "T2: getNdbOperation", - pCON); - - MyOp->readTuple(); - MyOp->equal(IND_SUBSCRIBER_NUMBER, - td->transactionData.number); - MyOp->getValue(IND_SUBSCRIBER_LOCATION, - (char *)&td->transactionData.location); - MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, - td->transactionData.changed_by); - MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, - td->transactionData.changed_time); - MyOp->getValue(IND_SUBSCRIBER_NAME, - td->transactionData.name); - pCON->executeAsynchPrepare( Commit, T2_Callback, td ); -} - -void -T2_Callback(int result, NdbConnection * pCON, void * threadData){ - ThreadData * td = (ThreadData *)threadData; - DEBUG3("T2(%.*s, %p): - Completing\n", SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.location); - - CHECK_MINUS_ONE(result, "T2: Commit", pCON); - td->pNDB->closeTransaction(pCON); - complete_T2(td); -} - -/** - * Transaction 3 - T3 - * - * Read session details - * - * Input: - * SubscriberNumber - * ServerId - * ServerBit - * - * Output: - * BranchExecuted - * SessionDetails - * ChangedBy - * ChangedTime - * Location - */ -void -start_T3(Ndb * pNDB, ThreadData * td){ - - DEBUG3("T3(%.*s, %.2d): - Starting\n", SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id); - - int check; - NdbRecAttr * check2; - - NdbConnection * pCON = startTransaction(pNDB, - td->transactionData.server_id, - td->transactionData.number); - if (pCON == NULL) - error_handler("T3-1: startTranscation", - pNDB->getNdbErrorString(), - pNDB->getNdbError()); - - NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOp, "T3-1: getNdbOperation", - pCON); - - MyOp->readTuple(); - MyOp->equal(IND_SUBSCRIBER_NUMBER, - td->transactionData.number); - MyOp->getValue(IND_SUBSCRIBER_LOCATION, - (char *)&td->transactionData.location); - MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, - td->transactionData.changed_by); - MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, - td->transactionData.changed_time); - MyOp->getValue(IND_SUBSCRIBER_GROUP, - (char *)&td->transactionData.group_id); - MyOp->getValue(IND_SUBSCRIBER_SESSIONS, - (char *)&td->transactionData.sessions); - pCON->executeAsynchPrepare( NoCommit , T3_Callback_1, td); -} - -void -T3_Callback_1(int result, NdbConnection * pCON, void * threadData){ - ThreadData * td = (ThreadData *)threadData; - DEBUG3("T3(%.*s, %.2d): - Callback 1\n", SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id); - - CHECK_MINUS_ONE(result, "T3-1: NoCommit", pCON); - - NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE); - CHECK_NULL(MyOp, "T3-2: getNdbOperation", - pCON); - - MyOp->readTuple(); - MyOp->equal(IND_GROUP_ID, - (char*)&td->transactionData.group_id); - MyOp->getValue(IND_GROUP_ALLOW_READ, - (char *)&td->transactionData.permission); - pCON->executeAsynchPrepare( NoCommit, T3_Callback_2, td ); -} - -void -T3_Callback_2(int result, NdbConnection * pCON, void * threadData){ - ThreadData * td = (ThreadData *)threadData; - - CHECK_MINUS_ONE(result, "T3-2: NoCommit", pCON); - - Uint32 permission = td->transactionData.permission; - Uint32 sessions = td->transactionData.sessions; - Uint32 server_bit = td->transactionData.server_bit; - - if(((permission & server_bit) == server_bit) && - ((sessions & server_bit) == server_bit)){ - - memcpy(td->transactionData.suffix, - &td->transactionData.number - [SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], - SUBSCRIBER_NUMBER_SUFFIX_LENGTH); - DEBUG5("T3(%.*s, %.2d): - Callback 2 - reading(%.*s)\n", - SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id, - SUBSCRIBER_NUMBER_SUFFIX_LENGTH, - td->transactionData.suffix); - - /* Operation 3 */ - NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); - CHECK_NULL(MyOp, "T3-3: getNdbOperation", - pCON); - - MyOp->simpleRead(); - MyOp->equal(IND_SESSION_SUBSCRIBER, - (char*)td->transactionData.number); - MyOp->equal(IND_SESSION_SERVER, - (char*)&td->transactionData.server_id); - MyOp->getValue(IND_SESSION_DATA, - (char *)td->transactionData.session_details); - - /* Operation 4 */ - MyOp = pCON->getNdbOperation(SERVER_TABLE); - CHECK_NULL(MyOp, "T3-4: getNdbOperation", - pCON); - - MyOp->interpretedUpdateTuple(); - MyOp->equal(IND_SERVER_ID, - (char*)&td->transactionData.server_id); - MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX, - (char*)td->transactionData.suffix); - MyOp->incValue(IND_SERVER_READS, (uint32)1); - td->transactionData.branchExecuted = 1; - } else { - DEBUG3("T3(%.*s, %.2d): - Callback 2 - no read\n", - SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id); - td->transactionData.branchExecuted = 0; - } - pCON->executeAsynchPrepare( Commit, T3_Callback_3, td ); -} - -void -T3_Callback_3(int result, NdbConnection * pCON, void * threadData){ - ThreadData * td = (ThreadData *)threadData; - DEBUG3("T3(%.*s, %.2d): - Completing\n", SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id); - - CHECK_MINUS_ONE(result, "T3-3: Commit", pCON); - - td->pNDB->closeTransaction(pCON); - complete_T3(td); -} - -/** - * Transaction 4 - T4 - * - * Create session - * - * Input: - * SubscriberNumber - * ServerId - * ServerBit - * SessionDetails, - * DoRollback - * Output: - * ChangedBy - * ChangedTime - * Location - * BranchExecuted - */ -void -start_T4(Ndb * pNDB, ThreadData * td){ - - DEBUG3("T4(%.*s, %.2d): - Starting\n", SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id); - - int check; - NdbRecAttr * check2; - - NdbConnection * pCON = startTransaction(pNDB, - td->transactionData.server_id, - td->transactionData.number); - if (pCON == NULL) - error_handler("T4-1: startTranscation", - pNDB->getNdbErrorString(), - pNDB->getNdbError()); - - NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOp, "T4-1: getNdbOperation", - pCON); - - MyOp->interpretedUpdateTuple(); - MyOp->equal(IND_SUBSCRIBER_NUMBER, - td->transactionData.number); - MyOp->getValue(IND_SUBSCRIBER_LOCATION, - (char *)&td->transactionData.location); - MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, - td->transactionData.changed_by); - MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, - td->transactionData.changed_time); - MyOp->getValue(IND_SUBSCRIBER_GROUP, - (char *)&td->transactionData.group_id); - MyOp->getValue(IND_SUBSCRIBER_SESSIONS, - (char *)&td->transactionData.sessions); - MyOp->incValue(IND_SUBSCRIBER_SESSIONS, - (uint32)td->transactionData.server_bit); - pCON->executeAsynchPrepare( NoCommit , T4_Callback_1, td); -} - -void -T4_Callback_1(int result, NdbConnection * pCON, void * threadData){ - CHECK_MINUS_ONE(result, "T4-1: NoCommit", pCON); - ThreadData * td = (ThreadData *)threadData; - - DEBUG3("T4(%.*s, %.2d): - Callback 1\n", - SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id); - - - NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE); - CHECK_NULL(MyOp, "T4-2: getNdbOperation", - pCON); - - MyOp->readTuple(); - MyOp->equal(IND_GROUP_ID, - (char*)&td->transactionData.group_id); - MyOp->getValue(IND_GROUP_ALLOW_INSERT, - (char *)&td->transactionData.permission); - pCON->executeAsynchPrepare( NoCommit , T4_Callback_2, td); -} - -void -T4_Callback_2(int result, NdbConnection * pCON, void * threadData){ - CHECK_MINUS_ONE(result, "T4-2: NoCommit", pCON); - ThreadData * td = (ThreadData *)threadData; - - Uint32 permission = td->transactionData.permission; - Uint32 sessions = td->transactionData.sessions; - Uint32 server_bit = td->transactionData.server_bit; - - if(((permission & server_bit) == server_bit) && - ((sessions & server_bit) == 0)){ - - memcpy(td->transactionData.suffix, - &td->transactionData.number - [SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], - SUBSCRIBER_NUMBER_SUFFIX_LENGTH); - - DEBUG5("T4(%.*s, %.2d): - Callback 2 - inserting(%.*s)\n", - SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id, - SUBSCRIBER_NUMBER_SUFFIX_LENGTH, - td->transactionData.suffix); - - /* Operation 3 */ - - NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); - CHECK_NULL(MyOp, "T4-3: getNdbOperation", - pCON); - - MyOp->insertTuple(); - MyOp->equal(IND_SESSION_SUBSCRIBER, - (char*)td->transactionData.number); - MyOp->equal(IND_SESSION_SERVER, - (char*)&td->transactionData.server_id); - MyOp->setValue(SESSION_DATA, - (char *)td->transactionData.session_details); - /* Operation 4 */ - - /* Operation 5 */ - MyOp = pCON->getNdbOperation(SERVER_TABLE); - CHECK_NULL(MyOp, "T4-5: getNdbOperation", - pCON); - - MyOp->interpretedUpdateTuple(); - MyOp->equal(IND_SERVER_ID, - (char*)&td->transactionData.server_id); - MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX, - (char*)td->transactionData.suffix); - MyOp->incValue(IND_SERVER_INSERTS, (uint32)1); - td->transactionData.branchExecuted = 1; - } else { - td->transactionData.branchExecuted = 0; - DEBUG5("T4(%.*s, %.2d): - Callback 2 - %s %s\n", - SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id, - ((permission & server_bit) ? - "permission - " : "no permission - "), - ((sessions & server_bit) ? - "in session - " : "no in session - ")); - } - - if(!td->transactionData.do_rollback && td->transactionData.branchExecuted){ - pCON->executeAsynchPrepare(Commit, T4_Callback_3, td); - } else { - pCON->executeAsynchPrepare(Rollback, T4_Callback_3, td); - } -} - -void -T4_Callback_3(int result, NdbConnection * pCON, void * threadData){ - CHECK_MINUS_ONE(result, "T4-3: Commit", pCON); - ThreadData * td = (ThreadData *)threadData; - - DEBUG3("T4(%.*s, %.2d): - Completing\n", - SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id); - - td->pNDB->closeTransaction(pCON); - complete_T4(td); -} - -/** - * Transaction 5 - T5 - * - * Delete session - * - * Input: - * SubscriberNumber - * ServerId - * ServerBit - * DoRollback - * Output: - * ChangedBy - * ChangedTime - * Location - * BranchExecuted - */ -void -start_T5(Ndb * pNDB, ThreadData * td){ - - DEBUG3("T5(%.*s, %.2d): - Starting\n", SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id); - - int check; - NdbRecAttr * check2; - - NdbConnection * pCON = pNDB->startTransaction(); - if (pCON == NULL) - error_handler("T5-1: startTranscation", - pNDB->getNdbErrorString(), - pNDB->getNdbError()); - - NdbOperation * MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOp, "T5-1: getNdbOperation", - pCON); - - MyOp->interpretedUpdateTuple(); - MyOp->equal(IND_SUBSCRIBER_NUMBER, - td->transactionData.number); - MyOp->getValue(IND_SUBSCRIBER_LOCATION, - (char *)&td->transactionData.location); - MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, - td->transactionData.changed_by); - MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, - td->transactionData.changed_time); - MyOp->getValue(IND_SUBSCRIBER_GROUP, - (char *)&td->transactionData.group_id); - MyOp->getValue(IND_SUBSCRIBER_SESSIONS, - (char *)&td->transactionData.sessions); - MyOp->subValue(IND_SUBSCRIBER_SESSIONS, - (uint32)td->transactionData.server_bit); - pCON->executeAsynchPrepare( NoCommit, T5_Callback_1, td ); -} - -void -T5_Callback_1(int result, NdbConnection * pCON, void * threadData){ - CHECK_MINUS_ONE(result, "T5-1: NoCommit", pCON); - ThreadData * td = (ThreadData *)threadData; - - DEBUG3("T5(%.*s, %.2d): - Callback 1\n", - SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id); - - NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE); - CHECK_NULL(MyOp, "T5-2: getNdbOperation", - pCON); - - MyOp->readTuple(); - MyOp->equal(IND_GROUP_ID, - (char*)&td->transactionData.group_id); - MyOp->getValue(IND_GROUP_ALLOW_DELETE, - (char *)&td->transactionData.permission); - pCON->executeAsynchPrepare( NoCommit, T5_Callback_2, td ); -} - -void -T5_Callback_2(int result, NdbConnection * pCON, void * threadData){ - CHECK_MINUS_ONE(result, "T5-2: NoCommit", pCON); - ThreadData * td = (ThreadData *)threadData; - - Uint32 permission = td->transactionData.permission; - Uint32 sessions = td->transactionData.sessions; - Uint32 server_bit = td->transactionData.server_bit; - - if(((permission & server_bit) == server_bit) && - ((sessions & server_bit) == server_bit)){ - - memcpy(td->transactionData.suffix, - &td->transactionData.number - [SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], - SUBSCRIBER_NUMBER_SUFFIX_LENGTH); - - DEBUG5("T5(%.*s, %.2d): - Callback 2 - deleting(%.*s)\n", - SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id, - SUBSCRIBER_NUMBER_SUFFIX_LENGTH, - td->transactionData.suffix); - - /* Operation 3 */ - NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); - CHECK_NULL(MyOp, "T5-3: getNdbOperation", - pCON); - - MyOp->deleteTuple(); - MyOp->equal(IND_SESSION_SUBSCRIBER, - (char*)td->transactionData.number); - MyOp->equal(IND_SESSION_SERVER, - (char*)&td->transactionData.server_id); - /* Operation 4 */ - - /* Operation 5 */ - MyOp = pCON->getNdbOperation(SERVER_TABLE); - CHECK_NULL(MyOp, "T5-5: getNdbOperation", - pCON); - - MyOp->interpretedUpdateTuple(); - MyOp->equal(IND_SERVER_ID, - (char*)&td->transactionData.server_id); - MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX, - (char*)td->transactionData.suffix); - MyOp->incValue(IND_SERVER_DELETES, (uint32)1); - td->transactionData.branchExecuted = 1; - } else { - td->transactionData.branchExecuted = 0; - - DEBUG5("T5(%.*s, %.2d): - Callback 2 - no delete - %s %s\n", - SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id, - ((permission & server_bit) ? - "permission - " : "no permission - "), - ((sessions & server_bit) ? - "in session - " : "no in session - ")); - } - - if(!td->transactionData.do_rollback && td->transactionData.branchExecuted){ - pCON->executeAsynchPrepare(Commit, T5_Callback_3, td); - } else { - pCON->executeAsynchPrepare(Rollback, T5_Callback_3, td); - } -} - -void -T5_Callback_3(int result, NdbConnection * pCON, void * threadData){ - CHECK_MINUS_ONE(result, "T5-3: Commit", pCON); - ThreadData * td = (ThreadData *)threadData; - - DEBUG3("T5(%.*s, %.2d): - Completing\n", - SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id); - - td->pNDB->closeTransaction(pCON); - complete_T5(td); -} diff --git a/ndb/test/ndbapi/lmc-bench/async-src/user/ndb_async2.cpp b/ndb/test/ndbapi/lmc-bench/async-src/user/ndb_async2.cpp deleted file mode 100644 index 0c1d138defb..00000000000 --- a/ndb/test/ndbapi/lmc-bench/async-src/user/ndb_async2.cpp +++ /dev/null @@ -1,754 +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 */ - -//#define DEBUG_ON - -#include -#include "userInterface.h" - -#include "macros.h" -#include "ndb_schema.hpp" -#include "ndb_error.hpp" -#include - -#include - -void T1_Callback(int result, NdbConnection * pCon, void * threadData); -void T2_Callback(int result, NdbConnection * pCon, void * threadData); -void T3_Callback_1(int result, NdbConnection * pCon, void * threadData); -void T3_Callback_2(int result, NdbConnection * pCon, void * threadData); -void T3_Callback_3(int result, NdbConnection * pCon, void * threadData); -void T4_Callback_1(int result, NdbConnection * pCon, void * threadData); -void T4_Callback_2(int result, NdbConnection * pCon, void * threadData); -void T4_Callback_3(int result, NdbConnection * pCon, void * threadData); -void T5_Callback_1(int result, NdbConnection * pCon, void * threadData); -void T5_Callback_2(int result, NdbConnection * pCon, void * threadData); -void T5_Callback_3(int result, NdbConnection * pCon, void * threadData); - -static int stat_async = 0; - -/** - * Transaction 1 - T1 - * - * Update location and changed by/time on a subscriber - * - * Input: - * SubscriberNumber, - * Location, - * ChangedBy, - * ChangedTime - * - * Output: - */ - -#define SFX_START (SUBSCRIBER_NUMBER_LENGTH - SUBSCRIBER_NUMBER_SUFFIX_LENGTH) - -inline -NdbConnection * -startTransaction(Ndb * pNDB, ThreadData * td){ - return pNDB->startTransactionDGroup (0, - &td->transactionData.number[SFX_START], - 1); -} - -void -start_T1(Ndb * pNDB, ThreadData * td, int async){ - - DEBUG2("T1(%.*s): - Starting", SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number); - - NdbConnection * pCON = 0; - while((pCON = startTransaction(pNDB, td)) == 0){ - CHECK_ALLOWED_ERROR("T1: startTransaction", td, pNDB->getNdbError()); - NdbSleep_MilliSleep(10); - } - - NdbOperation *MyOp = pCON->getNdbOperation(SUBSCRIBER_TABLE); - if (MyOp != NULL) { - MyOp->updateTuple(); - MyOp->equal(IND_SUBSCRIBER_NUMBER, - td->transactionData.number); - MyOp->setValue(IND_SUBSCRIBER_LOCATION, - (char *)&td->transactionData.location); - MyOp->setValue(IND_SUBSCRIBER_CHANGED_BY, - td->transactionData.changed_by); - MyOp->setValue(IND_SUBSCRIBER_CHANGED_TIME, - td->transactionData.changed_time); - if (async == 1) { - pCON->executeAsynchPrepare( Commit , T1_Callback, td); - } else { - int result = pCON->execute(Commit); - T1_Callback(result, pCON, (void*)td); - return; - }//if - } else { - CHECK_NULL(MyOp, "T1: getNdbOperation", td, pCON->getNdbError()); - }//if -} - -void -T1_Callback(int result, NdbConnection * pCON, void * threadData) { - ThreadData * td = (ThreadData *)threadData; - - DEBUG2("T1(%.*s): - Completing", SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number); - - if (result == -1) { - CHECK_ALLOWED_ERROR("T1: Commit", td, pCON->getNdbError()); - td->pNDB->closeTransaction(pCON); - start_T1(td->pNDB, td, stat_async); - return; - }//if - td->pNDB->closeTransaction(pCON); - complete_T1(td); -} - -/** - * Transaction 2 - T2 - * - * Read from Subscriber: - * - * Input: - * SubscriberNumber - * - * Output: - * Location - * Changed by - * Changed Timestamp - * Name - */ -void -start_T2(Ndb * pNDB, ThreadData * td, int async){ - - DEBUG3("T2(%.*s, %d): - Starting", SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.location); - - NdbConnection * pCON = 0; - - while((pCON = startTransaction(pNDB, td)) == 0){ - CHECK_ALLOWED_ERROR("T2-1: startTransaction", td, pNDB->getNdbError()); - NdbSleep_MilliSleep(10); - } - - NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOp, "T2: getNdbOperation", td, - pCON->getNdbError()); - - MyOp->readTuple(); - MyOp->equal(IND_SUBSCRIBER_NUMBER, - td->transactionData.number); - MyOp->getValue(IND_SUBSCRIBER_LOCATION, - (char *)&td->transactionData.location); - MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, - td->transactionData.changed_by); - MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, - td->transactionData.changed_time); - MyOp->getValue(IND_SUBSCRIBER_NAME, - td->transactionData.name); - if (async == 1) { - pCON->executeAsynchPrepare( Commit , T2_Callback, td); - } else { - int result = pCON->execute(Commit); - T2_Callback(result, pCON, (void*)td); - return; - }//if -} - -void -T2_Callback(int result, NdbConnection * pCON, void * threadData){ - ThreadData * td = (ThreadData *)threadData; - DEBUG3("T2(%.*s, %d): - Completing", SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.location); - - if (result == -1) { - CHECK_ALLOWED_ERROR("T2: Commit", td, pCON->getNdbError()); - td->pNDB->closeTransaction(pCON); - start_T2(td->pNDB, td, stat_async); - return; - }//if - td->pNDB->closeTransaction(pCON); - complete_T2(td); -} - -/** - * Transaction 3 - T3 - * - * Read session details - * - * Input: - * SubscriberNumber - * ServerId - * ServerBit - * - * Output: - * BranchExecuted - * SessionDetails - * ChangedBy - * ChangedTime - * Location - */ -void -start_T3(Ndb * pNDB, ThreadData * td, int async){ - - DEBUG3("T3(%.*s, %.2d): - Starting", SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id); - - NdbConnection * pCON = 0; - - while((pCON = startTransaction(pNDB, td)) == 0){ - CHECK_ALLOWED_ERROR("T3-1: startTransaction", td, pNDB->getNdbError()); - NdbSleep_MilliSleep(10); - } - - NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOp, "T3-1: getNdbOperation", td, - pCON->getNdbError()); - - MyOp->readTuple(); - MyOp->equal(IND_SUBSCRIBER_NUMBER, - td->transactionData.number); - MyOp->getValue(IND_SUBSCRIBER_LOCATION, - (char *)&td->transactionData.location); - MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, - td->transactionData.changed_by); - MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, - td->transactionData.changed_time); - MyOp->getValue(IND_SUBSCRIBER_GROUP, - (char *)&td->transactionData.group_id); - MyOp->getValue(IND_SUBSCRIBER_SESSIONS, - (char *)&td->transactionData.sessions); - stat_async = async; - if (async == 1) { - pCON->executeAsynchPrepare( NoCommit , T3_Callback_1, td); - } else { - int result = pCON->execute( NoCommit ); - T3_Callback_1(result, pCON, (void*)td); - return; - }//if -} - -void -T3_Callback_1(int result, NdbConnection * pCON, void * threadData){ - ThreadData * td = (ThreadData *)threadData; - DEBUG3("T3(%.*s, %.2d): - Callback 1", SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id); - - if (result == -1) { - CHECK_ALLOWED_ERROR("T3-1: execute", td, pCON->getNdbError()); - td->pNDB->closeTransaction(pCON); - start_T3(td->pNDB, td, stat_async); - return; - }//if - - NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE); - CHECK_NULL(MyOp, "T3-2: getNdbOperation", td, - pCON->getNdbError()); - - MyOp->readTuple(); - MyOp->equal(IND_GROUP_ID, - (char*)&td->transactionData.group_id); - MyOp->getValue(IND_GROUP_ALLOW_READ, - (char *)&td->transactionData.permission); - if (stat_async == 1) { - pCON->executeAsynchPrepare( NoCommit , T3_Callback_2, td); - } else { - int result = pCON->execute( NoCommit ); - T3_Callback_2(result, pCON, (void*)td); - return; - }//if -} - -void -T3_Callback_2(int result, NdbConnection * pCON, void * threadData){ - ThreadData * td = (ThreadData *)threadData; - - if (result == -1) { - CHECK_ALLOWED_ERROR("T3-2: execute", td, pCON->getNdbError()); - td->pNDB->closeTransaction(pCON); - start_T3(td->pNDB, td, stat_async); - return; - }//if - - Uint32 permission = td->transactionData.permission; - Uint32 sessions = td->transactionData.sessions; - Uint32 server_bit = td->transactionData.server_bit; - - if(((permission & server_bit) == server_bit) && - ((sessions & server_bit) == server_bit)){ - - memcpy(td->transactionData.suffix, - &td->transactionData.number[SFX_START], - SUBSCRIBER_NUMBER_SUFFIX_LENGTH); - DEBUG5("T3(%.*s, %.2d): - Callback 2 - reading(%.*s)", - SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id, - SUBSCRIBER_NUMBER_SUFFIX_LENGTH, - td->transactionData.suffix); - - /* Operation 3 */ - NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); - CHECK_NULL(MyOp, "T3-3: getNdbOperation", td, - pCON->getNdbError()); - - MyOp->simpleRead(); - MyOp->equal(IND_SESSION_SUBSCRIBER, - (char*)td->transactionData.number); - MyOp->equal(IND_SESSION_SERVER, - (char*)&td->transactionData.server_id); - MyOp->getValue(IND_SESSION_DATA, - (char *)td->transactionData.session_details); - - /* Operation 4 */ - MyOp = pCON->getNdbOperation(SERVER_TABLE); - CHECK_NULL(MyOp, "T3-4: getNdbOperation", td, - pCON->getNdbError()); - - MyOp->interpretedUpdateTuple(); - MyOp->equal(IND_SERVER_ID, - (char*)&td->transactionData.server_id); - MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX, - (char*)td->transactionData.suffix); - MyOp->incValue(IND_SERVER_READS, (uint32)1); - td->transactionData.branchExecuted = 1; - } else { - DEBUG3("T3(%.*s, %.2d): - Callback 2 - no read", - SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id); - td->transactionData.branchExecuted = 0; - } - if (stat_async == 1) { - pCON->executeAsynchPrepare( Commit , T3_Callback_3, td); - } else { - int result = pCON->execute( Commit ); - T3_Callback_3(result, pCON, (void*)td); - return; - }//if -} - -void -T3_Callback_3(int result, NdbConnection * pCON, void * threadData){ - ThreadData * td = (ThreadData *)threadData; - DEBUG3("T3(%.*s, %.2d): - Completing", SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id); - - if (result == -1) { - CHECK_ALLOWED_ERROR("T3-3: Commit", td, pCON->getNdbError()); - td->pNDB->closeTransaction(pCON); - start_T3(td->pNDB, td, stat_async); - return; - }//if - td->pNDB->closeTransaction(pCON); - complete_T3(td); -} - -/** - * Transaction 4 - T4 - * - * Create session - * - * Input: - * SubscriberNumber - * ServerId - * ServerBit - * SessionDetails, - * DoRollback - * Output: - * ChangedBy - * ChangedTime - * Location - * BranchExecuted - */ -void -start_T4(Ndb * pNDB, ThreadData * td, int async){ - - DEBUG3("T4(%.*s, %.2d): - Starting", SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id); - - NdbConnection * pCON = 0; - while((pCON = startTransaction(pNDB, td)) == 0){ - CHECK_ALLOWED_ERROR("T4-1: startTransaction", td, pNDB->getNdbError()); - NdbSleep_MilliSleep(10); - } - - NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOp, "T4-1: getNdbOperation", td, - pCON->getNdbError()); - - MyOp->interpretedUpdateTuple(); - MyOp->equal(IND_SUBSCRIBER_NUMBER, - td->transactionData.number); - MyOp->getValue(IND_SUBSCRIBER_LOCATION, - (char *)&td->transactionData.location); - MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, - td->transactionData.changed_by); - MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, - td->transactionData.changed_time); - MyOp->getValue(IND_SUBSCRIBER_GROUP, - (char *)&td->transactionData.group_id); - MyOp->getValue(IND_SUBSCRIBER_SESSIONS, - (char *)&td->transactionData.sessions); - MyOp->incValue(IND_SUBSCRIBER_SESSIONS, - (uint32)td->transactionData.server_bit); - stat_async = async; - if (async == 1) { - pCON->executeAsynchPrepare( NoCommit , T4_Callback_1, td); - } else { - int result = pCON->execute( NoCommit ); - T4_Callback_1(result, pCON, (void*)td); - return; - }//if -} - -void -T4_Callback_1(int result, NdbConnection * pCON, void * threadData){ - ThreadData * td = (ThreadData *)threadData; - if (result == -1) { - CHECK_ALLOWED_ERROR("T4-1: execute", td, pCON->getNdbError()); - td->pNDB->closeTransaction(pCON); - start_T4(td->pNDB, td, stat_async); - return; - }//if - - DEBUG3("T4(%.*s, %.2d): - Callback 1", - SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id); - - - NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE); - CHECK_NULL(MyOp, "T4-2: getNdbOperation", td, - pCON->getNdbError()); - - MyOp->readTuple(); - MyOp->equal(IND_GROUP_ID, - (char*)&td->transactionData.group_id); - MyOp->getValue(IND_GROUP_ALLOW_INSERT, - (char *)&td->transactionData.permission); - if (stat_async == 1) { - pCON->executeAsynchPrepare( NoCommit , T4_Callback_2, td); - } else { - int result = pCON->execute( NoCommit ); - T4_Callback_2(result, pCON, (void*)td); - return; - }//if -} - -void -T4_Callback_2(int result, NdbConnection * pCON, void * threadData){ - ThreadData * td = (ThreadData *)threadData; - if (result == -1) { - CHECK_ALLOWED_ERROR("T4-2: execute", td, pCON->getNdbError()); - td->pNDB->closeTransaction(pCON); - start_T4(td->pNDB, td, stat_async); - return; - }//if - - Uint32 permission = td->transactionData.permission; - Uint32 sessions = td->transactionData.sessions; - Uint32 server_bit = td->transactionData.server_bit; - - if(((permission & server_bit) == server_bit) && - ((sessions & server_bit) == 0)){ - - memcpy(td->transactionData.suffix, - &td->transactionData.number[SFX_START], - SUBSCRIBER_NUMBER_SUFFIX_LENGTH); - - DEBUG5("T4(%.*s, %.2d): - Callback 2 - inserting(%.*s)", - SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id, - SUBSCRIBER_NUMBER_SUFFIX_LENGTH, - td->transactionData.suffix); - - /* Operation 3 */ - - NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); - CHECK_NULL(MyOp, "T4-3: getNdbOperation", td, - pCON->getNdbError()); - - MyOp->insertTuple(); - MyOp->equal(IND_SESSION_SUBSCRIBER, - (char*)td->transactionData.number); - MyOp->equal(IND_SESSION_SERVER, - (char*)&td->transactionData.server_id); - MyOp->setValue(SESSION_DATA, - (char *)td->transactionData.session_details); - /* Operation 4 */ - - /* Operation 5 */ - MyOp = pCON->getNdbOperation(SERVER_TABLE); - CHECK_NULL(MyOp, "T4-5: getNdbOperation", td, - pCON->getNdbError()); - - MyOp->interpretedUpdateTuple(); - MyOp->equal(IND_SERVER_ID, - (char*)&td->transactionData.server_id); - MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX, - (char*)td->transactionData.suffix); - MyOp->incValue(IND_SERVER_INSERTS, (uint32)1); - td->transactionData.branchExecuted = 1; - } else { - td->transactionData.branchExecuted = 0; - DEBUG5("T4(%.*s, %.2d): - Callback 2 - %s %s", - SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id, - ((permission & server_bit) ? - "permission - " : "no permission - "), - ((sessions & server_bit) ? - "in session - " : "no in session - ")); - } - - if(!td->transactionData.do_rollback && td->transactionData.branchExecuted){ - if (stat_async == 1) { - pCON->executeAsynchPrepare( Commit , T4_Callback_3, td); - } else { - int result = pCON->execute( Commit ); - T4_Callback_3(result, pCON, (void*)td); - return; - }//if - } else { - if (stat_async == 1) { - pCON->executeAsynchPrepare( Rollback , T4_Callback_3, td); - } else { - int result = pCON->execute( Rollback ); - T4_Callback_3(result, pCON, (void*)td); - return; - }//if - } -} - -void -T4_Callback_3(int result, NdbConnection * pCON, void * threadData){ - ThreadData * td = (ThreadData *)threadData; - if (result == -1) { - CHECK_ALLOWED_ERROR("T4-3: Commit", td, pCON->getNdbError()); - td->pNDB->closeTransaction(pCON); - start_T4(td->pNDB, td, stat_async); - return; - }//if - - DEBUG3("T4(%.*s, %.2d): - Completing", - SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id); - - td->pNDB->closeTransaction(pCON); - complete_T4(td); -} - -/** - * Transaction 5 - T5 - * - * Delete session - * - * Input: - * SubscriberNumber - * ServerId - * ServerBit - * DoRollback - * Output: - * ChangedBy - * ChangedTime - * Location - * BranchExecuted - */ -void -start_T5(Ndb * pNDB, ThreadData * td, int async){ - - DEBUG3("T5(%.*s, %.2d): - Starting", SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id); - - NdbConnection * pCON = 0; - while((pCON = startTransaction(pNDB, td)) == 0){ - CHECK_ALLOWED_ERROR("T5-1: startTransaction", td, pNDB->getNdbError()); - NdbSleep_MilliSleep(10); - } - - NdbOperation * MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOp, "T5-1: getNdbOperation", td, - pCON->getNdbError()); - - MyOp->interpretedUpdateTuple(); - MyOp->equal(IND_SUBSCRIBER_NUMBER, - td->transactionData.number); - MyOp->getValue(IND_SUBSCRIBER_LOCATION, - (char *)&td->transactionData.location); - MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, - td->transactionData.changed_by); - MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, - td->transactionData.changed_time); - MyOp->getValue(IND_SUBSCRIBER_GROUP, - (char *)&td->transactionData.group_id); - MyOp->getValue(IND_SUBSCRIBER_SESSIONS, - (char *)&td->transactionData.sessions); - MyOp->subValue(IND_SUBSCRIBER_SESSIONS, - (uint32)td->transactionData.server_bit); - stat_async = async; - if (async == 1) { - pCON->executeAsynchPrepare( NoCommit , T5_Callback_1, td); - } else { - int result = pCON->execute( NoCommit ); - T5_Callback_1(result, pCON, (void*)td); - return; - }//if -} - -void -T5_Callback_1(int result, NdbConnection * pCON, void * threadData){ - ThreadData * td = (ThreadData *)threadData; - if (result == -1) { - CHECK_ALLOWED_ERROR("T5-1: execute", td, pCON->getNdbError()); - td->pNDB->closeTransaction(pCON); - start_T5(td->pNDB, td, stat_async); - return; - }//if - - DEBUG3("T5(%.*s, %.2d): - Callback 1", - SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id); - - NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE); - CHECK_NULL(MyOp, "T5-2: getNdbOperation", td, - pCON->getNdbError()); - - MyOp->readTuple(); - MyOp->equal(IND_GROUP_ID, - (char*)&td->transactionData.group_id); - MyOp->getValue(IND_GROUP_ALLOW_DELETE, - (char *)&td->transactionData.permission); - if (stat_async == 1) { - pCON->executeAsynchPrepare( NoCommit , T5_Callback_2, td); - } else { - int result = pCON->execute( NoCommit ); - T5_Callback_2(result, pCON, (void*)td); - return; - }//if -} - -void -T5_Callback_2(int result, NdbConnection * pCON, void * threadData){ - ThreadData * td = (ThreadData *)threadData; - if (result == -1) { - CHECK_ALLOWED_ERROR("T5-2: execute", td, pCON->getNdbError()); - td->pNDB->closeTransaction(pCON); - start_T5(td->pNDB, td, stat_async); - return; - }//if - - Uint32 permission = td->transactionData.permission; - Uint32 sessions = td->transactionData.sessions; - Uint32 server_bit = td->transactionData.server_bit; - - if(((permission & server_bit) == server_bit) && - ((sessions & server_bit) == server_bit)){ - - memcpy(td->transactionData.suffix, - &td->transactionData.number[SFX_START], - SUBSCRIBER_NUMBER_SUFFIX_LENGTH); - - DEBUG5("T5(%.*s, %.2d): - Callback 2 - deleting(%.*s)", - SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id, - SUBSCRIBER_NUMBER_SUFFIX_LENGTH, - td->transactionData.suffix); - - /* Operation 3 */ - NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); - CHECK_NULL(MyOp, "T5-3: getNdbOperation", td, - pCON->getNdbError()); - - MyOp->deleteTuple(); - MyOp->equal(IND_SESSION_SUBSCRIBER, - (char*)td->transactionData.number); - MyOp->equal(IND_SESSION_SERVER, - (char*)&td->transactionData.server_id); - /* Operation 4 */ - - /* Operation 5 */ - MyOp = pCON->getNdbOperation(SERVER_TABLE); - CHECK_NULL(MyOp, "T5-5: getNdbOperation", td, - pCON->getNdbError()); - - MyOp->interpretedUpdateTuple(); - MyOp->equal(IND_SERVER_ID, - (char*)&td->transactionData.server_id); - MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX, - (char*)td->transactionData.suffix); - MyOp->incValue(IND_SERVER_DELETES, (uint32)1); - td->transactionData.branchExecuted = 1; - } else { - td->transactionData.branchExecuted = 0; - - DEBUG5("T5(%.*s, %.2d): - Callback 2 - no delete - %s %s", - SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id, - ((permission & server_bit) ? - "permission - " : "no permission - "), - ((sessions & server_bit) ? - "in session - " : "no in session - ")); - } - - if(!td->transactionData.do_rollback && td->transactionData.branchExecuted){ - if (stat_async == 1) { - pCON->executeAsynchPrepare( Commit , T5_Callback_3, td); - } else { - int result = pCON->execute( Commit ); - T5_Callback_3(result, pCON, (void*)td); - return; - }//if - } else { - if (stat_async == 1) { - pCON->executeAsynchPrepare( Rollback , T5_Callback_3, td); - } else { - int result = pCON->execute( Rollback ); - T5_Callback_3(result, pCON, (void*)td); - return; - }//if - } -} - -void -T5_Callback_3(int result, NdbConnection * pCON, void * threadData){ - ThreadData * td = (ThreadData *)threadData; - if (result == -1) { - CHECK_ALLOWED_ERROR("T5-3: Commit", td, pCON->getNdbError()); - td->pNDB->closeTransaction(pCON); - start_T5(td->pNDB, td, stat_async); - return; - }//if - - DEBUG3("T5(%.*s, %.2d): - Completing", - SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number, - td->transactionData.server_id); - - td->pNDB->closeTransaction(pCON); - complete_T5(td); -} diff --git a/ndb/test/ndbapi/lmc-bench/async-src/user/ndb_error.hpp b/ndb/test/ndbapi/lmc-bench/async-src/user/ndb_error.hpp deleted file mode 100644 index 9e6c5e55e73..00000000000 --- a/ndb/test/ndbapi/lmc-bench/async-src/user/ndb_error.hpp +++ /dev/null @@ -1,63 +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 */ - -#ifndef NDB_ERROR_H -#define NDB_ERROR_H - -#include -#include -#include "userInterface.h" -#include - -inline -void -CHECK_ALLOWED_ERROR(const char * str, - const ThreadData * td, - const struct NdbError & error){ - - char buf[100]; - snprintf(buf, sizeof(buf), "subscriber = %.*s ", - SUBSCRIBER_NUMBER_LENGTH, - td->transactionData.number); - ndbout << str << " " << error << endl - << buf; - showTime(); - - switch(error.classification) { - case NdbError::TimeoutExpired: - case NdbError::OverloadError: - case NdbError::TemporaryResourceError: - case NdbError::NodeRecoveryError: - break; - default: - if(error.status != NdbError::TemporaryError) - exit(-1); - } -} - -inline -void -CHECK_NULL(void * null, - const char * str, - const ThreadData * td, - const struct NdbError & err){ - if(null == 0){ - CHECK_ALLOWED_ERROR(str, td, err); - exit(-1); - } -} - -#endif diff --git a/ndb/test/ndbapi/lmc-bench/async-src/user/userInterface.cpp b/ndb/test/ndbapi/lmc-bench/async-src/user/userInterface.cpp deleted file mode 100644 index fdbc229cc98..00000000000 --- a/ndb/test/ndbapi/lmc-bench/async-src/user/userInterface.cpp +++ /dev/null @@ -1,117 +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 */ - -/*************************************************************** -* I N C L U D E D F I L E S * -***************************************************************/ - -#include -#include - -#include "ndb_schema.hpp" -#include "ndb_error.hpp" -#include "userInterface.h" -#include -#include -#include -#include -#include - -/*************************************************************** -* L O C A L C O N S T A N T S * -***************************************************************/ - -/*************************************************************** -* L O C A L D A T A S T R U C T U R E S * -***************************************************************/ - -/*************************************************************** -* L O C A L F U N C T I O N S * -***************************************************************/ - -#ifndef NDB_WIN32 -#include -#endif - - -static NdbMutex* startupMutex = NdbMutex_Create(); - -Ndb* -asyncDbConnect(int parallellism){ - NdbMutex_Lock(startupMutex); - Ndb * pNDB = new Ndb(""); - - pNDB->init(parallellism + 1); - - while(pNDB->waitUntilReady() != 0){ - } - - NdbMutex_Unlock(startupMutex); - - return pNDB; -} - -void -asyncDbDisconnect(Ndb* pNDB) -{ - delete pNDB; -} - -double -userGetTime(void) -{ - static bool initialized = false; - static NDB_TICKS initSecs = 0; - static Uint32 initMicros = 0; - double timeValue = 0; - - if ( !initialized ) { - initialized = true; - NdbTick_CurrentMicrosecond(&initSecs, &initMicros); - timeValue = 0.0; - } else { - NDB_TICKS secs = 0; - Uint32 micros = 0; - - NdbTick_CurrentMicrosecond(&secs, µs); - double s = (double)secs - (double)initSecs; - double us = (double)micros - (double)initMicros; - - timeValue = s + (us / 1000000.0); - } - return timeValue; -} - -void showTime() -{ - char buf[128]; - struct tm* tm_now; - time_t now; - now = ::time((time_t*)NULL); - tm_now = ::gmtime(&now); - - ::snprintf(buf, 128, - "%d-%.2d-%.2d %.2d:%.2d:%.2d", - tm_now->tm_year + 1900, - tm_now->tm_mon, - tm_now->tm_mday, - tm_now->tm_hour, - tm_now->tm_min, - tm_now->tm_sec); - - ndbout_c("Time: %s", buf); -} - diff --git a/ndb/test/ndbapi/lmc-bench/bin/.empty b/ndb/test/ndbapi/lmc-bench/bin/.empty deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/ndb/test/ndbapi/lmc-bench/include/ndb_schema.hpp b/ndb/test/ndbapi/lmc-bench/include/ndb_schema.hpp deleted file mode 100644 index af08bc2eecd..00000000000 --- a/ndb/test/ndbapi/lmc-bench/include/ndb_schema.hpp +++ /dev/null @@ -1,78 +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 */ - -#ifndef NDB_SCHEMA_H -#define NDB_SCHEMA_H - -#include "testDefinitions.h" - -#define SUBSCRIBER_TABLE "SUBSCRIBER" -#define SUBSCRIBER_NUMBER "NUMBER" -#define SUBSCRIBER_LOCATION "LOCATION" -#define SUBSCRIBER_NAME "NAME" -#define SUBSCRIBER_GROUP "GROUP_ID" -#define SUBSCRIBER_SESSIONS "SESSIONS" -#define SUBSCRIBER_CHANGED_BY "CHANGED_BY" -#define SUBSCRIBER_CHANGED_TIME "CHANGED_TIME" - -#define SERVER_TABLE "SERVER" -#define SERVER_ID "SERVER_ID" -#define SERVER_SUBSCRIBER_SUFFIX "SUFFIX" -#define SERVER_NAME "NAME" -#define SERVER_READS "NO_OF_READ" -#define SERVER_INSERTS "NO_OF_INSERT" -#define SERVER_DELETES "NO_OF_DELETE" - -#define GROUP_TABLE "GROUP" -#define GROUP_ID "GROUP_ID" -#define GROUP_NAME "GROUP_NAME" -#define GROUP_ALLOW_READ "ALLOW_READ" -#define GROUP_ALLOW_INSERT "ALLOW_INSERT" -#define GROUP_ALLOW_DELETE "ALLOW_DELETE" - -#define SESSION_TABLE "SESSION" -#define SESSION_SERVER "SERVER_ID" -#define SESSION_SUBSCRIBER "NUMBER" -#define SESSION_DATA "DATA" - -/** Numbers */ - -#define IND_SUBSCRIBER_NUMBER (unsigned)0 -#define IND_SUBSCRIBER_NAME (unsigned)1 -#define IND_SUBSCRIBER_GROUP (unsigned)2 -#define IND_SUBSCRIBER_LOCATION (unsigned)3 -#define IND_SUBSCRIBER_SESSIONS (unsigned)4 -#define IND_SUBSCRIBER_CHANGED_BY (unsigned)5 -#define IND_SUBSCRIBER_CHANGED_TIME (unsigned)6 - -#define IND_SERVER_SUBSCRIBER_SUFFIX (unsigned)0 -#define IND_SERVER_ID (unsigned)1 -#define IND_SERVER_NAME (unsigned)2 -#define IND_SERVER_READS (unsigned)3 -#define IND_SERVER_INSERTS (unsigned)4 -#define IND_SERVER_DELETES (unsigned)5 - -#define IND_GROUP_ID (unsigned)0 -#define IND_GROUP_NAME (unsigned)1 -#define IND_GROUP_ALLOW_READ (unsigned)2 -#define IND_GROUP_ALLOW_INSERT (unsigned)3 -#define IND_GROUP_ALLOW_DELETE (unsigned)4 - -#define IND_SESSION_SUBSCRIBER (unsigned)0 -#define IND_SESSION_SERVER (unsigned)1 -#define IND_SESSION_DATA (unsigned)2 - -#endif diff --git a/ndb/test/ndbapi/lmc-bench/include/testDefinitions.h b/ndb/test/ndbapi/lmc-bench/include/testDefinitions.h deleted file mode 100644 index 2f4aeb30975..00000000000 --- a/ndb/test/ndbapi/lmc-bench/include/testDefinitions.h +++ /dev/null @@ -1,90 +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 */ - -#ifndef TESTDEFINITIONS_H -#define TESTDEFINITIONS_H - -/***************************************************************/ -/* I N C L U D E D F I L E S */ -/***************************************************************/ - -#include - -/***************************************************************/ -/* C O N S T A N T S */ -/***************************************************************/ - -#define OP_PER_TRANS 200 -#define NO_OF_SUBSCRIBERS 500000 -#define NO_OF_GROUPS 100 -#define NO_OF_SERVERS 20 - -#define SUBSCRIBER_NUMBER_LENGTH 12 -#define SUBSCRIBER_NUMBER_SUFFIX_LENGTH 2 - -#define SUBSCRIBER_NAME_LENGTH 32 -#define CHANGED_BY_LENGTH 32 -#define CHANGED_TIME_LENGTH 32 -#define SESSION_DETAILS_LENGTH 2000 -#define SERVER_NAME_LENGTH 32 -#define GROUP_NAME_LENGTH 32 - -/*************************************************************** -* D A T A S T R U C T U R E S * -***************************************************************/ - -#define PADDING 4 - -typedef char SubscriberNumber[SUBSCRIBER_NUMBER_LENGTH]; -typedef char SubscriberSuffix[SUBSCRIBER_NUMBER_SUFFIX_LENGTH + 2]; -typedef char SubscriberName[SUBSCRIBER_NAME_LENGTH]; -typedef char ServerName[SERVER_NAME_LENGTH]; -typedef char GroupName[GROUP_NAME_LENGTH]; -typedef char ChangedBy[CHANGED_BY_LENGTH]; -typedef char ChangedTime[CHANGED_TIME_LENGTH]; -typedef char SessionDetails[SESSION_DETAILS_LENGTH]; -typedef Uint32 ServerId; -typedef Uint32 ServerBit; -typedef Uint32 GroupId; -typedef Uint32 Location; -typedef Uint32 Permission; - -typedef Uint32 Counter; -typedef Uint32 ActiveSessions; -typedef unsigned int BranchExecuted; -typedef unsigned int DoRollback; - -/*************************************************************** -* P U B L I C F U N C T I O N S * -***************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - - -#ifdef __cplusplus -} -#endif - -/*************************************************************** -* E X T E R N A L D A T A * -***************************************************************/ - - - -#endif /* TESTDEFINITIONS_H */ - diff --git a/ndb/test/ndbapi/lmc-bench/lib/.empty b/ndb/test/ndbapi/lmc-bench/lib/.empty deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/ndb/test/ndbapi/lmc-bench/script/Makefile b/ndb/test/ndbapi/lmc-bench/script/Makefile deleted file mode 100644 index 240b5957573..00000000000 --- a/ndb/test/ndbapi/lmc-bench/script/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -include .defs.mk - -SOURCES.sh := async-lmc-bench.sh async-lmc-bench-l.sh async-lmc-bench-p10.sh async-lmc-bench-l-p10.sh - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/lmc-bench/script/async-lmc-bench-l-p10.sh b/ndb/test/ndbapi/lmc-bench/script/async-lmc-bench-l-p10.sh deleted file mode 100755 index 1ce3969f9fb..00000000000 --- a/ndb/test/ndbapi/lmc-bench/script/async-lmc-bench-l-p10.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -DbCreate -l -ret=$? -if [ $ret -ne 0 ] -then - echo "DbCreate failed" - exit $ret -fi - -DbAsyncGenerator -time 300 -p 10 $* -ret=$? -exit $ret - diff --git a/ndb/test/ndbapi/lmc-bench/script/async-lmc-bench-l.sh b/ndb/test/ndbapi/lmc-bench/script/async-lmc-bench-l.sh deleted file mode 100755 index a5de71395c4..00000000000 --- a/ndb/test/ndbapi/lmc-bench/script/async-lmc-bench-l.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -DbCreate -l -ret=$? -if [ $ret -ne 0 ] -then - echo "DbCreate failed" - exit $ret -fi - -DbAsyncGenerator -time 300 $* -ret=$? -exit $ret - diff --git a/ndb/test/ndbapi/lmc-bench/script/async-lmc-bench-p10.sh b/ndb/test/ndbapi/lmc-bench/script/async-lmc-bench-p10.sh deleted file mode 100755 index 92c853cdd86..00000000000 --- a/ndb/test/ndbapi/lmc-bench/script/async-lmc-bench-p10.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -DbCreate -ret=$? -if [ $ret -ne 0 ] -then - echo "DbCreate failed" - exit $ret -fi - -DbAsyncGenerator -time 300 -p 10 $* -ret=$? -exit $ret - diff --git a/ndb/test/ndbapi/lmc-bench/script/async-lmc-bench.sh b/ndb/test/ndbapi/lmc-bench/script/async-lmc-bench.sh deleted file mode 100755 index da8e9d9bf42..00000000000 --- a/ndb/test/ndbapi/lmc-bench/script/async-lmc-bench.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -DbCreate -ret=$? -if [ $ret -ne 0 ] -then - echo "DbCreate failed" - exit $ret -fi - -DbAsyncGenerator -time 300 $* -ret=$? -exit $ret - diff --git a/ndb/test/ndbapi/lmc-bench/src/Makefile b/ndb/test/ndbapi/lmc-bench/src/Makefile deleted file mode 100644 index ae7fac9c49b..00000000000 --- a/ndb/test/ndbapi/lmc-bench/src/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -include .defs.mk - -DIRS = \ - user \ - populator \ - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/test/ndbapi/lmc-bench/src/README b/ndb/test/ndbapi/lmc-bench/src/README deleted file mode 100644 index e81c8ba0051..00000000000 --- a/ndb/test/ndbapi/lmc-bench/src/README +++ /dev/null @@ -1,8 +0,0 @@ - -Note that you have to use gnumake to build - -On ndbs05: -use 'gmake' instead of 'make' - -On hfXXX: -do 'module add make' diff --git a/ndb/test/ndbapi/lmc-bench/src/generator/Makefile b/ndb/test/ndbapi/lmc-bench/src/generator/Makefile deleted file mode 100644 index 143d9ba655e..00000000000 --- a/ndb/test/ndbapi/lmc-bench/src/generator/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -SOURCES = mainGenerator.c dbGenerator.c - -CCFLAGS_LOC := -I../include -I../../include - -OBJECTS = \ - mainGenerator.o\ - dbGenerator.o - -BIN_TARGET := DbGenerator -BIN_TARGET_ARCHIVES := lmc_User - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/test/ndbapi/lmc-bench/src/generator/dbGenerator.c b/ndb/test/ndbapi/lmc-bench/src/generator/dbGenerator.c deleted file mode 100644 index 7484c7647f5..00000000000 --- a/ndb/test/ndbapi/lmc-bench/src/generator/dbGenerator.c +++ /dev/null @@ -1,543 +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 */ - -/*************************************************************** -* I N C L U D E D F I L E S * -***************************************************************/ - -#include -#include "dbGenerator.h" - -/*************************************************************** -* L O C A L C O N S T A N T S * -***************************************************************/ - -/*************************************************************** -* L O C A L D A T A S T R U C T U R E S * -***************************************************************/ - -/*************************************************************** -* L O C A L F U N C T I O N S * -***************************************************************/ - -static void getRandomSubscriberNumber(SubscriberNumber number); -static void getRandomServerId(ServerId *serverId); -static void getRandomChangedBy(ChangedBy changedBy); -static void getRandomChangedTime(ChangedTime changedTime); - -static void clearTransaction(TransactionDefinition *trans); -static void initGeneratorStatistics(GeneratorStatistics *gen); - -static void doOneTransaction(UserHandle *uh, GeneratorStatistics *gen); -static void doTransaction_T1(UserHandle *uh, GeneratorStatistics *gen); -static void doTransaction_T2(UserHandle *uh, GeneratorStatistics *gen); -static void doTransaction_T3(UserHandle *uh, GeneratorStatistics *gen); -static void doTransaction_T4(UserHandle *uh, GeneratorStatistics *gen); -static void doTransaction_T5(UserHandle *uh, GeneratorStatistics *gen); - -/*************************************************************** -* L O C A L D A T A * -***************************************************************/ - -static SequenceValues transactionDefinition[] = { - {25, 1}, - {25, 2}, - {20, 3}, - {15, 4}, - {15, 5}, - {0, 0} -}; - -static SequenceValues rollbackDefinition[] = { - {98, 0}, - {2 , 1}, - {0, 0} -}; - -static int maxsize = 0; - -/*************************************************************** -* P U B L I C D A T A * -***************************************************************/ - -/*************************************************************** -**************************************************************** -* L O C A L F U N C T I O N S C O D E S E C T I O N * -**************************************************************** -***************************************************************/ - -static void getRandomSubscriberNumber(SubscriberNumber number) -{ - uint32 tmp; - char sbuf[SUBSCRIBER_NUMBER_LENGTH + 1]; - tmp = myRandom48(NO_OF_SUBSCRIBERS); - sprintf(sbuf, "%.*d", SUBSCRIBER_NUMBER_LENGTH, tmp); - memcpy(number, sbuf, SUBSCRIBER_NUMBER_LENGTH); -} - -static void getRandomServerId(ServerId *serverId) -{ - *serverId = myRandom48(NO_OF_SERVERS); -} - -static void getRandomChangedBy(ChangedBy changedBy) -{ - memset(changedBy, myRandom48(26)+'A', CHANGED_BY_LENGTH); - changedBy[CHANGED_BY_LENGTH] = 0; -} - -static void getRandomChangedTime(ChangedTime changedTime) -{ - memset(changedTime, myRandom48(26)+'A', CHANGED_TIME_LENGTH); - changedTime[CHANGED_TIME_LENGTH] = 0; -} - -static void clearTransaction(TransactionDefinition *trans) -{ - trans->benchTime = 0.0; - trans->count = 0; - trans->branchExecuted = 0; - trans->rollbackExecuted = 0; -} - -static int listFull(SessionList *list) -{ - return(list->numberInList == SESSION_LIST_LENGTH); -} - -static int listEmpty(SessionList *list) -{ - return(list->numberInList == 0); -} - -static void insertSession(SessionList *list, - SubscriberNumber number, - ServerId serverId) -{ - SessionElement *e; - if( listFull(list) ) return; - - e = &list->list[list->writeIndex]; - - strcpy(e->subscriberNumber, number); - e->serverId = serverId; - - list->writeIndex = (list->writeIndex + 1) % SESSION_LIST_LENGTH; - list->numberInList++; - -if( list->numberInList > maxsize ) -maxsize = list->numberInList; -} - -static SessionElement *getNextSession(SessionList *list) -{ - if( listEmpty(list) ) return(0); - - return(&list->list[list->readIndex]); -} - -static void deleteSession(SessionList *list) -{ - if( listEmpty(list) ) return; - - list->readIndex = (list->readIndex + 1) % SESSION_LIST_LENGTH; - list->numberInList--; -} - -static void initGeneratorStatistics(GeneratorStatistics *gen) -{ - int i; - - if( initSequence(&gen->transactionSequence, - transactionDefinition) != 0 ) { - printf("could not set the transaction types\n"); - exit(0); - } - - if( initSequence(&gen->rollbackSequenceT4, - rollbackDefinition) != 0 ) { - printf("could not set the rollback sequence\n"); - exit(0); - } - - if( initSequence(&gen->rollbackSequenceT5, - rollbackDefinition) != 0 ) { - printf("could not set the rollback sequence\n"); - exit(0); - } - - for(i = 0; i < NUM_TRANSACTION_TYPES; i++ ) - clearTransaction(&gen->transactions[i]); - - gen->totalTransactions = 0; - - gen->activeSessions.numberInList = 0; - gen->activeSessions.readIndex = 0; - gen->activeSessions.writeIndex = 0; -} - - -static void doOneTransaction(UserHandle *uh, GeneratorStatistics *gen) -{ - unsigned int transactionType; - - transactionType = getNextRandom(&gen->transactionSequence); - - switch(transactionType) { - case 1: - doTransaction_T1(uh, gen); - break; - case 2: - doTransaction_T2(uh, gen); - break; - case 3: - doTransaction_T3(uh, gen); - break; - case 4: - doTransaction_T4(uh, gen); - break; - case 5: - doTransaction_T5(uh, gen); - break; - default: - printf("Unknown transaction type: %d\n", transactionType); - } - - gen->totalTransactions++; -} - -static void doTransaction_T1(UserHandle *uh, GeneratorStatistics *gen) -{ - SubscriberNumber number; - Location new_location; - ChangedBy changed_by; - ChangedTime changed_time; - - double start_time; - double end_time; - double transaction_time; - - unsigned int tid = 0; - - /*----------------*/ - /* Init arguments */ - /*----------------*/ - getRandomSubscriberNumber(number); - getRandomChangedBy(changed_by); - getRandomChangedTime(changed_time); - new_location = changed_by[0]; - - /*-----------------*/ - /* Run transaction */ - /*-----------------*/ - start_time = userGetTimeSync(); - userTransaction_T1(uh, - number, - new_location, - changed_by, - changed_time); - end_time = userGetTimeSync(); - - /*-------------------*/ - /* Update Statistics */ - /*-------------------*/ - transaction_time = end_time - start_time; - gen->transactions[tid].benchTime += transaction_time; - gen->transactions[tid].count++; -} - -static void doTransaction_T2(UserHandle *uh, GeneratorStatistics *gen) -{ - SubscriberNumber number; - Location new_location; - ChangedBy changed_by; - ChangedTime changed_time; - SubscriberName subscriberName; - - double start_time; - double end_time; - double transaction_time; - - unsigned int tid = 1; - - /*----------------*/ - /* Init arguments */ - /*----------------*/ - getRandomSubscriberNumber(number); - - /*-----------------*/ - /* Run transaction */ - /*-----------------*/ - start_time = userGetTimeSync(); - userTransaction_T2(uh, - number, - &new_location, - changed_by, - changed_time, - subscriberName); - end_time = userGetTimeSync(); - - /*-------------------*/ - /* Update Statistics */ - /*-------------------*/ - transaction_time = end_time - start_time; - gen->transactions[tid].benchTime += transaction_time; - gen->transactions[tid].count++; -} - -static void doTransaction_T3(UserHandle *uh, GeneratorStatistics *gen) -{ - SubscriberNumber number; - ServerId serverId; - ServerBit serverBit; - SessionDetails sessionDetails; - unsigned int branchExecuted; - SessionElement *se; - - double start_time; - double end_time; - double transaction_time; - - unsigned int tid = 2; - - /*----------------*/ - /* Init arguments */ - /*----------------*/ - se = getNextSession(&gen->activeSessions); - if( se ) { - strcpy(number, se->subscriberNumber); - serverId = se->serverId; - } - else { - getRandomSubscriberNumber(number); - getRandomServerId(&serverId); - } - - serverBit = 1 << serverId; - - /*-----------------*/ - /* Run transaction */ - /*-----------------*/ - start_time = userGetTimeSync(); - userTransaction_T3(uh, - number, - serverId, - serverBit, - sessionDetails, - &branchExecuted); - end_time = userGetTimeSync(); - - /*-------------------*/ - /* Update Statistics */ - /*-------------------*/ - transaction_time = end_time - start_time; - gen->transactions[tid].benchTime += transaction_time; - gen->transactions[tid].count++; - - if(branchExecuted) - gen->transactions[tid].branchExecuted++; -} - -static void doTransaction_T4(UserHandle *uh, GeneratorStatistics *gen) -{ - SubscriberNumber number; - ServerId serverId; - ServerBit serverBit; - SessionDetails sessionDetails; - unsigned int branchExecuted; - unsigned int rollback; - - double start_time; - double end_time; - double transaction_time; - - unsigned int tid = 3; - - /*----------------*/ - /* Init arguments */ - /*----------------*/ - getRandomSubscriberNumber(number); - getRandomServerId(&serverId); - - serverBit = 1 << serverId; - rollback = getNextRandom(&gen->rollbackSequenceT4); - - memset(sessionDetails, myRandom48(26)+'A', SESSION_DETAILS_LENGTH); - sessionDetails[SESSION_DETAILS_LENGTH] = 0; - - /*-----------------*/ - /* Run transaction */ - /*-----------------*/ - start_time = userGetTimeSync(); - userTransaction_T4(uh, - number, - serverId, - serverBit, - sessionDetails, - rollback, - &branchExecuted); - end_time = userGetTimeSync(); - - /*-------------------*/ - /* Update Statistics */ - /*-------------------*/ - transaction_time = end_time - start_time; - gen->transactions[tid].benchTime += transaction_time; - gen->transactions[tid].count++; - - if(branchExecuted) - gen->transactions[tid].branchExecuted++; - if(rollback) - gen->transactions[tid].rollbackExecuted++; - - if( branchExecuted && !rollback ) { - insertSession(&gen->activeSessions, number, serverId); - } -} - -static void doTransaction_T5(UserHandle *uh, GeneratorStatistics *gen) -{ - SubscriberNumber number; - ServerId serverId; - ServerBit serverBit; - unsigned int branchExecuted; - unsigned int rollback; - SessionElement *se; - - double start_time; - double end_time; - double transaction_time; - - unsigned int tid = 4; - - /*----------------*/ - /* Init arguments */ - /*----------------*/ - se = getNextSession(&gen->activeSessions); - if( se ) { - strcpy(number, se->subscriberNumber); - serverId = se->serverId; - } - else { - getRandomSubscriberNumber(number); - getRandomServerId(&serverId); - } - - serverBit = 1 << serverId; - rollback = getNextRandom(&gen->rollbackSequenceT5); - - /*-----------------*/ - /* Run transaction */ - /*-----------------*/ - start_time = userGetTimeSync(); - userTransaction_T5(uh, - number, - serverId, - serverBit, - rollback, - &branchExecuted); - end_time = userGetTimeSync(); - - /*-------------------*/ - /* Update Statistics */ - /*-------------------*/ - transaction_time = end_time - start_time; - gen->transactions[tid].benchTime += transaction_time; - gen->transactions[tid].count++; - - if(branchExecuted) - gen->transactions[tid].branchExecuted++; - if(rollback) - gen->transactions[tid].rollbackExecuted++; - - if( se && !rollback) { - deleteSession(&gen->activeSessions); - } -} - -/*************************************************************** -**************************************************************** -* P U B L I C F U N C T I O N S C O D E S E C T I O N * -**************************************************************** -***************************************************************/ - - -void dbGenerator(UserHandle *uh, ThreadData *data) -{ - GeneratorStatistics rg_warmUp; - GeneratorStatistics rg_coolDown; - GeneratorStatistics *st; - double periodStop; - double benchTimeStart; - double benchTimeEnd; - int i; - - myRandom48Init(data->randomSeed); - - initGeneratorStatistics(&rg_warmUp); - initGeneratorStatistics(&data->generator); - initGeneratorStatistics(&rg_coolDown); - - /*----------------*/ - /* warm up period */ - /*----------------*/ - periodStop = userGetTimeSync() + (double)data->warmUpSeconds; - while(userGetTimeSync() < periodStop){ - doOneTransaction(uh, &rg_warmUp); - } - - /*-------------------------*/ - /* normal benchmark period */ - /*-------------------------*/ - benchTimeStart = userGetTimeSync(); - - if( data->numTransactions > 0 ) { - for(i = 0; i < data->numTransactions; i++) - doOneTransaction(uh, &data->generator); - } - else { - periodStop = benchTimeStart + (double)data->testSeconds; - while(userGetTimeSync() < periodStop) - doOneTransaction(uh, &data->generator); - } - - benchTimeEnd = userGetTimeSync(); - - /*------------------*/ - /* cool down period */ - /*------------------*/ - periodStop = benchTimeEnd + data->coolDownSeconds; - while(userGetTimeSync() < periodStop){ - doOneTransaction(uh, &rg_coolDown); - } - - /*---------------------------------------------------------*/ - /* add the times for all transaction for inner loop timing */ - /*---------------------------------------------------------*/ - st = &data->generator; - st->innerLoopTime = 0.0; - for(i = 0 ; i < NUM_TRANSACTION_TYPES; i++) { - st->innerLoopTime += st->transactions[i].benchTime; - st->transactions[i].tps = getTps(st->transactions[i].count, - st->transactions[i].benchTime); - } - - st->outerLoopTime = benchTimeEnd - benchTimeStart; - st->outerTps = getTps(st->totalTransactions, st->outerLoopTime); - st->innerTps = getTps(st->totalTransactions, st->innerLoopTime); - - /* printf("maxsize = %d\n",maxsize); */ -} diff --git a/ndb/test/ndbapi/lmc-bench/src/generator/dbGenerator.h b/ndb/test/ndbapi/lmc-bench/src/generator/dbGenerator.h deleted file mode 100644 index 824688b6cf9..00000000000 --- a/ndb/test/ndbapi/lmc-bench/src/generator/dbGenerator.h +++ /dev/null @@ -1,61 +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 */ - -#ifndef DBGENERATOR_H -#define DBGENERATOR_H - -/*************************************************************** -* I N C L U D E D F I L E S * -***************************************************************/ - -#include "testData.h" -#include "userInterface.h" - -/*************************************************************** -* M A C R O S * -***************************************************************/ - -/***************************************************************/ -/* C O N S T A N T S */ -/***************************************************************/ - -/*************************************************************** -* D A T A S T R U C T U R E S * -***************************************************************/ - -/*************************************************************** -* P U B L I C F U N C T I O N S * -***************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - -extern void dbGenerator(UserHandle *uh, ThreadData *data); - - -#ifdef __cplusplus -} -#endif - -/*************************************************************** -* E X T E R N A L D A T A * -***************************************************************/ - - - -#endif /* DBGENERATOR_H */ - diff --git a/ndb/test/ndbapi/lmc-bench/src/generator/mainGenerator.c b/ndb/test/ndbapi/lmc-bench/src/generator/mainGenerator.c deleted file mode 100644 index 4a31db0b4e9..00000000000 --- a/ndb/test/ndbapi/lmc-bench/src/generator/mainGenerator.c +++ /dev/null @@ -1,323 +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 */ - -#include - -#include -#include -#include -#include - -#include "userInterface.h" -#include "dbGenerator.h" - - -static int numProcesses; -static int numTransactions; -static int numSeconds; -static int numWarmSeconds; -static char *testDbName; - -static ThreadData data[100]; - -typedef struct { - pthread_t threadId; - int waitSeconds; - int toExit; -}CheckpointData; - -static void usage(char *prog) -{ - char *progname; - - /*--------------------------------------------*/ - /* Get the name of the program (without path) */ - /*--------------------------------------------*/ - progname = strrchr(prog, '/'); - - if (progname == 0) - progname = prog; - else - ++progname; - - fprintf(stderr, - "Usage: %s [-db ] [-proc ] [-transactions ] [-time ]\n" - " -db Specifies the database name\n" - " default = '%s'\n" - " -proc Specifies that is the number of\n" - " concurrent processes. The default is 1.\n" - " -transactions Specifies that transactions will be\n" - " performed. The default is to do a specific time interval\n" - " -time Specifies that the test will run for sec.\n" - " The default is 10 sec\n" - " -warm Specifies the warm-up/cooldown period of sec.\n" - " The default is 10 sec\n", - progname, DEFAULTDB); - exit(1); -} - -static void parse_args(int argc,char **argv) -{ - int i; - - testDbName = DEFAULTDB; - numProcesses = 1; - numTransactions = 0; - numSeconds = 10; - numWarmSeconds = 10; - - i = 1; - while (i < argc){ - if (strcmp("-db",argv[i]) == 0) { - if (i + 1 >= argc) { - usage(argv[0]); - exit(1); - } - testDbName = argv[i + 1]; - i += 2; - } - else if (strcmp("-proc",argv[i]) == 0) { - if (i + 1 >= argc) { - usage(argv[0]); - exit(1); - } - if (sscanf(argv[i+1], "%d", &numProcesses) == -1 || - numProcesses <= 0 || numProcesses > 99) { - fprintf(stderr, "-proc flag requires a positive integer argument [1..99]\n"); - usage(argv[0]); - exit(1); - } - i += 2; - } - else if (strcmp("-transactions",argv[i]) == 0) { - if (i + 1 >= argc) { - usage(argv[0]); - exit(1); - } - if (sscanf(argv[i+1], "%d", &numTransactions) == -1 || - numTransactions < 0) { - fprintf(stderr, "-transactions flag requires a positive integer argument\n"); - usage(argv[0]); - exit(1); - } - i += 2; - } - else if (strcmp("-time",argv[i]) == 0) { - if (i + 1 >= argc) { - usage(argv[0]); - exit(1); - } - if (sscanf(argv[i+1], "%d", &numSeconds) == -1 || - numSeconds < 0) { - fprintf(stderr, "-time flag requires a positive integer argument\n"); - usage(argv[0]); - exit(1); - } - i += 2; - } - else if (strcmp("-warm",argv[i]) == 0) { - if (i + 1 >= argc) { - usage(argv[0]); - exit(1); - } - if (sscanf(argv[i+1], "%d", &numWarmSeconds) == -1 || - numWarmSeconds < 0) { - fprintf(stderr, "-warm flag requires a positive integer argument\n"); - usage(argv[0]); - exit(1); - } - i += 2; - } - else - usage(argv[0]); - } -} - -static void print_transaction(const char *header, - unsigned long totalCount, - TransactionDefinition *trans, - unsigned int printBranch, - unsigned int printRollback) -{ - double f; - - printf(" %s: %d (%.2f%%) Time: %.4f sec TPS = %.0f\n", - header, - trans->count, - (double)trans->count / (double)totalCount * 100.0, - trans->benchTime, - trans->tps); - - if( printBranch ){ - if( trans->count == 0 ) - f = 0.0; - else - f = (double)trans->branchExecuted / (double)trans->count * 100.0; - printf(" Branches Executed: %d (%.2f%%)\n", trans->branchExecuted, f); - } - - if( printRollback ){ - if( trans->count == 0 ) - f = 0.0; - else - f = (double)trans->rollbackExecuted / (double)trans->count * 100.0; - printf(" Rollback Executed: %d (%.2f%%)\n", trans->rollbackExecuted, f); - } -} - -void print_stats_sync(const char *title, - unsigned int length, - unsigned int transactionFlag, - GeneratorStatistics *gen, - int numProc) -{ - int i; - char buf[10]; - char name[100]; - - name[0] = 0; - NdbHost_GetHostName(name); - - printf("\n------ %s ------\n",title); - printf("Length : %d %s\n", - length, - transactionFlag ? "Transactions" : "sec"); - printf("Processor : %s\n", name); - printf("Number of Proc: %d\n",numProc); - printf("\n"); - - if( gen->totalTransactions == 0 ) { - printf(" No Transactions for this test\n"); - } - else { - for(i = 0; i < 5; i++) { - sprintf(buf, "T%d",i+1); - print_transaction(buf, - gen->totalTransactions, - &gen->transactions[i], - i >= 2, - i >= 3 ); - } - - printf("\n"); - printf(" Overall Statistics:\n"); - printf(" Transactions: %d\n", gen->totalTransactions); - printf(" Inner : %.0f TPS\n",gen->innerTps); - printf(" Outer : %.0f TPS\n",gen->outerTps); - printf("\n"); - } -} - -static void *threadRoutine(void *arg) -{ - UserHandle *uh; - ThreadData *data = (ThreadData *)arg; - - uh = userDbConnect(0, testDbName); - NdbSleep_MilliSleep(data->threadId); - dbGenerator(uh,data); - userDbDisconnect(uh); - - pthread_exit(0); - return(0); -} - -NDB_COMMAND(DbGenerator, "DbGenerator", "DbGenerator", "DbGenerator", 16384) -{ - int i; - int j; - GeneratorStatistics stats; - GeneratorStatistics *p; - CheckpointData cd; - - parse_args(argc,argv); - - printf("\nStarting Test with %d process(es) for %d %s\n", - numProcesses, - numTransactions ? numTransactions : numSeconds, - numTransactions ? "Transactions" : "sec"); - printf(" WarmUp/coolDown = %d sec\n", numWarmSeconds); - - /* - cd.waitSeconds = 300; - cd.toExit = 0; - pthread_create(&cd.threadId, 0, checkpointRoutine, &cd); - */ - - for(i = 0; i < numProcesses; i++) { - data[i].warmUpSeconds = numWarmSeconds; - data[i].testSeconds = numSeconds; - data[i].coolDownSeconds = numWarmSeconds; - data[i].numTransactions = numTransactions; - data[i].randomSeed = time(0)+i; - j = pthread_create(&data[i].threadId, 0, threadRoutine, &data[i]); - if(j != 0){ - perror("Failed to create thread"); - } - } - - /*--------------------------------*/ - /* Wait for all processes to exit */ - /*--------------------------------*/ - for(i = 0; i < numProcesses; i++) - pthread_join(data[i].threadId, 0); - - printf("All threads have finished\n"); - - cd.toExit = 1; - - /*-------------------------------------------*/ - /* Clear all structures for total statistics */ - /*-------------------------------------------*/ - stats.totalTransactions = 0; - stats.outerTps = 0.0; - stats.innerTps = 0.0; - - for(i = 0; i < NUM_TRANSACTION_TYPES; i++ ) { - stats.transactions[i].benchTime = 0.0; - stats.transactions[i].count = 0; - stats.transactions[i].tps = 0.0; - stats.transactions[i].branchExecuted = 0; - stats.transactions[i].rollbackExecuted = 0; - } - - /*--------------------------------*/ - /* Add the values for all Threads */ - /*--------------------------------*/ - for(i = 0; i < numProcesses; i++) { - p = &data[i].generator; - - stats.totalTransactions += p->totalTransactions; - stats.outerTps += p->outerTps; - stats.innerTps += p->innerTps; - - for(j = 0; j < NUM_TRANSACTION_TYPES; j++ ) { - stats.transactions[j].benchTime += p->transactions[j].benchTime; - stats.transactions[j].count += p->transactions[j].count; - stats.transactions[j].tps += p->transactions[j].tps; - stats.transactions[j].branchExecuted += p->transactions[j].branchExecuted; - stats.transactions[j].rollbackExecuted += p->transactions[j].rollbackExecuted; - } - } - - print_stats_sync("Test Results", - numTransactions ? numTransactions : numSeconds, - numTransactions ? 1 : 0, - &stats, - numProcesses); - - return(0); -} diff --git a/ndb/test/ndbapi/lmc-bench/src/include/testData.h b/ndb/test/ndbapi/lmc-bench/src/include/testData.h deleted file mode 100644 index 863c230502b..00000000000 --- a/ndb/test/ndbapi/lmc-bench/src/include/testData.h +++ /dev/null @@ -1,103 +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 */ - -#ifndef TESTDATA_H -#define TESTDATA_H - -/*************************************************************** -* I N C L U D E D F I L E S * -***************************************************************/ - -#include "testDefinitions.h" -#include - -/*************************************************************** -* M A C R O S * -***************************************************************/ - -/***************************************************************/ -/* C O N S T A N T S */ -/***************************************************************/ - -#define NUM_TRANSACTION_TYPES 5 -#define SESSION_LIST_LENGTH 1000 - -/*************************************************************** -* D A T A S T R U C T U R E S * -***************************************************************/ - -typedef struct { - SubscriberNumber subscriberNumber; - ServerId serverId; -} SessionElement; - -typedef struct { - SessionElement list[SESSION_LIST_LENGTH]; - unsigned int readIndex; - unsigned int writeIndex; - unsigned int numberInList; -} SessionList; - -typedef struct { - double benchTime; - unsigned int count; - double tps; - unsigned int branchExecuted; - unsigned int rollbackExecuted; -}TransactionDefinition; - -typedef struct { - RandomSequence transactionSequence; - RandomSequence rollbackSequenceT4; - RandomSequence rollbackSequenceT5; - - TransactionDefinition transactions[NUM_TRANSACTION_TYPES]; - - unsigned int totalTransactions; - - double innerLoopTime; - double innerTps; - - double outerLoopTime; - double outerTps; - - SessionList activeSessions; -} GeneratorStatistics; - -typedef struct { - unsigned long threadId; - unsigned long randomSeed; - - unsigned int warmUpSeconds; - unsigned int testSeconds; - unsigned int coolDownSeconds; - unsigned int numTransactions; - - GeneratorStatistics generator; -}ThreadData; - -/*************************************************************** -* P U B L I C F U N C T I O N S * -***************************************************************/ - -/*************************************************************** -* E X T E R N A L D A T A * -***************************************************************/ - - - -#endif /* TESTDATA_H */ - diff --git a/ndb/test/ndbapi/lmc-bench/src/include/userInterface.h b/ndb/test/ndbapi/lmc-bench/src/include/userInterface.h deleted file mode 100644 index b70ded87756..00000000000 --- a/ndb/test/ndbapi/lmc-bench/src/include/userInterface.h +++ /dev/null @@ -1,128 +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 */ - -#ifndef DBINTERFACE_H -#define DBINTERFACE_H - -/***************************************************************/ -/* I N C L U D E D F I L E S */ -/***************************************************************/ - -#include "testDefinitions.h" - -/*************************************************************** -* M A C R O S * -***************************************************************/ - -/***************************************************************/ -/* C O N S T A N T S */ -/***************************************************************/ - -/*-----------------------*/ -/* Default Database Name */ -/*-----------------------*/ -#define DEFAULTDB "TestDbClient" - -/*************************************************************** -* D A T A S T R U C T U R E S * -***************************************************************/ - -typedef struct { - struct Ndb * pNDB; - struct NdbConnection * pCurrTrans; -} UserHandle; - -/*************************************************************** -* P U B L I C F U N C T I O N S * -***************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - -extern double userGetTimeSync(void); - -extern void userCheckpoint(UserHandle *uh); - -extern UserHandle *userDbConnect(uint32 createDb, char *dbName); -extern void userDbDisconnect(UserHandle *uh); - -extern int userDbInsertServer(UserHandle *uh, - ServerId serverId, - SubscriberSuffix suffix, - ServerName name); - -extern int userDbInsertSubscriber(UserHandle *uh, - SubscriberNumber number, - uint32 groupId, - SubscriberName name); - -extern int userDbInsertGroup(UserHandle *uh, - GroupId groupId, - GroupName name, - Permission allowRead, - Permission allowInsert, - Permission allowDelete); - -extern int userDbCommit(UserHandle *uh); -extern int userDbRollback(UserHandle *uh); - -extern void userTransaction_T1(UserHandle *uh, - SubscriberNumber number, - Location new_location, - ChangedBy changed_by, - ChangedTime changed_time); - -extern void userTransaction_T2(UserHandle *uh, - SubscriberNumber number, - Location *new_location, - ChangedBy changed_by, - ChangedTime changed_time, - SubscriberName subscriberName); - -extern void userTransaction_T3(UserHandle *uh, - SubscriberNumber number, - ServerId server_id, - ServerBit server_bit, - SessionDetails session_details, - unsigned int *branch_executed); - -extern void userTransaction_T4(UserHandle *uh, - SubscriberNumber number, - ServerId server_id, - ServerBit server_bit, - SessionDetails session_details, - unsigned int do_rollback, - unsigned int *branch_executed); - -extern void userTransaction_T5(UserHandle *uh, - SubscriberNumber number, - ServerId server_id, - ServerBit server_bit, - unsigned int do_rollback, - unsigned int *branch_executed); - - -#ifdef __cplusplus -} -#endif - -/*************************************************************** -* E X T E R N A L D A T A * -***************************************************************/ - -#endif /* DBINTERFACE_H */ - diff --git a/ndb/test/ndbapi/lmc-bench/src/makevars.linux b/ndb/test/ndbapi/lmc-bench/src/makevars.linux deleted file mode 100644 index a933669cfe7..00000000000 --- a/ndb/test/ndbapi/lmc-bench/src/makevars.linux +++ /dev/null @@ -1,6 +0,0 @@ -PROJECT_TOP = /home/lmcritr/ecurlmc/users/lmcritr/dbBenchmark - -CFLAGS = -Wall -Wstrict-prototypes -O2 -I/opt/TimesTen4.1/32/include/ -I../include -LDFLAGS = -L/opt/TimesTen4.1/32/lib -Wl,-rpath,/opt/TimesTen4.1/32/lib -LIBS = -ltten -ldl -LIBSCS = -lttclient -ldl diff --git a/ndb/test/ndbapi/lmc-bench/src/makevars.sparc b/ndb/test/ndbapi/lmc-bench/src/makevars.sparc deleted file mode 100644 index 57ab8bf982f..00000000000 --- a/ndb/test/ndbapi/lmc-bench/src/makevars.sparc +++ /dev/null @@ -1,15 +0,0 @@ - -include $(UAS_TOP)/Defs.mk - -LINK.CC = CC -CC := /opt/as/forte6/SUNWspro/bin/cc -export CC - -NDB_LIB = -L$(UAS_TOP)/API -lNDB_API \ - -L$(UAS_OSPACE_LOC)/lib -lospace \ - -lrt - -CFLAGS = -xO3 -I../include -mt -LDFLAGS = $(NDB_LIB) -lpthread -LIBS = -LIBSCS = diff --git a/ndb/test/ndbapi/lmc-bench/src/populator/Makefile b/ndb/test/ndbapi/lmc-bench/src/populator/Makefile deleted file mode 100644 index 2107c948843..00000000000 --- a/ndb/test/ndbapi/lmc-bench/src/populator/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := DbCreate -BIN_TARGET_ARCHIVES := lmc_User - -CCFLAGS_LOC:= -I../include -I../../include - -SOURCES := \ - mainPopulate.c\ - dbPopulate.c - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/test/ndbapi/lmc-bench/src/populator/dbPopulate.c b/ndb/test/ndbapi/lmc-bench/src/populator/dbPopulate.c deleted file mode 100644 index 42fbb52f3b2..00000000000 --- a/ndb/test/ndbapi/lmc-bench/src/populator/dbPopulate.c +++ /dev/null @@ -1,244 +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 */ - -/*************************************************************** -* I N C L U D E D F I L E S * -***************************************************************/ - -#include - -#include "userInterface.h" - -#include "dbPopulate.h" -#include -#include - -/*************************************************************** -* L O C A L C O N S T A N T S * -***************************************************************/ - -/*************************************************************** -* L O C A L D A T A S T R U C T U R E S * -***************************************************************/ - -/*************************************************************** -* L O C A L F U N C T I O N S * -***************************************************************/ - -static void getRandomSubscriberData(int subscriberNo, - SubscriberNumber number, - SubscriberName name); - -static void populate(char *title, - int count, - void (*func)(UserHandle*,int), - UserHandle *uh); - -static void populateServers(UserHandle *uh, int count); -static void populateSubscribers(UserHandle *uh, int count); -static void populateGroups(UserHandle *uh, int count); - -/*************************************************************** -* L O C A L D A T A * -***************************************************************/ - -static SequenceValues permissionsDefinition[] = { - {90, 1}, - {10, 0}, - {0, 0} -}; - -/*************************************************************** -* P U B L I C D A T A * -***************************************************************/ - - -/*************************************************************** -**************************************************************** -* L O C A L F U N C T I O N S C O D E S E C T I O N * -**************************************************************** -***************************************************************/ - -static void getRandomSubscriberData(int subscriberNo, - SubscriberNumber number, - SubscriberName name) -{ - char sbuf[SUBSCRIBER_NUMBER_LENGTH + 1]; - sprintf(sbuf, "%.*d", SUBSCRIBER_NUMBER_LENGTH, subscriberNo); - memcpy(number, sbuf, SUBSCRIBER_NUMBER_LENGTH); - - memset(name, myRandom48(26)+'A', SUBSCRIBER_NAME_LENGTH); -} - -static void populate(char *title, - int count, - void (*func)(UserHandle*, int), - UserHandle *uh) -{ - ndbout_c("Populating %d '%s' ... ",count, title); - /* fflush(stdout); */ - func(uh,count); - ndbout_c("done"); -} - -static void populateServers(UserHandle *uh, int count) -{ - int i, j; - int len; - char tmp[80]; - int suffix_length = 1; - ServerName serverName; - SubscriberSuffix suffix; - - int commitCount = 0; - - for(i = 0; i < SUBSCRIBER_NUMBER_SUFFIX_LENGTH; i++) - suffix_length *= 10; - - for(i = 0; i < count; i++) { - sprintf(tmp, "-Server %d-", i); - - len = strlen(tmp); - for(j = 0; j < SERVER_NAME_LENGTH; j++){ - serverName[j] = tmp[j % len]; - } - /* serverName[j] = 0; not null-terminated */ - - for(j = 0; j < suffix_length; j++){ - char sbuf[SUBSCRIBER_NUMBER_SUFFIX_LENGTH + 1]; - sprintf(sbuf, "%.*d", SUBSCRIBER_NUMBER_SUFFIX_LENGTH, j); - memcpy(suffix, sbuf, SUBSCRIBER_NUMBER_SUFFIX_LENGTH); - userDbInsertServer(uh, i, suffix, serverName); - commitCount ++; - if((commitCount % OP_PER_TRANS) == 0) - userDbCommit(uh); - } - } - if((commitCount % OP_PER_TRANS) != 0) - userDbCommit(uh); -} - -static void populateSubscribers(UserHandle *uh, int count) -{ - SubscriberNumber number; - SubscriberName name; - int i, j, k; - int res; - - SequenceValues values[NO_OF_GROUPS+1]; - RandomSequence seq; - - for(i = 0; i < NO_OF_GROUPS; i++) { - values[i].length = 1; - values[i].value = i; - } - - values[i].length = 0; - values[i].value = 0; - - if( initSequence(&seq, values) != 0 ) { - ndbout_c("could not set the sequence of random groups"); - exit(0); - } - -#define RETRIES 25 - - for(i = 0; i < count; i+= OP_PER_TRANS) { - for(j = 0; j - -#include "userInterface.h" -#include "dbPopulate.h" -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif -int useTableLogging; -int useIndexTables; -#ifdef __cplusplus -} -#endif - - -static -void usage(const char *prog) -{ - - ndbout_c( - "Usage: %s [-l]\n" - " -l Use logging and checkpointing on tables\n", - " -i Use index tables\n", - prog); - - exit(1); -} - -NDB_COMMAND(DbCreate, "DbCreate", "DbCreate", "DbCreate", 16384) -{ - int i; - UserHandle *uh; - - useTableLogging = useIndexTables = 0; - - for(i = 1; i - -#include "userInterface.h" -#include "userHandle.h" - -/*************************************************************** -* L O C A L C O N S T A N T S * -***************************************************************/ - -/*************************************************************** -* L O C A L D A T A S T R U C T U R E S * -***************************************************************/ - -/*************************************************************** -* L O C A L F U N C T I O N S * -***************************************************************/ - - -/*************************************************************** -* L O C A L D A T A * -***************************************************************/ - -/*----------------*/ -/* Transaction T1 */ -/*----------------*/ -static char *update_subscriber_stmnt = "update subscriber set \ -location = ?,changedBy = ?, changedTime = ? where subscriberNumber = ?"; - -/*----------------*/ -/* Transaction T2 */ -/*----------------*/ -static char *read_subscriber_stmnt = "select subscriberName,location,\ -changedBy,changedTime from subscriber where subscriberNumber = ? for update"; - -/*----------------*/ -/* Transaction T3 */ -/*----------------*/ -static char *read_subscriber_session_stmnt = "select activeSessions,groupId,\ -changedBy,changedTime from subscriber where subscriberNumber = ? for update"; - -static char *read_group_allowRead_stmnt = "select allowRead from userGroup \ -where groupId = ?"; -static char *read_group_allowInsert_stmnt = "select allowInsert from userGroup \ -where groupId = ?"; -static char *read_group_allowDelete_stmnt = "select allowDelete from userGroup \ -where groupId = ?"; - -static char *read_session_details_stmnt = "select sessionData from userSession \ -where subscriberNumber = ? and serverId = ? for update"; - -static char *update_noOfRead_stmnt = "update server \ -set noOfRead = noOfRead + 1 where serverId = ? and subscriberSuffix = ?"; -static char *update_noOfInsert_stmnt = "update server \ -set noOfInsert = noOfInsert + 1 where serverId = ? and subscriberSuffix = ?"; -static char *update_noOfDelete_stmnt = "update server \ -set noOfDelete = noOfDelete + 1 where serverId = ? and subscriberSuffix = ?"; - -static char *insert_session_stmnt = "insert into userSession values (?,?,?)"; - -static char *delete_session_stmnt = "delete from userSession \ -where subscriberNumber = ? and serverId = ?"; - -static char *update_subscriber_session_stmnt = "update subscriber set \ -activeSessions = ? where subscriberNumber = ?"; - -/*************************************************************** -* P U B L I C D A T A * -***************************************************************/ - - -/*************************************************************** -**************************************************************** -* L O C A L F U N C T I O N S C O D E S E C T I O N * -**************************************************************** -***************************************************************/ - -extern void handle_error(SQLHDBC hdbc, - SQLHENV henv, - SQLHSTMT hstmt, - SQLRETURN rc, - char *filename, - int lineno); - -/*************************************************************** -**************************************************************** -* P U B L I C F U N C T I O N S C O D E S E C T I O N * -**************************************************************** -***************************************************************/ - -int localDbPrepare(UserHandle *uh) -{ - SQLRETURN rc; - - if(!uh) return(-1); - - /*-----------------------------*/ - /* Update Subscriber Statement */ - /*-----------------------------*/ - rc = SQLAllocStmt(uh->hdbc, &uh->updateSubscriber.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to allocate insert group statement\n"); - return(-1); - } - - rc = SQLPrepare(uh->updateSubscriber.stmt,(SQLCHAR *) update_subscriber_stmnt, SQL_NTS); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { -/* -handle_error(uh->hdbc, uh->henv, uh->updateSubscriber.stmt, rc, __FILE__, __LINE__); -*/ - printf("Unable to prepare update subscriber statement\n"); - return(-1); - } - - rc = SQLBindParameter(uh->updateSubscriber.stmt, - 1,SQL_PARAM_INPUT,SQL_C_DEFAULT,SQL_INTEGER, - 0,0, - &uh->updateSubscriber.values.location,0,NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare update subscriber statement param 1\n"); - return(-1); - } - - rc = SQLBindParameter(uh->updateSubscriber.stmt, - 2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, - CHANGED_BY_LENGTH+1,0, - uh->updateSubscriber.values.changedBy,0,NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare update subscriber statement param 2\n"); - return(-1); - } - - rc = SQLBindParameter(uh->updateSubscriber.stmt, - 3,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, - CHANGED_TIME_LENGTH+1,0, - uh->updateSubscriber.values.changedTime,0,NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare update subscriber statement param 3\n"); - return(-1); - } - - rc = SQLBindParameter(uh->updateSubscriber.stmt, - 4,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, - SUBSCRIBER_NUMBER_LENGTH+1,0, - uh->updateSubscriber.values.number,0,NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare update subscriber statement param 3\n"); - return(-1); - } - - /*---------------------------*/ - /* Read Subscriber Statement */ - /*---------------------------*/ - rc = SQLAllocStmt(uh->hdbc, &uh->readSubscriber.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to allocate read subscriber statement\n"); - return(-1); - } - - rc = SQLPrepare(uh->readSubscriber.stmt,(SQLCHAR *) read_subscriber_stmnt, SQL_NTS); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare read subscriber statement\n"); - return(-1); - } - - rc = SQLBindParameter(uh->readSubscriber.stmt, - 1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, - SUBSCRIBER_NUMBER_LENGTH+1,0, - uh->readSubscriber.values.number,0,NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare read subscriber statement param 1\n"); - return(-1); - } - - rc = SQLBindCol(uh->readSubscriber.stmt, 1, - SQL_C_CHAR, - uh->readSubscriber.values.name, SUBSCRIBER_NAME_LENGTH+1, - NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to bind column 1 to read subscriber statement\n"); - return(-1); - } - - rc = SQLBindCol(uh->readSubscriber.stmt, 2, - SQL_C_DEFAULT, - &uh->readSubscriber.values.location, 1, - NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to bind column 2 to read subscriber statement\n"); - return(-1); - } - - rc = SQLBindCol(uh->readSubscriber.stmt, 3, - SQL_C_CHAR, - uh->readSubscriber.values.changedBy, CHANGED_BY_LENGTH+1, - NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to bind column 3 to read subscriber statement\n"); - return(-1); - } - - rc = SQLBindCol(uh->readSubscriber.stmt, 4, - SQL_C_CHAR, - uh->readSubscriber.values.changedTime, CHANGED_TIME_LENGTH+1, - NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to bind column 4 to read subscriber statement\n"); - return(-1); - } - - /*------------------------------------*/ - /* Read Subscriber Sessions Statement */ - /*------------------------------------*/ - rc = SQLAllocStmt(uh->hdbc, &uh->readSubscriberSession.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to allocate read subscriber session statement\n"); - return(-1); - } - - rc = SQLPrepare(uh->readSubscriberSession.stmt,(SQLCHAR *) read_subscriber_session_stmnt, SQL_NTS); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare read subscriber sessions statement\n"); - return(-1); - } - - rc = SQLBindParameter(uh->readSubscriberSession.stmt, - 1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, - SUBSCRIBER_NUMBER_LENGTH+1,0, - uh->readSubscriberSession.values.number,0,NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare read subscriber statement param 1\n"); - return(-1); - } - - rc = SQLBindCol(uh->readSubscriberSession.stmt, 1, - SQL_C_DEFAULT, - &uh->readSubscriberSession.values.activeSessions, 0, - NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to bind column 1 to read subscriber sessions statement\n"); - return(-1); - } - - rc = SQLBindCol(uh->readSubscriberSession.stmt, 2, - SQL_C_DEFAULT, - &uh->readSubscriberSession.values.groupId, 0, - NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to bind column 2 to read subscriber sessions statement\n"); - return(-1); - } - - rc = SQLBindCol(uh->readSubscriberSession.stmt, 3, - SQL_C_CHAR, - uh->readSubscriberSession.values.changedBy, CHANGED_BY_LENGTH+1, - NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to bind column 3 to read subscriber sessions statement\n"); - return(-1); - } - - rc = SQLBindCol(uh->readSubscriberSession.stmt, 4, - SQL_C_CHAR, - uh->readSubscriberSession.values.changedTime, CHANGED_TIME_LENGTH+1, - NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to bind column 4 to read subscriber sessions statement\n"); - return(-1); - } - - /*--------------------------------*/ - /* Read Group AllowRead Statement */ - /*--------------------------------*/ - rc = SQLAllocStmt(uh->hdbc, &uh->readGroupAllowRead.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to allocate read subscriber session statement\n"); - return(-1); - } - - rc = SQLPrepare(uh->readGroupAllowRead.stmt,(SQLCHAR *) read_group_allowRead_stmnt, SQL_NTS); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare read group allow read statement\n"); - return(-1); - } - - rc = SQLBindParameter(uh->readGroupAllowRead.stmt, - 1,SQL_PARAM_INPUT,SQL_C_DEFAULT,SQL_INTEGER, - 0,0, - &uh->readGroupAllowRead.values.groupId,0,NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare read allow read statement param 1\n"); - return(-1); - } - - rc = SQLBindCol(uh->readGroupAllowRead.stmt, 1, - SQL_C_DEFAULT, - &uh->readGroupAllowRead.values.allowRead, 0, - NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to bind column 1 to read group allow read statement\n"); - return(-1); - } - - /*----------------------------------*/ - /* Read Group AllowInsert Statement */ - /*----------------------------------*/ - rc = SQLAllocStmt(uh->hdbc, &uh->readGroupAllowInsert.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to allocate read subscriber session statement\n"); - return(-1); - } - - rc = SQLPrepare(uh->readGroupAllowInsert.stmt,(SQLCHAR *) read_group_allowInsert_stmnt, SQL_NTS); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare read group allow read statement\n"); - return(-1); - } - - rc = SQLBindParameter(uh->readGroupAllowInsert.stmt, - 1,SQL_PARAM_INPUT,SQL_C_DEFAULT,SQL_INTEGER, - 0,0, - &uh->readGroupAllowInsert.values.groupId,0,NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare read allow read statement param 1\n"); - return(-1); - } - - rc = SQLBindCol(uh->readGroupAllowInsert.stmt, 1, - SQL_C_DEFAULT, - &uh->readGroupAllowInsert.values.allowInsert, 0, - NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to bind column 1 to read group allow read statement\n"); - return(-1); - } - - /*----------------------------------*/ - /* Read Group AllowDelete Statement */ - /*----------------------------------*/ - rc = SQLAllocStmt(uh->hdbc, &uh->readGroupAllowDelete.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to allocate read subscriber session statement\n"); - return(-1); - } - - rc = SQLPrepare(uh->readGroupAllowDelete.stmt,(SQLCHAR *) read_group_allowDelete_stmnt, SQL_NTS); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare read group allow read statement\n"); - return(-1); - } - - rc = SQLBindParameter(uh->readGroupAllowDelete.stmt, - 1,SQL_PARAM_INPUT,SQL_C_DEFAULT,SQL_INTEGER, - 0,0, - &uh->readGroupAllowDelete.values.groupId,0,NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare read allow read statement param 1\n"); - return(-1); - } - - rc = SQLBindCol(uh->readGroupAllowDelete.stmt, 1, - SQL_C_DEFAULT, - &uh->readGroupAllowDelete.values.allowDelete, 0, - NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to bind column 1 to read group allow read statement\n"); - return(-1); - } - - /*----------------------*/ - /* read session details */ - /*----------------------*/ - rc = SQLAllocStmt(uh->hdbc, &uh->readSessionDetails.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to allocate read session details statement\n"); - return(-1); - } - - rc = SQLPrepare(uh->readSessionDetails.stmt,(SQLCHAR *) read_session_details_stmnt, SQL_NTS); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare read session details statement\n"); - return(-1); - } - - rc = SQLBindParameter(uh->readSessionDetails.stmt, - 1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, - SUBSCRIBER_NUMBER_LENGTH+1,0, - uh->readSessionDetails.values.number,0,NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare read sessions param 1\n"); - return(-1); - } - - rc = SQLBindParameter(uh->readSessionDetails.stmt, - 2,SQL_PARAM_INPUT,SQL_C_DEFAULT,SQL_INTEGER, - 0,0, - &uh->readSessionDetails.values.serverId,0,NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare read sessions param 2\n"); - return(-1); - } - - rc = SQLBindCol(uh->readSessionDetails.stmt, 1, - SQL_C_CHAR, - uh->readSessionDetails.values.details, SESSION_DETAILS_LENGTH+1, - NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to bind column 1 to read group allow read statement\n"); - return(-1); - } - - /*-------------------*/ - /* Update no of Read */ - /*-------------------*/ - rc = SQLAllocStmt(uh->hdbc, &uh->updateServerNoOfRead.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to allocate update noOfRead statement\n"); - return(-1); - } - - rc = SQLPrepare(uh->updateServerNoOfRead.stmt,(SQLCHAR *) update_noOfRead_stmnt, SQL_NTS); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare update noOfRead statement\n"); - return(-1); - } - - rc = SQLBindParameter(uh->updateServerNoOfRead.stmt, - 1,SQL_PARAM_INPUT,SQL_C_DEFAULT,SQL_INTEGER, - 0,0, - &uh->updateServerNoOfRead.values.serverId,0,NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare read noOfRead param 1\n"); - return(-1); - } - - rc = SQLBindParameter(uh->updateServerNoOfRead.stmt, - 2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, - SUBSCRIBER_NUMBER_SUFFIX_LENGTH+1,0, - uh->updateServerNoOfRead.values.suffix,0,NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare read noOfRead param 2\n"); - return(-1); - } - - /*----------------*/ - /* Insert Session */ - /*----------------*/ - rc = SQLAllocStmt(uh->hdbc, &uh->insertSession.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to allocate update noOfRead statement\n"); - return(-1); - } - - rc = SQLPrepare(uh->insertSession.stmt,(SQLCHAR *) insert_session_stmnt, SQL_NTS); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare insert session statement\n"); - return(-1); - } - - rc = SQLBindParameter(uh->insertSession.stmt, - 1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, - SUBSCRIBER_NUMBER_LENGTH+1,0, - uh->insertSession.values.number,0,NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare read sessions param 1\n"); - return(-1); - } - - rc = SQLBindParameter(uh->insertSession.stmt, - 2,SQL_PARAM_INPUT,SQL_C_DEFAULT,SQL_INTEGER, - 0,0, - &uh->insertSession.values.serverId,0,NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare read noOfRead param 2\n"); - return(-1); - } - - rc = SQLBindParameter(uh->insertSession.stmt, - 3,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, - SESSION_DETAILS_LENGTH+1,0, - uh->insertSession.values.details,0,NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare read sessions param 1\n"); - return(-1); - } - - /*----------------------------*/ - /* Update subscriber sessions */ - /*----------------------------*/ - rc = SQLAllocStmt(uh->hdbc, &uh->updateSubscriberSession.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to allocate update noOfRead statement\n"); - return(-1); - } - - rc = SQLPrepare(uh->updateSubscriberSession.stmt,(SQLCHAR *) update_subscriber_session_stmnt, SQL_NTS); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare update subscriber session statement\n"); - return(-1); - } - - rc = SQLBindParameter(uh->updateSubscriberSession.stmt, - 1,SQL_PARAM_INPUT,SQL_C_DEFAULT,SQL_INTEGER, - 0,0, - &uh->updateSubscriberSession.values.activeSessions,0,NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare read noOfRead param 2\n"); - return(-1); - } - - rc = SQLBindParameter(uh->updateSubscriberSession.stmt, - 2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, - SUBSCRIBER_NUMBER_LENGTH+1,0, - uh->updateSubscriberSession.values.number,0,NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare read sessions param 1\n"); - return(-1); - } - - /*---------------------*/ - /* Update no of Insert */ - /*---------------------*/ - rc = SQLAllocStmt(uh->hdbc, &uh->updateServerNoOfInsert.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to allocate update noOfRead statement\n"); - return(-1); - } - - rc = SQLPrepare(uh->updateServerNoOfInsert.stmt,(SQLCHAR *) update_noOfInsert_stmnt, SQL_NTS); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare update noOfRead statement\n"); - return(-1); - } - - rc = SQLBindParameter(uh->updateServerNoOfInsert.stmt, - 1,SQL_PARAM_INPUT,SQL_C_DEFAULT,SQL_INTEGER, - 0,0, - &uh->updateServerNoOfInsert.values.serverId,0,NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare read noOfRead param 1\n"); - return(-1); - } - - rc = SQLBindParameter(uh->updateServerNoOfInsert.stmt, - 2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, - SUBSCRIBER_NUMBER_SUFFIX_LENGTH+1,0, - uh->updateServerNoOfInsert.values.suffix,0,NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare read noOfRead param 2\n"); - return(-1); - } - - /*----------------*/ - /* Delete Session */ - /*----------------*/ - rc = SQLAllocStmt(uh->hdbc, &uh->deleteSession.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to allocate update noOfRead statement\n"); - return(-1); - } - - rc = SQLPrepare(uh->deleteSession.stmt,(SQLCHAR *) delete_session_stmnt, SQL_NTS); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare insert session statement\n"); - return(-1); - } - - rc = SQLBindParameter(uh->deleteSession.stmt, - 1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, - SUBSCRIBER_NUMBER_LENGTH+1,0, - uh->deleteSession.values.number,0,NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare read sessions param 1\n"); - return(-1); - } - - rc = SQLBindParameter(uh->deleteSession.stmt, - 2,SQL_PARAM_INPUT,SQL_C_DEFAULT,SQL_INTEGER, - 0,0, - &uh->deleteSession.values.serverId,0,NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare read noOfRead param 2\n"); - return(-1); - } - - /*---------------------*/ - /* Update no of Delete */ - /*---------------------*/ - rc = SQLAllocStmt(uh->hdbc, &uh->updateServerNoOfDelete.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to allocate update noOfRead statement\n"); - return(-1); - } - - rc = SQLPrepare(uh->updateServerNoOfDelete.stmt,(SQLCHAR *) update_noOfDelete_stmnt, SQL_NTS); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare update noOfRead statement\n"); - return(-1); - } - - rc = SQLBindParameter(uh->updateServerNoOfDelete.stmt, - 1,SQL_PARAM_INPUT,SQL_C_DEFAULT,SQL_INTEGER, - 0,0, - &uh->updateServerNoOfDelete.values.serverId,0,NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare read noOfRead param 1\n"); - return(-1); - } - - rc = SQLBindParameter(uh->updateServerNoOfDelete.stmt, - 2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, - SUBSCRIBER_NUMBER_SUFFIX_LENGTH+1,0, - uh->updateServerNoOfInsert.values.suffix,0,NULL); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to prepare read noOfRead param 2\n"); - return(-1); - } - - /*-------------------------------*/ - /* Commit all prepare statements */ - /*-------------------------------*/ - rc = SQLTransact(uh->henv, uh->hdbc, SQL_COMMIT); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to commit all prepare insert statement\n"); - return(-1); - } - - return(0); -} diff --git a/ndb/test/ndbapi/lmc-bench/src/user/macros.h b/ndb/test/ndbapi/lmc-bench/src/user/macros.h deleted file mode 100644 index 363f247b93f..00000000000 --- a/ndb/test/ndbapi/lmc-bench/src/user/macros.h +++ /dev/null @@ -1,51 +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 */ - -#ifndef MACROS_H -#define MACROS_H - -#include -#include - -#define ERROR(x) {ndbout_c((x)); } -#define ERROR1(x,y) {ndbout_c((x), (y)); } -#define ERROR2(x,y,z) {ndbout_c((x), (y), (z)); } -#define ERROR3(x,y,z,u) {ndbout_c((x), (y), (z), (u)); } -#define ERROR4(x,y,z,u,w) {ndbout_c((x), (y), (z), (u), (w)); } - -#define INIT_RANDOM(x) srand48((x)) -#define UI_RANDOM(x) ((unsigned int)(lrand48()%(x))) - -#define ASSERT(cond, message) \ - { if(!(cond)) { ERROR(message); exit(-1); }} - -#ifdef DEBUG_ON -#define DEBUG(x) {ndbout_c((x)); } -#define DEBUG1(x,y) {ndbout_c((x), (y)); } -#define DEBUG2(x,y,z) {ndbout_c((x), (y), (z)); } -#define DEBUG3(x,y,z,u) {ndbout_c((x), (y), (z), (u)); } -#define DEBUG4(x,y,z,u,w) {ndbout_c((x), (y), (z), (u), (w)); } -#define DEBUG5(x,y,z,u,w, v) {ndbout_c((x), (y), (z), (u), (w), (v)); } -#else -#define DEBUG(x) -#define DEBUG1(x,y) -#define DEBUG2(x,y,z) -#define DEBUG3(x,y,z,u) -#define DEBUG4(x,y,z,u,w) -#define DEBUG5(x,y,z,u,w, v) -#endif - -#endif diff --git a/ndb/test/ndbapi/lmc-bench/src/user/ndb_error.hpp b/ndb/test/ndbapi/lmc-bench/src/user/ndb_error.hpp deleted file mode 100644 index b3aaeac822e..00000000000 --- a/ndb/test/ndbapi/lmc-bench/src/user/ndb_error.hpp +++ /dev/null @@ -1,31 +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 */ - -#ifndef NDB_ERROR_H -#define NDB_ERROR_H - -#include - -#define error_handler(x,y, z) { \ - ndbout << x << " " << y << endl; \ - exit(-1); } - -#define CHECK_NULL(x,y, z) if(x == 0) \ - error_handler(y,(z->getNdbError()), 0) -#define CHECK_MINUS_ONE(x, y, z) if(x == -1) \ - error_handler(y,(z->getNdbError()), 0) - -#endif diff --git a/ndb/test/ndbapi/lmc-bench/src/user/ndb_user_populate.cpp b/ndb/test/ndbapi/lmc-bench/src/user/ndb_user_populate.cpp deleted file mode 100644 index ce3a76cdd59..00000000000 --- a/ndb/test/ndbapi/lmc-bench/src/user/ndb_user_populate.cpp +++ /dev/null @@ -1,165 +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 */ - - -extern "C" { -#include "user_populate.h" -} - -#include -#include - -#include "ndb_schema.hpp" -#include "ndb_error.hpp" - -int -insert_subscriber(void * obj, - SubscriberNumber number, - SubscriberName name, - GroupId groupId, - Location l, - ActiveSessions activeSessions, - ChangedBy changedBy, - ChangedTime changedTime){ - Ndb * pNDB = (Ndb *)obj; - int check; - - NdbConnection * MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("startTranscation", pNDB->getNdbErrorString(), 0); - - NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "getNdbOperation", MyTransaction); - - check = MyOperation->insertTuple(); - CHECK_MINUS_ONE(check, "insertTuple", MyTransaction); - - check = MyOperation->equal(SUBSCRIBER_NUMBER, number); - CHECK_MINUS_ONE(check, "equal", MyTransaction); - - check = MyOperation->setValue(SUBSCRIBER_NAME, name); - CHECK_MINUS_ONE(check, "setValue name", MyTransaction); - - check = MyOperation->setValue(SUBSCRIBER_GROUP, (char*)&groupId); - CHECK_MINUS_ONE(check, "setValue group", MyTransaction); - - check = MyOperation->setValue(SUBSCRIBER_LOCATION, (char*)&l); - CHECK_MINUS_ONE(check, "setValue location", MyTransaction); - - check = MyOperation->setValue(SUBSCRIBER_SESSIONS, (char*)&activeSessions); - CHECK_MINUS_ONE(check, "setValue sessions", MyTransaction); - - check = MyOperation->setValue(SUBSCRIBER_CHANGED_BY, changedBy); - CHECK_MINUS_ONE(check, "setValue changedBy", MyTransaction); - - check = MyOperation->setValue(SUBSCRIBER_CHANGED_TIME, changedTime); - CHECK_MINUS_ONE(check, "setValue changedTime", MyTransaction); - - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "commit", MyTransaction); - - pNDB->closeTransaction(MyTransaction); - return 0; -} - -int -insert_server(void * obj, - ServerId serverId, - SubscriberSuffix suffix, - ServerName name, - Counter noOfRead, - Counter noOfInsert, - Counter noOfDelete){ - Ndb * pNDB = (Ndb *)obj; - int check; - - NdbConnection * MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("startTranscation", pNDB->getNdbErrorString(), 0); - - NdbOperation *MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); - CHECK_NULL(MyOperation, "getNdbOperation", MyTransaction); - - check = MyOperation->insertTuple(); - CHECK_MINUS_ONE(check, "insert tuple", MyTransaction); - - check = MyOperation->equal(SERVER_ID, (char*)&serverId); - CHECK_MINUS_ONE(check, "setValue id", MyTransaction); - - check = MyOperation->setValue(SERVER_SUBSCRIBER_SUFFIX, suffix); - CHECK_MINUS_ONE(check, "setValue suffix", MyTransaction); - - check = MyOperation->setValue(SERVER_NAME, name); - CHECK_MINUS_ONE(check, "setValue name", MyTransaction); - - check = MyOperation->setValue(SERVER_READS, (char*)&noOfRead); - CHECK_MINUS_ONE(check, "setValue reads", MyTransaction); - - check = MyOperation->setValue(SERVER_INSERTS, (char*)&noOfInsert); - CHECK_MINUS_ONE(check, "setValue inserts", MyTransaction); - - check = MyOperation->setValue(SERVER_DELETES, (char*)&noOfDelete); - CHECK_MINUS_ONE(check, "setValue deletes", MyTransaction); - - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "commit", MyTransaction); - - pNDB->closeTransaction(MyTransaction); - return 0; -} - -int -insert_group(void * obj, - GroupId groupId, - GroupName name, - Permission allowRead, - Permission allowInsert, - Permission allowDelete){ - Ndb * pNDB = (Ndb *)obj; - int check; - - NdbConnection * MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("startTranscation", pNDB->getNdbErrorString(), 0); - - NdbOperation *MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); - CHECK_NULL(MyOperation, "getNdbOperation", MyTransaction); - - check = MyOperation->insertTuple(); - CHECK_MINUS_ONE(check, "insertTuple", MyTransaction); - - check = MyOperation->equal(GROUP_ID, (char*)&groupId); - CHECK_MINUS_ONE(check, "equal", MyTransaction); - - check = MyOperation->setValue(GROUP_NAME, name); - CHECK_MINUS_ONE(check, "setValue name", MyTransaction); - - check = MyOperation->setValue(GROUP_ALLOW_READ, (char*)&allowRead); - CHECK_MINUS_ONE(check, "setValue allowRead", MyTransaction); - - check = MyOperation->setValue(GROUP_ALLOW_INSERT, (char*)&allowInsert); - CHECK_MINUS_ONE(check, "setValue allowInsert", MyTransaction); - - check = MyOperation->setValue(GROUP_ALLOW_DELETE, (char*)&allowDelete); - CHECK_MINUS_ONE(check, "setValue allowDelete", MyTransaction); - - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "commit", MyTransaction); - - pNDB->closeTransaction(MyTransaction); - return 0; -} - diff --git a/ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction.cpp b/ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction.cpp deleted file mode 100644 index 182f1f99586..00000000000 --- a/ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction.cpp +++ /dev/null @@ -1,825 +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 */ - -//#define DEBUG_ON - -extern "C" { -#include "user_transaction.h" -}; - -#include "macros.h" -#include "ndb_schema.hpp" -#include "ndb_error.hpp" - -#include -#include - -/** - * Transaction 1 - T1 - * - * Update location and changed by/time on a subscriber - * - * Input: - * SubscriberNumber, - * Location, - * ChangedBy, - * ChangedTime - * - * Output: - */ -int -T1(void * obj, - const SubscriberNumber number, - const Location new_location, - const ChangedBy changed_by, - const ChangedTime changed_time, - BenchmarkTime * transaction_time){ - - Ndb * pNDB = (Ndb *) obj; - - BenchmarkTime start; - get_time(&start); - - int check; - NdbRecAttr * check2; - - NdbConnection * MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("T1: startTranscation", pNDB->getNdbErrorString(), 0); - - NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction); - - check = MyOperation->updateTuple(); - CHECK_MINUS_ONE(check, "T1: updateTuple", - MyTransaction); - - check = MyOperation->equal(SUBSCRIBER_NUMBER, - number); - CHECK_MINUS_ONE(check, "T1: equal subscriber", - MyTransaction); - - check = MyOperation->setValue(SUBSCRIBER_LOCATION, - (char *)&new_location); - CHECK_MINUS_ONE(check, "T1: setValue location", - MyTransaction); - - check = MyOperation->setValue(SUBSCRIBER_CHANGED_BY, - changed_by); - CHECK_MINUS_ONE(check, "T1: setValue changed_by", - MyTransaction); - - check = MyOperation->setValue(SUBSCRIBER_CHANGED_TIME, - changed_time); - CHECK_MINUS_ONE(check, "T1: setValue changed_time", - MyTransaction); - - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T1: Commit", - MyTransaction); - - pNDB->closeTransaction(MyTransaction); - - get_time(transaction_time); - time_diff(transaction_time, &start); - return 0; -} - -/** - * Transaction 2 - T2 - * - * Read from Subscriber: - * - * Input: - * SubscriberNumber - * - * Output: - * Location - * Changed by - * Changed Timestamp - * Name - */ -int -T2(void * obj, - const SubscriberNumber number, - Location * readLocation, - ChangedBy changed_by, - ChangedTime changed_time, - SubscriberName subscriberName, - BenchmarkTime * transaction_time){ - - Ndb * pNDB = (Ndb *) obj; - - BenchmarkTime start; - get_time(&start); - - int check; - NdbRecAttr * check2; - - NdbConnection * MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("T2: startTranscation", pNDB->getNdbErrorString(), 0); - - NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T2: getNdbOperation", - MyTransaction); - - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T2: readTuple", - MyTransaction); - - check = MyOperation->equal(SUBSCRIBER_NUMBER, - number); - CHECK_MINUS_ONE(check, "T2: equal subscriber", - MyTransaction); - - check2 = MyOperation->getValue(SUBSCRIBER_LOCATION, - (char *)readLocation); - CHECK_NULL(check2, "T2: getValue location", - MyTransaction); - - check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_BY, - changed_by); - CHECK_NULL(check2, "T2: getValue changed_by", - MyTransaction); - - check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_TIME, - changed_time); - CHECK_NULL(check2, "T2: getValue changed_time", - MyTransaction); - - check2 = MyOperation->getValue(SUBSCRIBER_NAME, - subscriberName); - CHECK_NULL(check2, "T2: getValue name", - MyTransaction); - - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T2: Commit", - MyTransaction); - - pNDB->closeTransaction(MyTransaction); - - get_time(transaction_time); - time_diff(transaction_time, &start); - return 0; -} - -/** - * Transaction 3 - T3 - * - * Read session details - * - * Input: - * SubscriberNumber - * ServerId - * ServerBit - * - * Output: - * BranchExecuted - * SessionDetails - * ChangedBy - * ChangedTime - * Location - */ -int -T3(void * obj, - const SubscriberNumber inNumber, - const SubscriberSuffix inSuffix, - const ServerId inServerId, - const ServerBit inServerBit, - SessionDetails outSessionDetails, - ChangedBy outChangedBy, - ChangedTime outChangedTime, - Location * outLocation, - BranchExecuted * outBranchExecuted, - BenchmarkTime * outTransactionTime){ - - Ndb * pNDB = (Ndb *) obj; - - GroupId groupId; - ActiveSessions sessions; - Permission permission; - - BenchmarkTime start; - get_time(&start); - - int check; - NdbRecAttr * check2; - - NdbConnection * MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("T3-1: startTranscation", pNDB->getNdbErrorString(), 0); - - NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T3-1: getNdbOperation", - MyTransaction); - - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T3-1: readTuple", - MyTransaction); - - check = MyOperation->equal(SUBSCRIBER_NUMBER, - inNumber); - CHECK_MINUS_ONE(check, "T3-1: equal subscriber", - MyTransaction); - - check2 = MyOperation->getValue(SUBSCRIBER_LOCATION, - (char *)outLocation); - CHECK_NULL(check2, "T3-1: getValue location", - MyTransaction); - - check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_BY, - outChangedBy); - CHECK_NULL(check2, "T3-1: getValue changed_by", - MyTransaction); - - check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_TIME, - outChangedTime); - CHECK_NULL(check2, "T3-1: getValue changed_time", - MyTransaction); - - check2 = MyOperation->getValue(SUBSCRIBER_GROUP, - (char *)&groupId); - CHECK_NULL(check2, "T3-1: getValue group", - MyTransaction); - - check2 = MyOperation->getValue(SUBSCRIBER_SESSIONS, - (char *)&sessions); - CHECK_NULL(check2, "T3-1: getValue sessions", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T3-1: NoCommit", - MyTransaction); - - /* Operation 2 */ - - MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); - CHECK_NULL(MyOperation, "T3-2: getNdbOperation", - MyTransaction); - - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T3-2: readTuple", - MyTransaction); - - check = MyOperation->equal(GROUP_ID, - (char*)&groupId); - CHECK_MINUS_ONE(check, "T3-2: equal group", - MyTransaction); - - check2 = MyOperation->getValue(GROUP_ALLOW_READ, - (char *)&permission); - CHECK_NULL(check2, "T3-2: getValue allow_read", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T3-2: NoCommit", - MyTransaction); - - DEBUG3("T3(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); - - if(((permission & inServerBit) == inServerBit) && - ((sessions & inServerBit) == inServerBit)){ - - DEBUG("reading - "); - - /* Operation 3 */ - - MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); - CHECK_NULL(MyOperation, "T3-3: getNdbOperation", - MyTransaction); - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T3-3: readTuple", - MyTransaction); - - check = MyOperation->equal(SESSION_SUBSCRIBER, - (char*)inNumber); - CHECK_MINUS_ONE(check, "T3-3: equal number", - MyTransaction); - - check = MyOperation->equal(SESSION_SERVER, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T3-3: equal server id", - MyTransaction); - - check2 = MyOperation->getValue(SESSION_DATA, - (char *)outSessionDetails); - CHECK_NULL(check2, "T3-3: getValue session details", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T3-3: NoCommit", - MyTransaction); - - /* Operation 4 */ - - MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); - CHECK_NULL(MyOperation, "T3-4: getNdbOperation", - MyTransaction); - - check = MyOperation->interpretedUpdateTuple(); - CHECK_MINUS_ONE(check, "T3-4: interpretedUpdateTuple", - MyTransaction); - - check = MyOperation->equal(SERVER_ID, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T3-4: equal serverId", - MyTransaction); - - check = MyOperation->equal(SERVER_SUBSCRIBER_SUFFIX, - (char*)inSuffix); - CHECK_MINUS_ONE(check, "T3-4: equal suffix", - MyTransaction); - - check = MyOperation->incValue(SERVER_READS, (uint32)1); - CHECK_MINUS_ONE(check, "T3-4: inc value", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T3-4: NoCommit", - MyTransaction); - - (* outBranchExecuted) = 1; - } else { - (* outBranchExecuted) = 0; - } - DEBUG("commit\n"); - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T3: Commit", - MyTransaction); - - pNDB->closeTransaction(MyTransaction); - - get_time(outTransactionTime); - time_diff(outTransactionTime, &start); - return 0; -} - - -/** - * Transaction 4 - T4 - * - * Create session - * - * Input: - * SubscriberNumber - * ServerId - * ServerBit - * SessionDetails, - * DoRollback - * Output: - * ChangedBy - * ChangedTime - * Location - * BranchExecuted - */ -int -T4(void * obj, - const SubscriberNumber inNumber, - const SubscriberSuffix inSuffix, - const ServerId inServerId, - const ServerBit inServerBit, - const SessionDetails inSessionDetails, - ChangedBy outChangedBy, - ChangedTime outChangedTime, - Location * outLocation, - DoRollback inDoRollback, - BranchExecuted * outBranchExecuted, - BenchmarkTime * outTransactionTime){ - - Ndb * pNDB = (Ndb *) obj; - - GroupId groupId; - ActiveSessions sessions; - Permission permission; - - BenchmarkTime start; - get_time(&start); - - int check; - NdbRecAttr * check2; - - NdbConnection * MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("T4-1: startTranscation", pNDB->getNdbErrorString(), 0); - - DEBUG3("T4(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); - - NdbOperation * MyOperation = 0; - - MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T4-1: getNdbOperation", - MyTransaction); - - check = MyOperation->readTupleExclusive(); - CHECK_MINUS_ONE(check, "T4-1: readTuple", - MyTransaction); - - check = MyOperation->equal(SUBSCRIBER_NUMBER, - inNumber); - CHECK_MINUS_ONE(check, "T4-1: equal subscriber", - MyTransaction); - - check2 = MyOperation->getValue(SUBSCRIBER_LOCATION, - (char *)outLocation); - CHECK_NULL(check2, "T4-1: getValue location", - MyTransaction); - - check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_BY, - outChangedBy); - CHECK_NULL(check2, "T4-1: getValue changed_by", - MyTransaction); - - check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_TIME, - outChangedTime); - CHECK_NULL(check2, "T4-1: getValue changed_time", - MyTransaction); - - check2 = MyOperation->getValue(SUBSCRIBER_GROUP, - (char *)&groupId); - CHECK_NULL(check2, "T4-1: getValue group", - MyTransaction); - - check2 = MyOperation->getValue(SUBSCRIBER_SESSIONS, - (char *)&sessions); - CHECK_NULL(check2, "T4-1: getValue sessions", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T4-1: NoCommit", - MyTransaction); - - /* Operation 2 */ - MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); - CHECK_NULL(MyOperation, "T4-2: getNdbOperation", - MyTransaction); - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T4-2: readTuple", - MyTransaction); - - check = MyOperation->equal(GROUP_ID, - (char*)&groupId); - CHECK_MINUS_ONE(check, "T4-2: equal group", - MyTransaction); - - check2 = MyOperation->getValue(GROUP_ALLOW_INSERT, - (char *)&permission); - CHECK_NULL(check2, "T4-2: getValue allow_insert", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T4-2: NoCommit", - MyTransaction); - - if(((permission & inServerBit) == inServerBit) && - ((sessions & inServerBit) == 0)){ - - DEBUG("inserting - "); - - /* Operation 3 */ - MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); - CHECK_NULL(MyOperation, "T4-3: getNdbOperation", - MyTransaction); - - check = MyOperation->insertTuple(); - CHECK_MINUS_ONE(check, "T4-3: insertTuple", - MyTransaction); - - check = MyOperation->equal(SESSION_SUBSCRIBER, - (char*)inNumber); - CHECK_MINUS_ONE(check, "T4-3: equal number", - MyTransaction); - - check = MyOperation->equal(SESSION_SERVER, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T4-3: equal server id", - MyTransaction); - - check = MyOperation->setValue(SESSION_DATA, - (char *)inSessionDetails); - CHECK_MINUS_ONE(check, "T4-3: setValue session details", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T4-3: NoCommit", - MyTransaction); - - /* Operation 4 */ - MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T4-4: getNdbOperation", - MyTransaction); - - check = MyOperation->interpretedUpdateTuple(); - CHECK_MINUS_ONE(check, "T4-4: interpretedUpdateTuple", - MyTransaction); - - check = MyOperation->equal(SUBSCRIBER_NUMBER, - (char*)inNumber); - CHECK_MINUS_ONE(check, "T4-4: equal number", - MyTransaction); - - check = MyOperation->incValue(SUBSCRIBER_SESSIONS, - (uint32)inServerBit); - CHECK_MINUS_ONE(check, "T4-4: inc value", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T4-4: NoCommit", - MyTransaction); - - /* Operation 5 */ - MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); - CHECK_NULL(MyOperation, "T4-5: getNdbOperation", - MyTransaction); - - check = MyOperation->interpretedUpdateTuple(); - CHECK_MINUS_ONE(check, "T4-5: interpretedUpdateTuple", - MyTransaction); - - check = MyOperation->equal(SERVER_ID, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T4-5: equal serverId", - MyTransaction); - - check = MyOperation->equal(SERVER_SUBSCRIBER_SUFFIX, - (char*)inSuffix); - CHECK_MINUS_ONE(check, "T4-5: equal suffix", - MyTransaction); - - check = MyOperation->incValue(SERVER_INSERTS, (uint32)1); - CHECK_MINUS_ONE(check, "T4-5: inc value", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T4-5: NoCommit", - MyTransaction); - - (* outBranchExecuted) = 1; - } else { - DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); - DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); - (* outBranchExecuted) = 0; - } - - if(!inDoRollback){ - DEBUG("commit\n"); - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T4: Commit", - MyTransaction); - } else { - DEBUG("rollback\n"); - check = MyTransaction->execute(Rollback); - CHECK_MINUS_ONE(check, "T4:Rollback", - MyTransaction); - - } - - pNDB->closeTransaction(MyTransaction); - - get_time(outTransactionTime); - time_diff(outTransactionTime, &start); - return 0; -} - - -/** - * Transaction 5 - T5 - * - * Delete session - * - * Input: - * SubscriberNumber - * ServerId - * ServerBit - * DoRollback - * Output: - * ChangedBy - * ChangedTime - * Location - * BranchExecuted - */ -int -T5(void * obj, - const SubscriberNumber inNumber, - const SubscriberSuffix inSuffix, - const ServerId inServerId, - const ServerBit inServerBit, - ChangedBy outChangedBy, - ChangedTime outChangedTime, - Location * outLocation, - DoRollback inDoRollback, - BranchExecuted * outBranchExecuted, - BenchmarkTime * outTransactionTime){ - - Ndb * pNDB = (Ndb *) obj; - NdbConnection * MyTransaction = 0; - NdbOperation * MyOperation = 0; - - GroupId groupId; - ActiveSessions sessions; - Permission permission; - - BenchmarkTime start; - get_time(&start); - - int check; - NdbRecAttr * check2; - - MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), 0); - - MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T5-1: getNdbOperation", - MyTransaction); - - - check = MyOperation->readTupleExclusive(); - CHECK_MINUS_ONE(check, "T5-1: readTuple", - MyTransaction); - - check = MyOperation->equal(SUBSCRIBER_NUMBER, - inNumber); - CHECK_MINUS_ONE(check, "T5-1: equal subscriber", - MyTransaction); - - check2 = MyOperation->getValue(SUBSCRIBER_LOCATION, - (char *)outLocation); - CHECK_NULL(check2, "T5-1: getValue location", - MyTransaction); - - check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_BY, - outChangedBy); - CHECK_NULL(check2, "T5-1: getValue changed_by", - MyTransaction); - - check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_TIME, - outChangedTime); - CHECK_NULL(check2, "T5-1: getValue changed_time", - MyTransaction); - - check2 = MyOperation->getValue(SUBSCRIBER_GROUP, - (char *)&groupId); - CHECK_NULL(check2, "T5-1: getValue group", - MyTransaction); - - check2 = MyOperation->getValue(SUBSCRIBER_SESSIONS, - (char *)&sessions); - CHECK_NULL(check2, "T5-1: getValue sessions", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T5-1: NoCommit", - MyTransaction); - - /* Operation 2 */ - - MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); - CHECK_NULL(MyOperation, "T5-2: getNdbOperation", - MyTransaction); - - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T5-2: readTuple", - MyTransaction); - - check = MyOperation->equal(GROUP_ID, - (char*)&groupId); - CHECK_MINUS_ONE(check, "T5-2: equal group", - MyTransaction); - - check2 = MyOperation->getValue(GROUP_ALLOW_DELETE, - (char *)&permission); - CHECK_NULL(check2, "T5-2: getValue allow_delete", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T5-2: NoCommit", - MyTransaction); - - DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); - - if(((permission & inServerBit) == inServerBit) && - ((sessions & inServerBit) == inServerBit)){ - - DEBUG("deleting - "); - - /* Operation 3 */ - MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); - CHECK_NULL(MyOperation, "T5-3: getNdbOperation", - MyTransaction); - - check = MyOperation->deleteTuple(); - CHECK_MINUS_ONE(check, "T5-3: deleteTuple", - MyTransaction); - - check = MyOperation->equal(SESSION_SUBSCRIBER, - (char*)inNumber); - CHECK_MINUS_ONE(check, "T5-3: equal number", - MyTransaction); - - check = MyOperation->equal(SESSION_SERVER, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T5-3: equal server id", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T5-3: NoCommit", - MyTransaction); - - /* Operation 4 */ - MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T5-4: getNdbOperation", - MyTransaction); - - check = MyOperation->interpretedUpdateTuple(); - CHECK_MINUS_ONE(check, "T5-4: interpretedUpdateTuple", - MyTransaction); - - check = MyOperation->equal(SUBSCRIBER_NUMBER, - (char*)inNumber); - CHECK_MINUS_ONE(check, "T5-4: equal number", - MyTransaction); - - check = MyOperation->subValue(SUBSCRIBER_SESSIONS, - (uint32)inServerBit); - CHECK_MINUS_ONE(check, "T5-4: dec value", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T5-4: NoCommit", - MyTransaction); - - /* Operation 5 */ - MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); - CHECK_NULL(MyOperation, "T5-5: getNdbOperation", - MyTransaction); - - - check = MyOperation->interpretedUpdateTuple(); - CHECK_MINUS_ONE(check, "T5-5: interpretedUpdateTuple", - MyTransaction); - - check = MyOperation->equal(SERVER_ID, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T5-5: equal serverId", - MyTransaction); - - check = MyOperation->equal(SERVER_SUBSCRIBER_SUFFIX, - (char*)inSuffix); - CHECK_MINUS_ONE(check, "T5-5: equal suffix", - MyTransaction); - - check = MyOperation->incValue(SERVER_DELETES, (uint32)1); - CHECK_MINUS_ONE(check, "T5-5: inc value", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T5-5: NoCommit", - MyTransaction); - - (* outBranchExecuted) = 1; - } else { - DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); - DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); - (* outBranchExecuted) = 0; - } - - if(!inDoRollback){ - DEBUG("commit\n"); - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T5: Commit", - MyTransaction); - } else { - DEBUG("rollback\n"); - check = MyTransaction->execute(Rollback); - CHECK_MINUS_ONE(check, "T5:Rollback", - MyTransaction); - - } - - pNDB->closeTransaction(MyTransaction); - - get_time(outTransactionTime); - time_diff(outTransactionTime, &start); - return 0; -} - diff --git a/ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction2.cpp b/ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction2.cpp deleted file mode 100644 index df3c7a7989e..00000000000 --- a/ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction2.cpp +++ /dev/null @@ -1,825 +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 */ - -//#define DEBUG_ON - -extern "C" { -#include "user_transaction.h" -}; - -#include "macros.h" -#include "ndb_schema.hpp" -#include "ndb_error.hpp" - -#include -#include - -/** - * Transaction 1 - T1 - * - * Update location and changed by/time on a subscriber - * - * Input: - * SubscriberNumber, - * Location, - * ChangedBy, - * ChangedTime - * - * Output: - */ -int -T1(void * obj, - const SubscriberNumber number, - const Location new_location, - const ChangedBy changed_by, - const ChangedTime changed_time, - BenchmarkTime * transaction_time){ - - Ndb * pNDB = (Ndb *) obj; - - BenchmarkTime start; - get_time(&start); - - int check; - NdbRecAttr * check2; - - NdbConnection * MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("T1: startTranscation", pNDB->getNdbErrorString(), 0); - - NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction); - - check = MyOperation->updateTuple(); - CHECK_MINUS_ONE(check, "T1: updateTuple", - MyTransaction); - - check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, - number); - CHECK_MINUS_ONE(check, "T1: equal subscriber", - MyTransaction); - - check = MyOperation->setValue(IND_SUBSCRIBER_LOCATION, - (char *)&new_location); - CHECK_MINUS_ONE(check, "T1: setValue location", - MyTransaction); - - check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_BY, - changed_by); - CHECK_MINUS_ONE(check, "T1: setValue changed_by", - MyTransaction); - - check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_TIME, - changed_time); - CHECK_MINUS_ONE(check, "T1: setValue changed_time", - MyTransaction); - - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T1: Commit", - MyTransaction); - - pNDB->closeTransaction(MyTransaction); - - get_time(transaction_time); - time_diff(transaction_time, &start); - return 0; -} - -/** - * Transaction 2 - T2 - * - * Read from Subscriber: - * - * Input: - * SubscriberNumber - * - * Output: - * Location - * Changed by - * Changed Timestamp - * Name - */ -int -T2(void * obj, - const SubscriberNumber number, - Location * readLocation, - ChangedBy changed_by, - ChangedTime changed_time, - SubscriberName subscriberName, - BenchmarkTime * transaction_time){ - - Ndb * pNDB = (Ndb *) obj; - - BenchmarkTime start; - get_time(&start); - - int check; - NdbRecAttr * check2; - - NdbConnection * MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("T2: startTranscation", pNDB->getNdbErrorString(), 0); - - NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T2: getNdbOperation", - MyTransaction); - - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T2: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, - number); - CHECK_MINUS_ONE(check, "T2: equal subscriber", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, - (char *)readLocation); - CHECK_NULL(check2, "T2: getValue location", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, - changed_by); - CHECK_NULL(check2, "T2: getValue changed_by", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, - changed_time); - CHECK_NULL(check2, "T2: getValue changed_time", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_NAME, - subscriberName); - CHECK_NULL(check2, "T2: getValue name", - MyTransaction); - - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T2: Commit", - MyTransaction); - - pNDB->closeTransaction(MyTransaction); - - get_time(transaction_time); - time_diff(transaction_time, &start); - return 0; -} - -/** - * Transaction 3 - T3 - * - * Read session details - * - * Input: - * SubscriberNumber - * ServerId - * ServerBit - * - * Output: - * BranchExecuted - * SessionDetails - * ChangedBy - * ChangedTime - * Location - */ -int -T3(void * obj, - const SubscriberNumber inNumber, - const SubscriberSuffix inSuffix, - const ServerId inServerId, - const ServerBit inServerBit, - SessionDetails outSessionDetails, - ChangedBy outChangedBy, - ChangedTime outChangedTime, - Location * outLocation, - BranchExecuted * outBranchExecuted, - BenchmarkTime * outTransactionTime){ - - Ndb * pNDB = (Ndb *) obj; - - GroupId groupId; - ActiveSessions sessions; - Permission permission; - - BenchmarkTime start; - get_time(&start); - - int check; - NdbRecAttr * check2; - - NdbConnection * MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("T3-1: startTranscation", pNDB->getNdbErrorString(), 0); - - NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T3-1: getNdbOperation", - MyTransaction); - - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T3-1: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, - inNumber); - CHECK_MINUS_ONE(check, "T3-1: equal subscriber", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, - (char *)outLocation); - CHECK_NULL(check2, "T3-1: getValue location", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, - outChangedBy); - CHECK_NULL(check2, "T3-1: getValue changed_by", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, - outChangedTime); - CHECK_NULL(check2, "T3-1: getValue changed_time", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, - (char *)&groupId); - CHECK_NULL(check2, "T3-1: getValue group", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, - (char *)&sessions); - CHECK_NULL(check2, "T3-1: getValue sessions", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T3-1: NoCommit", - MyTransaction); - - /* Operation 2 */ - - MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); - CHECK_NULL(MyOperation, "T3-2: getNdbOperation", - MyTransaction); - - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T3-2: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_GROUP_ID, - (char*)&groupId); - CHECK_MINUS_ONE(check, "T3-2: equal group", - MyTransaction); - - check2 = MyOperation->getValue(IND_GROUP_ALLOW_READ, - (char *)&permission); - CHECK_NULL(check2, "T3-2: getValue allow_read", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T3-2: NoCommit", - MyTransaction); - - DEBUG3("T3(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); - - if(((permission & inServerBit) == inServerBit) && - ((sessions & inServerBit) == inServerBit)){ - - DEBUG("reading - "); - - /* Operation 3 */ - - MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); - CHECK_NULL(MyOperation, "T3-3: getNdbOperation", - MyTransaction); - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T3-3: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_SESSION_SUBSCRIBER, - (char*)inNumber); - CHECK_MINUS_ONE(check, "T3-3: equal number", - MyTransaction); - - check = MyOperation->equal(IND_SESSION_SERVER, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T3-3: equal server id", - MyTransaction); - - check2 = MyOperation->getValue(IND_SESSION_DATA, - (char *)outSessionDetails); - CHECK_NULL(check2, "T3-3: getValue session details", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T3-3: NoCommit", - MyTransaction); - - /* Operation 4 */ - - MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); - CHECK_NULL(MyOperation, "T3-4: getNdbOperation", - MyTransaction); - - check = MyOperation->interpretedUpdateTuple(); - CHECK_MINUS_ONE(check, "T3-4: interpretedUpdateTuple", - MyTransaction); - - check = MyOperation->equal(IND_SERVER_ID, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T3-4: equal serverId", - MyTransaction); - - check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, - (char*)inSuffix); - CHECK_MINUS_ONE(check, "T3-4: equal suffix", - MyTransaction); - - check = MyOperation->incValue(IND_SERVER_READS, (uint32)1); - CHECK_MINUS_ONE(check, "T3-4: inc value", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T3-4: NoCommit", - MyTransaction); - - (* outBranchExecuted) = 1; - } else { - (* outBranchExecuted) = 0; - } - DEBUG("commit\n"); - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T3: Commit", - MyTransaction); - - pNDB->closeTransaction(MyTransaction); - - get_time(outTransactionTime); - time_diff(outTransactionTime, &start); - return 0; -} - - -/** - * Transaction 4 - T4 - * - * Create session - * - * Input: - * SubscriberNumber - * ServerId - * ServerBit - * SessionDetails, - * DoRollback - * Output: - * ChangedBy - * ChangedTime - * Location - * BranchExecuted - */ -int -T4(void * obj, - const SubscriberNumber inNumber, - const SubscriberSuffix inSuffix, - const ServerId inServerId, - const ServerBit inServerBit, - const SessionDetails inSessionDetails, - ChangedBy outChangedBy, - ChangedTime outChangedTime, - Location * outLocation, - DoRollback inDoRollback, - BranchExecuted * outBranchExecuted, - BenchmarkTime * outTransactionTime){ - - Ndb * pNDB = (Ndb *) obj; - - GroupId groupId; - ActiveSessions sessions; - Permission permission; - - BenchmarkTime start; - get_time(&start); - - int check; - NdbRecAttr * check2; - - NdbConnection * MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("T4-1: startTranscation", pNDB->getNdbErrorString(), 0); - - DEBUG3("T4(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); - - NdbOperation * MyOperation = 0; - - MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T4-1: getNdbOperation", - MyTransaction); - - check = MyOperation->readTupleExclusive(); - CHECK_MINUS_ONE(check, "T4-1: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, - inNumber); - CHECK_MINUS_ONE(check, "T4-1: equal subscriber", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, - (char *)outLocation); - CHECK_NULL(check2, "T4-1: getValue location", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, - outChangedBy); - CHECK_NULL(check2, "T4-1: getValue changed_by", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, - outChangedTime); - CHECK_NULL(check2, "T4-1: getValue changed_time", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, - (char *)&groupId); - CHECK_NULL(check2, "T4-1: getValue group", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, - (char *)&sessions); - CHECK_NULL(check2, "T4-1: getValue sessions", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T4-1: NoCommit", - MyTransaction); - - /* Operation 2 */ - MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); - CHECK_NULL(MyOperation, "T4-2: getNdbOperation", - MyTransaction); - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T4-2: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_GROUP_ID, - (char*)&groupId); - CHECK_MINUS_ONE(check, "T4-2: equal group", - MyTransaction); - - check2 = MyOperation->getValue(IND_GROUP_ALLOW_INSERT, - (char *)&permission); - CHECK_NULL(check2, "T4-2: getValue allow_insert", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T4-2: NoCommit", - MyTransaction); - - if(((permission & inServerBit) == inServerBit) && - ((sessions & inServerBit) == 0)){ - - DEBUG("inserting - "); - - /* Operation 3 */ - MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); - CHECK_NULL(MyOperation, "T4-3: getNdbOperation", - MyTransaction); - - check = MyOperation->insertTuple(); - CHECK_MINUS_ONE(check, "T4-3: insertTuple", - MyTransaction); - - check = MyOperation->equal(IND_SESSION_SUBSCRIBER, - (char*)inNumber); - CHECK_MINUS_ONE(check, "T4-3: equal number", - MyTransaction); - - check = MyOperation->equal(IND_SESSION_SERVER, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T4-3: equal server id", - MyTransaction); - - check = MyOperation->setValue(SESSION_DATA, - (char *)inSessionDetails); - CHECK_MINUS_ONE(check, "T4-3: setValue session details", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T4-3: NoCommit", - MyTransaction); - - /* Operation 4 */ - MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T4-4: getNdbOperation", - MyTransaction); - - check = MyOperation->interpretedUpdateTuple(); - CHECK_MINUS_ONE(check, "T4-4: interpretedUpdateTuple", - MyTransaction); - - check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, - (char*)inNumber); - CHECK_MINUS_ONE(check, "T4-4: equal number", - MyTransaction); - - check = MyOperation->incValue(IND_SUBSCRIBER_SESSIONS, - (uint32)inServerBit); - CHECK_MINUS_ONE(check, "T4-4: inc value", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T4-4: NoCommit", - MyTransaction); - - /* Operation 5 */ - MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); - CHECK_NULL(MyOperation, "T4-5: getNdbOperation", - MyTransaction); - - check = MyOperation->interpretedUpdateTuple(); - CHECK_MINUS_ONE(check, "T4-5: interpretedUpdateTuple", - MyTransaction); - - check = MyOperation->equal(IND_SERVER_ID, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T4-5: equal serverId", - MyTransaction); - - check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, - (char*)inSuffix); - CHECK_MINUS_ONE(check, "T4-5: equal suffix", - MyTransaction); - - check = MyOperation->incValue(IND_SERVER_INSERTS, (uint32)1); - CHECK_MINUS_ONE(check, "T4-5: inc value", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T4-5: NoCommit", - MyTransaction); - - (* outBranchExecuted) = 1; - } else { - DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); - DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); - (* outBranchExecuted) = 0; - } - - if(!inDoRollback){ - DEBUG("commit\n"); - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T4: Commit", - MyTransaction); - } else { - DEBUG("rollback\n"); - check = MyTransaction->execute(Rollback); - CHECK_MINUS_ONE(check, "T4:Rollback", - MyTransaction); - - } - - pNDB->closeTransaction(MyTransaction); - - get_time(outTransactionTime); - time_diff(outTransactionTime, &start); - return 0; -} - - -/** - * Transaction 5 - T5 - * - * Delete session - * - * Input: - * SubscriberNumber - * ServerId - * ServerBit - * DoRollback - * Output: - * ChangedBy - * ChangedTime - * Location - * BranchExecuted - */ -int -T5(void * obj, - const SubscriberNumber inNumber, - const SubscriberSuffix inSuffix, - const ServerId inServerId, - const ServerBit inServerBit, - ChangedBy outChangedBy, - ChangedTime outChangedTime, - Location * outLocation, - DoRollback inDoRollback, - BranchExecuted * outBranchExecuted, - BenchmarkTime * outTransactionTime){ - - Ndb * pNDB = (Ndb *) obj; - NdbConnection * MyTransaction = 0; - NdbOperation * MyOperation = 0; - - GroupId groupId; - ActiveSessions sessions; - Permission permission; - - BenchmarkTime start; - get_time(&start); - - int check; - NdbRecAttr * check2; - - MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), 0); - - MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T5-1: getNdbOperation", - MyTransaction); - - - check = MyOperation->readTupleExclusive(); - CHECK_MINUS_ONE(check, "T5-1: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, - inNumber); - CHECK_MINUS_ONE(check, "T5-1: equal subscriber", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, - (char *)outLocation); - CHECK_NULL(check2, "T5-1: getValue location", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, - outChangedBy); - CHECK_NULL(check2, "T5-1: getValue changed_by", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, - outChangedTime); - CHECK_NULL(check2, "T5-1: getValue changed_time", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, - (char *)&groupId); - CHECK_NULL(check2, "T5-1: getValue group", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, - (char *)&sessions); - CHECK_NULL(check2, "T5-1: getValue sessions", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T5-1: NoCommit", - MyTransaction); - - /* Operation 2 */ - - MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); - CHECK_NULL(MyOperation, "T5-2: getNdbOperation", - MyTransaction); - - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T5-2: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_GROUP_ID, - (char*)&groupId); - CHECK_MINUS_ONE(check, "T5-2: equal group", - MyTransaction); - - check2 = MyOperation->getValue(IND_GROUP_ALLOW_DELETE, - (char *)&permission); - CHECK_NULL(check2, "T5-2: getValue allow_delete", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T5-2: NoCommit", - MyTransaction); - - DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); - - if(((permission & inServerBit) == inServerBit) && - ((sessions & inServerBit) == inServerBit)){ - - DEBUG("deleting - "); - - /* Operation 3 */ - MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); - CHECK_NULL(MyOperation, "T5-3: getNdbOperation", - MyTransaction); - - check = MyOperation->deleteTuple(); - CHECK_MINUS_ONE(check, "T5-3: deleteTuple", - MyTransaction); - - check = MyOperation->equal(IND_SESSION_SUBSCRIBER, - (char*)inNumber); - CHECK_MINUS_ONE(check, "T5-3: equal number", - MyTransaction); - - check = MyOperation->equal(IND_SESSION_SERVER, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T5-3: equal server id", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T5-3: NoCommit", - MyTransaction); - - /* Operation 4 */ - MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T5-4: getNdbOperation", - MyTransaction); - - check = MyOperation->interpretedUpdateTuple(); - CHECK_MINUS_ONE(check, "T5-4: interpretedUpdateTuple", - MyTransaction); - - check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, - (char*)inNumber); - CHECK_MINUS_ONE(check, "T5-4: equal number", - MyTransaction); - - check = MyOperation->subValue(IND_SUBSCRIBER_SESSIONS, - (uint32)inServerBit); - CHECK_MINUS_ONE(check, "T5-4: dec value", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T5-4: NoCommit", - MyTransaction); - - /* Operation 5 */ - MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); - CHECK_NULL(MyOperation, "T5-5: getNdbOperation", - MyTransaction); - - - check = MyOperation->interpretedUpdateTuple(); - CHECK_MINUS_ONE(check, "T5-5: interpretedUpdateTuple", - MyTransaction); - - check = MyOperation->equal(IND_SERVER_ID, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T5-5: equal serverId", - MyTransaction); - - check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, - (char*)inSuffix); - CHECK_MINUS_ONE(check, "T5-5: equal suffix", - MyTransaction); - - check = MyOperation->incValue(IND_SERVER_DELETES, (uint32)1); - CHECK_MINUS_ONE(check, "T5-5: inc value", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T5-5: NoCommit", - MyTransaction); - - (* outBranchExecuted) = 1; - } else { - DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); - DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); - (* outBranchExecuted) = 0; - } - - if(!inDoRollback){ - DEBUG("commit\n"); - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T5: Commit", - MyTransaction); - } else { - DEBUG("rollback\n"); - check = MyTransaction->execute(Rollback); - CHECK_MINUS_ONE(check, "T5:Rollback", - MyTransaction); - - } - - pNDB->closeTransaction(MyTransaction); - - get_time(outTransactionTime); - time_diff(outTransactionTime, &start); - return 0; -} - diff --git a/ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction3.cpp b/ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction3.cpp deleted file mode 100644 index d2c92ecd424..00000000000 --- a/ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction3.cpp +++ /dev/null @@ -1,793 +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 */ - -//#define DEBUG_ON - -extern "C" { -#include "user_transaction.h" -}; - -#include "macros.h" -#include "ndb_schema.hpp" -#include "ndb_error.hpp" - -#include -#include - -/** - * Transaction 1 - T1 - * - * Update location and changed by/time on a subscriber - * - * Input: - * SubscriberNumber, - * Location, - * ChangedBy, - * ChangedTime - * - * Output: - */ -int -T1(void * obj, - const SubscriberNumber number, - const Location new_location, - const ChangedBy changed_by, - const ChangedTime changed_time, - BenchmarkTime * transaction_time){ - - Ndb * pNDB = (Ndb *) obj; - - BenchmarkTime start; - get_time(&start); - - int check; - NdbRecAttr * check2; - - NdbConnection * MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("T1: startTranscation", pNDB->getNdbErrorString(), 0); - - NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction); - - check = MyOperation->updateTuple(); - CHECK_MINUS_ONE(check, "T1: updateTuple", - MyTransaction); - - check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, - number); - CHECK_MINUS_ONE(check, "T1: equal subscriber", - MyTransaction); - - check = MyOperation->setValue(IND_SUBSCRIBER_LOCATION, - (char *)&new_location); - CHECK_MINUS_ONE(check, "T1: setValue location", - MyTransaction); - - check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_BY, - changed_by); - CHECK_MINUS_ONE(check, "T1: setValue changed_by", - MyTransaction); - - check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_TIME, - changed_time); - CHECK_MINUS_ONE(check, "T1: setValue changed_time", - MyTransaction); - - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T1: Commit", - MyTransaction); - - pNDB->closeTransaction(MyTransaction); - - get_time(transaction_time); - time_diff(transaction_time, &start); - return 0; -} - -/** - * Transaction 2 - T2 - * - * Read from Subscriber: - * - * Input: - * SubscriberNumber - * - * Output: - * Location - * Changed by - * Changed Timestamp - * Name - */ -int -T2(void * obj, - const SubscriberNumber number, - Location * readLocation, - ChangedBy changed_by, - ChangedTime changed_time, - SubscriberName subscriberName, - BenchmarkTime * transaction_time){ - - Ndb * pNDB = (Ndb *) obj; - - BenchmarkTime start; - get_time(&start); - - int check; - NdbRecAttr * check2; - - NdbConnection * MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("T2: startTranscation", pNDB->getNdbErrorString(), 0); - - NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T2: getNdbOperation", - MyTransaction); - - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T2: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, - number); - CHECK_MINUS_ONE(check, "T2: equal subscriber", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, - (char *)readLocation); - CHECK_NULL(check2, "T2: getValue location", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, - changed_by); - CHECK_NULL(check2, "T2: getValue changed_by", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, - changed_time); - CHECK_NULL(check2, "T2: getValue changed_time", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_NAME, - subscriberName); - CHECK_NULL(check2, "T2: getValue name", - MyTransaction); - - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T2: Commit", - MyTransaction); - - pNDB->closeTransaction(MyTransaction); - - get_time(transaction_time); - time_diff(transaction_time, &start); - return 0; -} - -/** - * Transaction 3 - T3 - * - * Read session details - * - * Input: - * SubscriberNumber - * ServerId - * ServerBit - * - * Output: - * BranchExecuted - * SessionDetails - * ChangedBy - * ChangedTime - * Location - */ -int -T3(void * obj, - const SubscriberNumber inNumber, - const SubscriberSuffix inSuffix, - const ServerId inServerId, - const ServerBit inServerBit, - SessionDetails outSessionDetails, - ChangedBy outChangedBy, - ChangedTime outChangedTime, - Location * outLocation, - BranchExecuted * outBranchExecuted, - BenchmarkTime * outTransactionTime){ - - Ndb * pNDB = (Ndb *) obj; - - GroupId groupId; - ActiveSessions sessions; - Permission permission; - - BenchmarkTime start; - get_time(&start); - - int check; - NdbRecAttr * check2; - - NdbConnection * MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("T3-1: startTranscation", pNDB->getNdbErrorString(), 0); - - NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T3-1: getNdbOperation", - MyTransaction); - - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T3-1: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, - inNumber); - CHECK_MINUS_ONE(check, "T3-1: equal subscriber", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, - (char *)outLocation); - CHECK_NULL(check2, "T3-1: getValue location", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, - outChangedBy); - CHECK_NULL(check2, "T3-1: getValue changed_by", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, - outChangedTime); - CHECK_NULL(check2, "T3-1: getValue changed_time", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, - (char *)&groupId); - CHECK_NULL(check2, "T3-1: getValue group", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, - (char *)&sessions); - CHECK_NULL(check2, "T3-1: getValue sessions", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T3-1: NoCommit", - MyTransaction); - - /* Operation 2 */ - - MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); - CHECK_NULL(MyOperation, "T3-2: getNdbOperation", - MyTransaction); - - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T3-2: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_GROUP_ID, - (char*)&groupId); - CHECK_MINUS_ONE(check, "T3-2: equal group", - MyTransaction); - - check2 = MyOperation->getValue(IND_GROUP_ALLOW_READ, - (char *)&permission); - CHECK_NULL(check2, "T3-2: getValue allow_read", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T3-2: NoCommit", - MyTransaction); - - DEBUG3("T3(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); - - if(((permission & inServerBit) == inServerBit) && - ((sessions & inServerBit) == inServerBit)){ - - DEBUG("reading - "); - - /* Operation 3 */ - - MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); - CHECK_NULL(MyOperation, "T3-3: getNdbOperation", - MyTransaction); - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T3-3: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_SESSION_SUBSCRIBER, - (char*)inNumber); - CHECK_MINUS_ONE(check, "T3-3: equal number", - MyTransaction); - - check = MyOperation->equal(IND_SESSION_SERVER, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T3-3: equal server id", - MyTransaction); - - check2 = MyOperation->getValue(IND_SESSION_DATA, - (char *)outSessionDetails); - CHECK_NULL(check2, "T3-3: getValue session details", - MyTransaction); - - /* Operation 4 */ - - MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); - CHECK_NULL(MyOperation, "T3-4: getNdbOperation", - MyTransaction); - - check = MyOperation->interpretedUpdateTuple(); - CHECK_MINUS_ONE(check, "T3-4: interpretedUpdateTuple", - MyTransaction); - - check = MyOperation->equal(IND_SERVER_ID, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T3-4: equal serverId", - MyTransaction); - - check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, - (char*)inSuffix); - CHECK_MINUS_ONE(check, "T3-4: equal suffix", - MyTransaction); - - check = MyOperation->incValue(IND_SERVER_READS, (uint32)1); - CHECK_MINUS_ONE(check, "T3-4: inc value", - MyTransaction); - - (* outBranchExecuted) = 1; - } else { - (* outBranchExecuted) = 0; - } - DEBUG("commit\n"); - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T3: Commit", - MyTransaction); - - pNDB->closeTransaction(MyTransaction); - - get_time(outTransactionTime); - time_diff(outTransactionTime, &start); - return 0; -} - - -/** - * Transaction 4 - T4 - * - * Create session - * - * Input: - * SubscriberNumber - * ServerId - * ServerBit - * SessionDetails, - * DoRollback - * Output: - * ChangedBy - * ChangedTime - * Location - * BranchExecuted - */ -int -T4(void * obj, - const SubscriberNumber inNumber, - const SubscriberSuffix inSuffix, - const ServerId inServerId, - const ServerBit inServerBit, - const SessionDetails inSessionDetails, - ChangedBy outChangedBy, - ChangedTime outChangedTime, - Location * outLocation, - DoRollback inDoRollback, - BranchExecuted * outBranchExecuted, - BenchmarkTime * outTransactionTime){ - - Ndb * pNDB = (Ndb *) obj; - - GroupId groupId; - ActiveSessions sessions; - Permission permission; - - BenchmarkTime start; - get_time(&start); - - int check; - NdbRecAttr * check2; - - NdbConnection * MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("T4-1: startTranscation", pNDB->getNdbErrorString(), 0); - - DEBUG3("T4(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); - - NdbOperation * MyOperation = 0; - - MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T4-1: getNdbOperation", - MyTransaction); - - check = MyOperation->readTupleExclusive(); - CHECK_MINUS_ONE(check, "T4-1: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, - inNumber); - CHECK_MINUS_ONE(check, "T4-1: equal subscriber", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, - (char *)outLocation); - CHECK_NULL(check2, "T4-1: getValue location", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, - outChangedBy); - CHECK_NULL(check2, "T4-1: getValue changed_by", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, - outChangedTime); - CHECK_NULL(check2, "T4-1: getValue changed_time", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, - (char *)&groupId); - CHECK_NULL(check2, "T4-1: getValue group", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, - (char *)&sessions); - CHECK_NULL(check2, "T4-1: getValue sessions", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T4-1: NoCommit", - MyTransaction); - - /* Operation 2 */ - MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); - CHECK_NULL(MyOperation, "T4-2: getNdbOperation", - MyTransaction); - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T4-2: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_GROUP_ID, - (char*)&groupId); - CHECK_MINUS_ONE(check, "T4-2: equal group", - MyTransaction); - - check2 = MyOperation->getValue(IND_GROUP_ALLOW_INSERT, - (char *)&permission); - CHECK_NULL(check2, "T4-2: getValue allow_insert", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T4-2: NoCommit", - MyTransaction); - - if(((permission & inServerBit) == inServerBit) && - ((sessions & inServerBit) == 0)){ - - DEBUG("inserting - "); - - /* Operation 3 */ - MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); - CHECK_NULL(MyOperation, "T4-3: getNdbOperation", - MyTransaction); - - check = MyOperation->insertTuple(); - CHECK_MINUS_ONE(check, "T4-3: insertTuple", - MyTransaction); - - check = MyOperation->equal(IND_SESSION_SUBSCRIBER, - (char*)inNumber); - CHECK_MINUS_ONE(check, "T4-3: equal number", - MyTransaction); - - check = MyOperation->equal(IND_SESSION_SERVER, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T4-3: equal server id", - MyTransaction); - - check = MyOperation->setValue(SESSION_DATA, - (char *)inSessionDetails); - CHECK_MINUS_ONE(check, "T4-3: setValue session details", - MyTransaction); - - /* Operation 4 */ - MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T4-4: getNdbOperation", - MyTransaction); - - check = MyOperation->interpretedUpdateTuple(); - CHECK_MINUS_ONE(check, "T4-4: interpretedUpdateTuple", - MyTransaction); - - check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, - (char*)inNumber); - CHECK_MINUS_ONE(check, "T4-4: equal number", - MyTransaction); - - check = MyOperation->incValue(IND_SUBSCRIBER_SESSIONS, - (uint32)inServerBit); - CHECK_MINUS_ONE(check, "T4-4: inc value", - MyTransaction); - - /* Operation 5 */ - MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); - CHECK_NULL(MyOperation, "T4-5: getNdbOperation", - MyTransaction); - - check = MyOperation->interpretedUpdateTuple(); - CHECK_MINUS_ONE(check, "T4-5: interpretedUpdateTuple", - MyTransaction); - - check = MyOperation->equal(IND_SERVER_ID, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T4-5: equal serverId", - MyTransaction); - - check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, - (char*)inSuffix); - CHECK_MINUS_ONE(check, "T4-5: equal suffix", - MyTransaction); - - check = MyOperation->incValue(IND_SERVER_INSERTS, (uint32)1); - CHECK_MINUS_ONE(check, "T4-5: inc value", - MyTransaction); - - (* outBranchExecuted) = 1; - } else { - DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); - DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); - (* outBranchExecuted) = 0; - } - - if(!inDoRollback){ - DEBUG("commit\n"); - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T4: Commit", - MyTransaction); - } else { - DEBUG("rollback\n"); - check = MyTransaction->execute(Rollback); - CHECK_MINUS_ONE(check, "T4:Rollback", - MyTransaction); - - } - - pNDB->closeTransaction(MyTransaction); - - get_time(outTransactionTime); - time_diff(outTransactionTime, &start); - return 0; -} - - -/** - * Transaction 5 - T5 - * - * Delete session - * - * Input: - * SubscriberNumber - * ServerId - * ServerBit - * DoRollback - * Output: - * ChangedBy - * ChangedTime - * Location - * BranchExecuted - */ -int -T5(void * obj, - const SubscriberNumber inNumber, - const SubscriberSuffix inSuffix, - const ServerId inServerId, - const ServerBit inServerBit, - ChangedBy outChangedBy, - ChangedTime outChangedTime, - Location * outLocation, - DoRollback inDoRollback, - BranchExecuted * outBranchExecuted, - BenchmarkTime * outTransactionTime){ - - Ndb * pNDB = (Ndb *) obj; - NdbConnection * MyTransaction = 0; - NdbOperation * MyOperation = 0; - - GroupId groupId; - ActiveSessions sessions; - Permission permission; - - BenchmarkTime start; - get_time(&start); - - int check; - NdbRecAttr * check2; - - MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), 0); - - MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T5-1: getNdbOperation", - MyTransaction); - - - check = MyOperation->readTupleExclusive(); - CHECK_MINUS_ONE(check, "T5-1: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, - inNumber); - CHECK_MINUS_ONE(check, "T5-1: equal subscriber", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, - (char *)outLocation); - CHECK_NULL(check2, "T5-1: getValue location", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, - outChangedBy); - CHECK_NULL(check2, "T5-1: getValue changed_by", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, - outChangedTime); - CHECK_NULL(check2, "T5-1: getValue changed_time", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, - (char *)&groupId); - CHECK_NULL(check2, "T5-1: getValue group", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, - (char *)&sessions); - CHECK_NULL(check2, "T5-1: getValue sessions", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T5-1: NoCommit", - MyTransaction); - - /* Operation 2 */ - - MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); - CHECK_NULL(MyOperation, "T5-2: getNdbOperation", - MyTransaction); - - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T5-2: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_GROUP_ID, - (char*)&groupId); - CHECK_MINUS_ONE(check, "T5-2: equal group", - MyTransaction); - - check2 = MyOperation->getValue(IND_GROUP_ALLOW_DELETE, - (char *)&permission); - CHECK_NULL(check2, "T5-2: getValue allow_delete", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T5-2: NoCommit", - MyTransaction); - - DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); - - if(((permission & inServerBit) == inServerBit) && - ((sessions & inServerBit) == inServerBit)){ - - DEBUG("deleting - "); - - /* Operation 3 */ - MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); - CHECK_NULL(MyOperation, "T5-3: getNdbOperation", - MyTransaction); - - check = MyOperation->deleteTuple(); - CHECK_MINUS_ONE(check, "T5-3: deleteTuple", - MyTransaction); - - check = MyOperation->equal(IND_SESSION_SUBSCRIBER, - (char*)inNumber); - CHECK_MINUS_ONE(check, "T5-3: equal number", - MyTransaction); - - check = MyOperation->equal(IND_SESSION_SERVER, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T5-3: equal server id", - MyTransaction); - - /* Operation 4 */ - MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T5-4: getNdbOperation", - MyTransaction); - - check = MyOperation->interpretedUpdateTuple(); - CHECK_MINUS_ONE(check, "T5-4: interpretedUpdateTuple", - MyTransaction); - - check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, - (char*)inNumber); - CHECK_MINUS_ONE(check, "T5-4: equal number", - MyTransaction); - - check = MyOperation->subValue(IND_SUBSCRIBER_SESSIONS, - (uint32)inServerBit); - CHECK_MINUS_ONE(check, "T5-4: dec value", - MyTransaction); - - /* Operation 5 */ - MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); - CHECK_NULL(MyOperation, "T5-5: getNdbOperation", - MyTransaction); - - - check = MyOperation->interpretedUpdateTuple(); - CHECK_MINUS_ONE(check, "T5-5: interpretedUpdateTuple", - MyTransaction); - - check = MyOperation->equal(IND_SERVER_ID, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T5-5: equal serverId", - MyTransaction); - - check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, - (char*)inSuffix); - CHECK_MINUS_ONE(check, "T5-5: equal suffix", - MyTransaction); - - check = MyOperation->incValue(IND_SERVER_DELETES, (uint32)1); - CHECK_MINUS_ONE(check, "T5-5: inc value", - MyTransaction); - - (* outBranchExecuted) = 1; - } else { - DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); - DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); - (* outBranchExecuted) = 0; - } - - if(!inDoRollback){ - DEBUG("commit\n"); - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T5: Commit", - MyTransaction); - } else { - DEBUG("rollback\n"); - check = MyTransaction->execute(Rollback); - CHECK_MINUS_ONE(check, "T5:Rollback", - MyTransaction); - - } - - pNDB->closeTransaction(MyTransaction); - - get_time(outTransactionTime); - time_diff(outTransactionTime, &start); - return 0; -} - diff --git a/ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction4.cpp b/ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction4.cpp deleted file mode 100644 index e652c7bfed8..00000000000 --- a/ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction4.cpp +++ /dev/null @@ -1,770 +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 */ - -//#define DEBUG_ON - -extern "C" { -#include "user_transaction.h" -}; - -#include "macros.h" -#include "ndb_schema.hpp" -#include "ndb_error.hpp" - -#include -#include - -/** - * Transaction 1 - T1 - * - * Update location and changed by/time on a subscriber - * - * Input: - * SubscriberNumber, - * Location, - * ChangedBy, - * ChangedTime - * - * Output: - */ -int -T1(void * obj, - const SubscriberNumber number, - const Location new_location, - const ChangedBy changed_by, - const ChangedTime changed_time, - BenchmarkTime * transaction_time){ - - Ndb * pNDB = (Ndb *) obj; - - DEBUG2("T1(%.*s):\n", SUBSCRIBER_NUMBER_LENGTH, number); - - BenchmarkTime start; - get_time(&start); - - int check; - NdbRecAttr * check2; - - NdbConnection * MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("T1-1: startTranscation", pNDB->getNdbErrorString(), 0); - - NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction); - - check = MyOperation->updateTuple(); - CHECK_MINUS_ONE(check, "T1: updateTuple", - MyTransaction); - - check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, - number); - CHECK_MINUS_ONE(check, "T1: equal subscriber", - MyTransaction); - - check = MyOperation->setValue(IND_SUBSCRIBER_LOCATION, - (char *)&new_location); - CHECK_MINUS_ONE(check, "T1: setValue location", - MyTransaction); - - check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_BY, - changed_by); - CHECK_MINUS_ONE(check, "T1: setValue changed_by", - MyTransaction); - - check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_TIME, - changed_time); - CHECK_MINUS_ONE(check, "T1: setValue changed_time", - MyTransaction); - - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T1: Commit", - MyTransaction); - - pNDB->closeTransaction(MyTransaction); - - get_time(transaction_time); - time_diff(transaction_time, &start); - return 0; -} - -/** - * Transaction 2 - T2 - * - * Read from Subscriber: - * - * Input: - * SubscriberNumber - * - * Output: - * Location - * Changed by - * Changed Timestamp - * Name - */ -int -T2(void * obj, - const SubscriberNumber number, - Location * readLocation, - ChangedBy changed_by, - ChangedTime changed_time, - SubscriberName subscriberName, - BenchmarkTime * transaction_time){ - - Ndb * pNDB = (Ndb *) obj; - - DEBUG2("T2(%.*s):\n", SUBSCRIBER_NUMBER_LENGTH, number); - - BenchmarkTime start; - get_time(&start); - - int check; - NdbRecAttr * check2; - - NdbConnection * MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("T2-1: startTranscation", pNDB->getNdbErrorString(), 0); - - NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T2: getNdbOperation", - MyTransaction); - - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T2: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, - number); - CHECK_MINUS_ONE(check, "T2: equal subscriber", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, - (char *)readLocation); - CHECK_NULL(check2, "T2: getValue location", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, - changed_by); - CHECK_NULL(check2, "T2: getValue changed_by", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, - changed_time); - CHECK_NULL(check2, "T2: getValue changed_time", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_NAME, - subscriberName); - CHECK_NULL(check2, "T2: getValue name", - MyTransaction); - - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T2: Commit", - MyTransaction); - - pNDB->closeTransaction(MyTransaction); - - get_time(transaction_time); - time_diff(transaction_time, &start); - return 0; -} - -/** - * Transaction 3 - T3 - * - * Read session details - * - * Input: - * SubscriberNumber - * ServerId - * ServerBit - * - * Output: - * BranchExecuted - * SessionDetails - * ChangedBy - * ChangedTime - * Location - */ -int -T3(void * obj, - const SubscriberNumber inNumber, - const SubscriberSuffix inSuffix, - const ServerId inServerId, - const ServerBit inServerBit, - SessionDetails outSessionDetails, - ChangedBy outChangedBy, - ChangedTime outChangedTime, - Location * outLocation, - BranchExecuted * outBranchExecuted, - BenchmarkTime * outTransactionTime){ - - DEBUG3("T3(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); - - Ndb * pNDB = (Ndb *) obj; - - GroupId groupId; - ActiveSessions sessions; - Permission permission; - - BenchmarkTime start; - get_time(&start); - - int check; - NdbRecAttr * check2; - - NdbConnection * MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("T3-1: startTranscation", pNDB->getNdbErrorString(), 0); - - NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T3-1: getNdbOperation", - MyTransaction); - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T3-1: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, - inNumber); - CHECK_MINUS_ONE(check, "T3-1: equal subscriber", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, - (char *)outLocation); - CHECK_NULL(check2, "T3-1: getValue location", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, - outChangedBy); - CHECK_NULL(check2, "T3-1: getValue changed_by", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, - outChangedTime); - CHECK_NULL(check2, "T3-1: getValue changed_time", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, - (char *)&groupId); - CHECK_NULL(check2, "T3-1: getValue group", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, - (char *)&sessions); - CHECK_NULL(check2, "T3-1: getValue sessions", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T3-1: NoCommit", - MyTransaction); - - /* Operation 2 */ - - MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); - CHECK_NULL(MyOperation, "T3-2: getNdbOperation", - MyTransaction); - - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T3-2: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_GROUP_ID, - (char*)&groupId); - CHECK_MINUS_ONE(check, "T3-2: equal group", - MyTransaction); - - check2 = MyOperation->getValue(IND_GROUP_ALLOW_READ, - (char *)&permission); - CHECK_NULL(check2, "T3-2: getValue allow_read", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T3-2: NoCommit", - MyTransaction); - - if(((permission & inServerBit) == inServerBit) && - ((sessions & inServerBit) == inServerBit)){ - - DEBUG("reading - "); - - /* Operation 3 */ - - MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); - CHECK_NULL(MyOperation, "T3-3: getNdbOperation", - MyTransaction); - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T3-3: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_SESSION_SUBSCRIBER, - (char*)inNumber); - CHECK_MINUS_ONE(check, "T3-3: equal number", - MyTransaction); - - check = MyOperation->equal(IND_SESSION_SERVER, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T3-3: equal server id", - MyTransaction); - - check2 = MyOperation->getValue(IND_SESSION_DATA, - (char *)outSessionDetails); - CHECK_NULL(check2, "T3-3: getValue session details", - MyTransaction); - - /* Operation 4 */ - MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); - CHECK_NULL(MyOperation, "T3-4: getNdbOperation", - MyTransaction); - - check = MyOperation->interpretedUpdateTuple(); - CHECK_MINUS_ONE(check, "T3-4: interpretedUpdateTuple", - MyTransaction); - - check = MyOperation->equal(IND_SERVER_ID, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T3-4: equal serverId", - MyTransaction); - - check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, - (char*)inSuffix); - CHECK_MINUS_ONE(check, "T3-4: equal suffix", - MyTransaction); - - check = MyOperation->incValue(IND_SERVER_READS, (uint32)1); - CHECK_MINUS_ONE(check, "T3-4: inc value", - MyTransaction); - (* outBranchExecuted) = 1; - } else { - (* outBranchExecuted) = 0; - } - DEBUG("commit..."); - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T3: Commit", - MyTransaction); - - pNDB->closeTransaction(MyTransaction); - - DEBUG("done\n"); - get_time(outTransactionTime); - time_diff(outTransactionTime, &start); - return 0; -} - - -/** - * Transaction 4 - T4 - * - * Create session - * - * Input: - * SubscriberNumber - * ServerId - * ServerBit - * SessionDetails, - * DoRollback - * Output: - * ChangedBy - * ChangedTime - * Location - * BranchExecuted - */ -int -T4(void * obj, - const SubscriberNumber inNumber, - const SubscriberSuffix inSuffix, - const ServerId inServerId, - const ServerBit inServerBit, - const SessionDetails inSessionDetails, - ChangedBy outChangedBy, - ChangedTime outChangedTime, - Location * outLocation, - DoRollback inDoRollback, - BranchExecuted * outBranchExecuted, - BenchmarkTime * outTransactionTime){ - - DEBUG3("T4(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); - - Ndb * pNDB = (Ndb *) obj; - - GroupId groupId; - ActiveSessions sessions; - Permission permission; - - BenchmarkTime start; - get_time(&start); - - int check; - NdbRecAttr * check2; - - NdbConnection * MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("T4-1: startTranscation", pNDB->getNdbErrorString(), 0); - - NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T4-1: getNdbOperation", - MyTransaction); - - check = MyOperation->interpretedUpdateTuple(); - CHECK_MINUS_ONE(check, "T4-1: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, - inNumber); - CHECK_MINUS_ONE(check, "T4-1: equal subscriber", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, - (char *)outLocation); - CHECK_NULL(check2, "T4-1: getValue location", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, - outChangedBy); - CHECK_NULL(check2, "T4-1: getValue changed_by", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, - outChangedTime); - CHECK_NULL(check2, "T4-1: getValue changed_time", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, - (char *)&groupId); - CHECK_NULL(check2, "T4-1: getValue group", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, - (char *)&sessions); - CHECK_NULL(check2, "T4-1: getValue sessions", - MyTransaction); - - check = MyOperation->incValue(IND_SUBSCRIBER_SESSIONS, - (uint32)inServerBit); - CHECK_MINUS_ONE(check, "T4-4: inc value", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T4-1: NoCommit", - MyTransaction); - - /* Operation 2 */ - - MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); - CHECK_NULL(MyOperation, "T4-2: getNdbOperation", - MyTransaction); - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T4-2: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_GROUP_ID, - (char*)&groupId); - CHECK_MINUS_ONE(check, "T4-2: equal group", - MyTransaction); - - check2 = MyOperation->getValue(IND_GROUP_ALLOW_INSERT, - (char *)&permission); - CHECK_NULL(check2, "T4-2: getValue allow_insert", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T4-2: NoCommit", - MyTransaction); - - if(((permission & inServerBit) == inServerBit) && - ((sessions & inServerBit) == 0)){ - - DEBUG("inserting - "); - - /* Operation 3 */ - - MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); - CHECK_NULL(MyOperation, "T4-3: getNdbOperation", - MyTransaction); - - check = MyOperation->insertTuple(); - CHECK_MINUS_ONE(check, "T4-3: insertTuple", - MyTransaction); - - check = MyOperation->equal(IND_SESSION_SUBSCRIBER, - (char*)inNumber); - CHECK_MINUS_ONE(check, "T4-3: equal number", - MyTransaction); - - check = MyOperation->equal(IND_SESSION_SERVER, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T4-3: equal server id", - MyTransaction); - - check = MyOperation->setValue(SESSION_DATA, - (char *)inSessionDetails); - CHECK_MINUS_ONE(check, "T4-3: setValue session details", - MyTransaction); - - /* Operation 4 */ - - /* Operation 5 */ - MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); - CHECK_NULL(MyOperation, "T4-5: getNdbOperation", - MyTransaction); - - check = MyOperation->interpretedUpdateTuple(); - CHECK_MINUS_ONE(check, "T4-5: interpretedUpdateTuple", - MyTransaction); - - check = MyOperation->equal(IND_SERVER_ID, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T4-5: equal serverId", - MyTransaction); - - check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, - (char*)inSuffix); - CHECK_MINUS_ONE(check, "T4-5: equal suffix", - MyTransaction); - - check = MyOperation->incValue(IND_SERVER_INSERTS, (uint32)1); - CHECK_MINUS_ONE(check, "T4-5: inc value", - MyTransaction); - - (* outBranchExecuted) = 1; - } else { - DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); - DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); - (* outBranchExecuted) = 0; - } - - if(!inDoRollback && (* outBranchExecuted)){ - DEBUG("commit\n"); - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T4: Commit", - MyTransaction); - } else { - DEBUG("rollback\n"); - check = MyTransaction->execute(Rollback); - CHECK_MINUS_ONE(check, "T4:Rollback", - MyTransaction); - - } - - pNDB->closeTransaction(MyTransaction); - - get_time(outTransactionTime); - time_diff(outTransactionTime, &start); - return 0; -} - - -/** - * Transaction 5 - T5 - * - * Delete session - * - * Input: - * SubscriberNumber - * ServerId - * ServerBit - * DoRollback - * Output: - * ChangedBy - * ChangedTime - * Location - * BranchExecuted - */ -int -T5(void * obj, - const SubscriberNumber inNumber, - const SubscriberSuffix inSuffix, - const ServerId inServerId, - const ServerBit inServerBit, - ChangedBy outChangedBy, - ChangedTime outChangedTime, - Location * outLocation, - DoRollback inDoRollback, - BranchExecuted * outBranchExecuted, - BenchmarkTime * outTransactionTime){ - - DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); - - Ndb * pNDB = (Ndb *) obj; - NdbConnection * MyTransaction = 0; - NdbOperation * MyOperation = 0; - - GroupId groupId; - ActiveSessions sessions; - Permission permission; - - BenchmarkTime start; - get_time(&start); - - int check; - NdbRecAttr * check2; - - MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), 0); - - MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T5-1: getNdbOperation", - MyTransaction); - - check = MyOperation->interpretedUpdateTuple(); - CHECK_MINUS_ONE(check, "T5-1: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, - inNumber); - CHECK_MINUS_ONE(check, "T5-1: equal subscriber", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, - (char *)outLocation); - CHECK_NULL(check2, "T5-1: getValue location", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, - outChangedBy); - CHECK_NULL(check2, "T5-1: getValue changed_by", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, - outChangedTime); - CHECK_NULL(check2, "T5-1: getValue changed_time", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, - (char *)&groupId); - CHECK_NULL(check2, "T5-1: getValue group", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, - (char *)&sessions); - CHECK_NULL(check2, "T5-1: getValue sessions", - MyTransaction); - - check = MyOperation->subValue(IND_SUBSCRIBER_SESSIONS, - (uint32)inServerBit); - CHECK_MINUS_ONE(check, "T5-4: dec value", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T5-1: NoCommit", - MyTransaction); - - /* Operation 2 */ - - MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); - CHECK_NULL(MyOperation, "T5-2: getNdbOperation", - MyTransaction); - - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T5-2: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_GROUP_ID, - (char*)&groupId); - CHECK_MINUS_ONE(check, "T5-2: equal group", - MyTransaction); - - check2 = MyOperation->getValue(IND_GROUP_ALLOW_DELETE, - (char *)&permission); - CHECK_NULL(check2, "T5-2: getValue allow_delete", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T5-2: NoCommit", - MyTransaction); - - if(((permission & inServerBit) == inServerBit) && - ((sessions & inServerBit) == inServerBit)){ - - DEBUG("deleting - "); - - /* Operation 3 */ - MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); - CHECK_NULL(MyOperation, "T5-3: getNdbOperation", - MyTransaction); - - check = MyOperation->deleteTuple(); - CHECK_MINUS_ONE(check, "T5-3: deleteTuple", - MyTransaction); - - check = MyOperation->equal(IND_SESSION_SUBSCRIBER, - (char*)inNumber); - CHECK_MINUS_ONE(check, "T5-3: equal number", - MyTransaction); - - check = MyOperation->equal(IND_SESSION_SERVER, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T5-3: equal server id", - MyTransaction); - - /* Operation 4 */ - - /* Operation 5 */ - MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); - CHECK_NULL(MyOperation, "T5-5: getNdbOperation", - MyTransaction); - - - check = MyOperation->interpretedUpdateTuple(); - CHECK_MINUS_ONE(check, "T5-5: interpretedUpdateTuple", - MyTransaction); - - check = MyOperation->equal(IND_SERVER_ID, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T5-5: equal serverId", - MyTransaction); - - check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, - (char*)inSuffix); - CHECK_MINUS_ONE(check, "T5-5: equal suffix", - MyTransaction); - - check = MyOperation->incValue(IND_SERVER_DELETES, (uint32)1); - CHECK_MINUS_ONE(check, "T5-5: inc value", - MyTransaction); - - (* outBranchExecuted) = 1; - } else { - DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); - DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); - (* outBranchExecuted) = 0; - } - - if(!inDoRollback && (* outBranchExecuted)){ - DEBUG("commit\n"); - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T5: Commit", - MyTransaction); - } else { - DEBUG("rollback\n"); - check = MyTransaction->execute(Rollback); - CHECK_MINUS_ONE(check, "T5:Rollback", - MyTransaction); - - } - - pNDB->closeTransaction(MyTransaction); - - get_time(outTransactionTime); - time_diff(outTransactionTime, &start); - return 0; -} - diff --git a/ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction5.cpp b/ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction5.cpp deleted file mode 100644 index 86580008d10..00000000000 --- a/ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction5.cpp +++ /dev/null @@ -1,769 +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 */ - -//#define DEBUG_ON - -extern "C" { -#include "user_transaction.h" -}; - -#include "macros.h" -#include "ndb_schema.hpp" -#include "ndb_error.hpp" - -#include -#include - -/** - * Transaction 1 - T1 - * - * Update location and changed by/time on a subscriber - * - * Input: - * SubscriberNumber, - * Location, - * ChangedBy, - * ChangedTime - * - * Output: - */ -int -T1(void * obj, - const SubscriberNumber number, - const Location new_location, - const ChangedBy changed_by, - const ChangedTime changed_time, - BenchmarkTime * transaction_time){ - - Ndb * pNDB = (Ndb *) obj; - - DEBUG2("T1(%.*s):\n", SUBSCRIBER_NUMBER_LENGTH, number); - - BenchmarkTime start; - get_time(&start); - - int check; - NdbRecAttr * check2; - - NdbConnection * MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("T1-1: startTranscation", pNDB->getNdbErrorString(), 0); - - NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction); - - check = MyOperation->updateTuple(); - CHECK_MINUS_ONE(check, "T1: updateTuple", - MyTransaction); - - check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, - number); - CHECK_MINUS_ONE(check, "T1: equal subscriber", - MyTransaction); - - check = MyOperation->setValue(IND_SUBSCRIBER_LOCATION, - (char *)&new_location); - CHECK_MINUS_ONE(check, "T1: setValue location", - MyTransaction); - - check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_BY, - changed_by); - CHECK_MINUS_ONE(check, "T1: setValue changed_by", - MyTransaction); - - check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_TIME, - changed_time); - CHECK_MINUS_ONE(check, "T1: setValue changed_time", - MyTransaction); - - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T1: Commit", - MyTransaction); - - pNDB->closeTransaction(MyTransaction); - - get_time(transaction_time); - time_diff(transaction_time, &start); - return 0; -} - -/** - * Transaction 2 - T2 - * - * Read from Subscriber: - * - * Input: - * SubscriberNumber - * - * Output: - * Location - * Changed by - * Changed Timestamp - * Name - */ -int -T2(void * obj, - const SubscriberNumber number, - Location * readLocation, - ChangedBy changed_by, - ChangedTime changed_time, - SubscriberName subscriberName, - BenchmarkTime * transaction_time){ - - Ndb * pNDB = (Ndb *) obj; - - DEBUG2("T2(%.*s):\n", SUBSCRIBER_NUMBER_LENGTH, number); - - BenchmarkTime start; - get_time(&start); - - int check; - NdbRecAttr * check2; - - NdbConnection * MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("T2-1: startTranscation", pNDB->getNdbErrorString(), 0); - - NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T2: getNdbOperation", - MyTransaction); - - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T2: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, - number); - CHECK_MINUS_ONE(check, "T2: equal subscriber", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, - (char *)readLocation); - CHECK_NULL(check2, "T2: getValue location", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, - changed_by); - CHECK_NULL(check2, "T2: getValue changed_by", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, - changed_time); - CHECK_NULL(check2, "T2: getValue changed_time", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_NAME, - subscriberName); - CHECK_NULL(check2, "T2: getValue name", - MyTransaction); - - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T2: Commit", - MyTransaction); - - pNDB->closeTransaction(MyTransaction); - - get_time(transaction_time); - time_diff(transaction_time, &start); - return 0; -} - -/** - * Transaction 3 - T3 - * - * Read session details - * - * Input: - * SubscriberNumber - * ServerId - * ServerBit - * - * Output: - * BranchExecuted - * SessionDetails - * ChangedBy - * ChangedTime - * Location - */ -int -T3(void * obj, - const SubscriberNumber inNumber, - const SubscriberSuffix inSuffix, - const ServerId inServerId, - const ServerBit inServerBit, - SessionDetails outSessionDetails, - ChangedBy outChangedBy, - ChangedTime outChangedTime, - Location * outLocation, - BranchExecuted * outBranchExecuted, - BenchmarkTime * outTransactionTime){ - - Ndb * pNDB = (Ndb *) obj; - - GroupId groupId; - ActiveSessions sessions; - Permission permission; - - BenchmarkTime start; - get_time(&start); - - int check; - NdbRecAttr * check2; - - NdbConnection * MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("T3-1: startTranscation", pNDB->getNdbErrorString(), 0); - - NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T3-1: getNdbOperation", - MyTransaction); - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T3-1: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, - inNumber); - CHECK_MINUS_ONE(check, "T3-1: equal subscriber", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, - (char *)outLocation); - CHECK_NULL(check2, "T3-1: getValue location", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, - outChangedBy); - CHECK_NULL(check2, "T3-1: getValue changed_by", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, - outChangedTime); - CHECK_NULL(check2, "T3-1: getValue changed_time", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, - (char *)&groupId); - CHECK_NULL(check2, "T3-1: getValue group", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, - (char *)&sessions); - CHECK_NULL(check2, "T3-1: getValue sessions", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T3-1: NoCommit", - MyTransaction); - - /* Operation 2 */ - - MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); - CHECK_NULL(MyOperation, "T3-2: getNdbOperation", - MyTransaction); - - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T3-2: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_GROUP_ID, - (char*)&groupId); - CHECK_MINUS_ONE(check, "T3-2: equal group", - MyTransaction); - - check2 = MyOperation->getValue(IND_GROUP_ALLOW_READ, - (char *)&permission); - CHECK_NULL(check2, "T3-2: getValue allow_read", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T3-2: NoCommit", - MyTransaction); - - DEBUG3("T3(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); - - if(((permission & inServerBit) == inServerBit) && - ((sessions & inServerBit) == inServerBit)){ - - DEBUG("reading - "); - - /* Operation 3 */ - MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); - CHECK_NULL(MyOperation, "T3-3: getNdbOperation", - MyTransaction); - - check = MyOperation->simpleRead(); - CHECK_MINUS_ONE(check, "T3-3: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_SESSION_SUBSCRIBER, - (char*)inNumber); - CHECK_MINUS_ONE(check, "T3-3: equal number", - MyTransaction); - - check = MyOperation->equal(IND_SESSION_SERVER, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T3-3: equal server id", - MyTransaction); - - check2 = MyOperation->getValue(IND_SESSION_DATA, - (char *)outSessionDetails); - CHECK_NULL(check2, "T3-3: getValue session details", - MyTransaction); - - /* Operation 4 */ - MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); - CHECK_NULL(MyOperation, "T3-4: getNdbOperation", - MyTransaction); - - check = MyOperation->interpretedUpdateTuple(); - CHECK_MINUS_ONE(check, "T3-4: interpretedUpdateTuple", - MyTransaction); - - check = MyOperation->equal(IND_SERVER_ID, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T3-4: equal serverId", - MyTransaction); - - check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, - (char*)inSuffix); - CHECK_MINUS_ONE(check, "T3-4: equal suffix", - MyTransaction); - - check = MyOperation->incValue(IND_SERVER_READS, (uint32)1); - CHECK_MINUS_ONE(check, "T3-4: inc value", - MyTransaction); - (* outBranchExecuted) = 1; - } else { - (* outBranchExecuted) = 0; - } - DEBUG("commit..."); - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T3: Commit", - MyTransaction); - - pNDB->closeTransaction(MyTransaction); - - DEBUG("done\n"); - get_time(outTransactionTime); - time_diff(outTransactionTime, &start); - return 0; -} - - -/** - * Transaction 4 - T4 - * - * Create session - * - * Input: - * SubscriberNumber - * ServerId - * ServerBit - * SessionDetails, - * DoRollback - * Output: - * ChangedBy - * ChangedTime - * Location - * BranchExecuted - */ -int -T4(void * obj, - const SubscriberNumber inNumber, - const SubscriberSuffix inSuffix, - const ServerId inServerId, - const ServerBit inServerBit, - const SessionDetails inSessionDetails, - ChangedBy outChangedBy, - ChangedTime outChangedTime, - Location * outLocation, - DoRollback inDoRollback, - BranchExecuted * outBranchExecuted, - BenchmarkTime * outTransactionTime){ - - Ndb * pNDB = (Ndb *) obj; - - GroupId groupId; - ActiveSessions sessions; - Permission permission; - - BenchmarkTime start; - get_time(&start); - - int check; - NdbRecAttr * check2; - - NdbConnection * MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("T4-1: startTranscation", pNDB->getNdbErrorString(), 0); - - NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T4-1: getNdbOperation", - MyTransaction); - - check = MyOperation->interpretedUpdateTuple(); - CHECK_MINUS_ONE(check, "T4-1: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, - inNumber); - CHECK_MINUS_ONE(check, "T4-1: equal subscriber", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, - (char *)outLocation); - CHECK_NULL(check2, "T4-1: getValue location", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, - outChangedBy); - CHECK_NULL(check2, "T4-1: getValue changed_by", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, - outChangedTime); - CHECK_NULL(check2, "T4-1: getValue changed_time", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, - (char *)&groupId); - CHECK_NULL(check2, "T4-1: getValue group", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, - (char *)&sessions); - CHECK_NULL(check2, "T4-1: getValue sessions", - MyTransaction); - - check = MyOperation->incValue(IND_SUBSCRIBER_SESSIONS, - (uint32)inServerBit); - CHECK_MINUS_ONE(check, "T4-4: inc value", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T4-1: NoCommit", - MyTransaction); - - /* Operation 2 */ - - MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); - CHECK_NULL(MyOperation, "T4-2: getNdbOperation", - MyTransaction); - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T4-2: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_GROUP_ID, - (char*)&groupId); - CHECK_MINUS_ONE(check, "T4-2: equal group", - MyTransaction); - - check2 = MyOperation->getValue(IND_GROUP_ALLOW_INSERT, - (char *)&permission); - CHECK_NULL(check2, "T4-2: getValue allow_insert", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T4-2: NoCommit", - MyTransaction); - - DEBUG3("T4(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); - - if(((permission & inServerBit) == inServerBit) && - ((sessions & inServerBit) == 0)){ - - DEBUG("inserting - "); - - /* Operation 3 */ - - MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); - CHECK_NULL(MyOperation, "T4-3: getNdbOperation", - MyTransaction); - - check = MyOperation->insertTuple(); - CHECK_MINUS_ONE(check, "T4-3: insertTuple", - MyTransaction); - - check = MyOperation->equal(IND_SESSION_SUBSCRIBER, - (char*)inNumber); - CHECK_MINUS_ONE(check, "T4-3: equal number", - MyTransaction); - - check = MyOperation->equal(IND_SESSION_SERVER, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T4-3: equal server id", - MyTransaction); - - check = MyOperation->setValue(SESSION_DATA, - (char *)inSessionDetails); - CHECK_MINUS_ONE(check, "T4-3: setValue session details", - MyTransaction); - - /* Operation 4 */ - - /* Operation 5 */ - MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); - CHECK_NULL(MyOperation, "T4-5: getNdbOperation", - MyTransaction); - - check = MyOperation->interpretedUpdateTuple(); - CHECK_MINUS_ONE(check, "T4-5: interpretedUpdateTuple", - MyTransaction); - - check = MyOperation->equal(IND_SERVER_ID, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T4-5: equal serverId", - MyTransaction); - - check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, - (char*)inSuffix); - CHECK_MINUS_ONE(check, "T4-5: equal suffix", - MyTransaction); - - check = MyOperation->incValue(IND_SERVER_INSERTS, (uint32)1); - CHECK_MINUS_ONE(check, "T4-5: inc value", - MyTransaction); - - (* outBranchExecuted) = 1; - } else { - DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); - DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); - (* outBranchExecuted) = 0; - } - - if(!inDoRollback && (* outBranchExecuted)){ - DEBUG("commit\n"); - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T4: Commit", - MyTransaction); - } else { - DEBUG("rollback\n"); - check = MyTransaction->execute(Rollback); - CHECK_MINUS_ONE(check, "T4:Rollback", - MyTransaction); - - } - - pNDB->closeTransaction(MyTransaction); - - get_time(outTransactionTime); - time_diff(outTransactionTime, &start); - return 0; -} - - -/** - * Transaction 5 - T5 - * - * Delete session - * - * Input: - * SubscriberNumber - * ServerId - * ServerBit - * DoRollback - * Output: - * ChangedBy - * ChangedTime - * Location - * BranchExecuted - */ -int -T5(void * obj, - const SubscriberNumber inNumber, - const SubscriberSuffix inSuffix, - const ServerId inServerId, - const ServerBit inServerBit, - ChangedBy outChangedBy, - ChangedTime outChangedTime, - Location * outLocation, - DoRollback inDoRollback, - BranchExecuted * outBranchExecuted, - BenchmarkTime * outTransactionTime){ - - Ndb * pNDB = (Ndb *) obj; - NdbConnection * MyTransaction = 0; - NdbOperation * MyOperation = 0; - - GroupId groupId; - ActiveSessions sessions; - Permission permission; - - BenchmarkTime start; - get_time(&start); - - int check; - NdbRecAttr * check2; - - MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), 0); - - MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T5-1: getNdbOperation", - MyTransaction); - - check = MyOperation->interpretedUpdateTuple(); - CHECK_MINUS_ONE(check, "T5-1: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, - inNumber); - CHECK_MINUS_ONE(check, "T5-1: equal subscriber", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, - (char *)outLocation); - CHECK_NULL(check2, "T5-1: getValue location", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, - outChangedBy); - CHECK_NULL(check2, "T5-1: getValue changed_by", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, - outChangedTime); - CHECK_NULL(check2, "T5-1: getValue changed_time", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, - (char *)&groupId); - CHECK_NULL(check2, "T5-1: getValue group", - MyTransaction); - - check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, - (char *)&sessions); - CHECK_NULL(check2, "T5-1: getValue sessions", - MyTransaction); - - check = MyOperation->subValue(IND_SUBSCRIBER_SESSIONS, - (uint32)inServerBit); - CHECK_MINUS_ONE(check, "T5-4: dec value", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T5-1: NoCommit", - MyTransaction); - - /* Operation 2 */ - - MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); - CHECK_NULL(MyOperation, "T5-2: getNdbOperation", - MyTransaction); - - - check = MyOperation->readTuple(); - CHECK_MINUS_ONE(check, "T5-2: readTuple", - MyTransaction); - - check = MyOperation->equal(IND_GROUP_ID, - (char*)&groupId); - CHECK_MINUS_ONE(check, "T5-2: equal group", - MyTransaction); - - check2 = MyOperation->getValue(IND_GROUP_ALLOW_DELETE, - (char *)&permission); - CHECK_NULL(check2, "T5-2: getValue allow_delete", - MyTransaction); - - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T5-2: NoCommit", - MyTransaction); - - DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); - - if(((permission & inServerBit) == inServerBit) && - ((sessions & inServerBit) == inServerBit)){ - - DEBUG("deleting - "); - - /* Operation 3 */ - MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); - CHECK_NULL(MyOperation, "T5-3: getNdbOperation", - MyTransaction); - - check = MyOperation->deleteTuple(); - CHECK_MINUS_ONE(check, "T5-3: deleteTuple", - MyTransaction); - - check = MyOperation->equal(IND_SESSION_SUBSCRIBER, - (char*)inNumber); - CHECK_MINUS_ONE(check, "T5-3: equal number", - MyTransaction); - - check = MyOperation->equal(IND_SESSION_SERVER, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T5-3: equal server id", - MyTransaction); - - /* Operation 4 */ - - /* Operation 5 */ - MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); - CHECK_NULL(MyOperation, "T5-5: getNdbOperation", - MyTransaction); - - - check = MyOperation->interpretedUpdateTuple(); - CHECK_MINUS_ONE(check, "T5-5: interpretedUpdateTuple", - MyTransaction); - - check = MyOperation->equal(IND_SERVER_ID, - (char*)&inServerId); - CHECK_MINUS_ONE(check, "T5-5: equal serverId", - MyTransaction); - - check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, - (char*)inSuffix); - CHECK_MINUS_ONE(check, "T5-5: equal suffix", - MyTransaction); - - check = MyOperation->incValue(IND_SERVER_DELETES, (uint32)1); - CHECK_MINUS_ONE(check, "T5-5: inc value", - MyTransaction); - - (* outBranchExecuted) = 1; - } else { - DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); - DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); - (* outBranchExecuted) = 0; - } - - if(!inDoRollback && (* outBranchExecuted)){ - DEBUG("commit\n"); - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T5: Commit", - MyTransaction); - } else { - DEBUG("rollback\n"); - check = MyTransaction->execute(Rollback); - CHECK_MINUS_ONE(check, "T5:Rollback", - MyTransaction); - - } - - pNDB->closeTransaction(MyTransaction); - - get_time(outTransactionTime); - time_diff(outTransactionTime, &start); - return 0; -} - diff --git a/ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction6.cpp b/ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction6.cpp deleted file mode 100644 index 262f38e9ffb..00000000000 --- a/ndb/test/ndbapi/lmc-bench/src/user/ndb_user_transaction6.cpp +++ /dev/null @@ -1,561 +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 */ - -//#define DEBUG_ON - -#include -#include "userHandle.h" -#include "userInterface.h" - -#include "macros.h" -#include "ndb_schema.hpp" -#include "ndb_error.hpp" - -#include - - -void -userCheckpoint(UserHandle *uh){ -} - -inline -NdbConnection * -startTransaction(Ndb * pNDB, ServerId inServerId, const SubscriberNumber inNumber){ - - const int keyDataLenBytes = sizeof(ServerId)+SUBSCRIBER_NUMBER_LENGTH; - const int keyDataLen_64Words = keyDataLenBytes >> 3; - - Uint64 keyDataBuf[keyDataLen_64Words+1]; // The "+1" is for rounding... - - char * keyDataBuf_charP = (char *)&keyDataBuf[0]; - Uint32 * keyDataBuf_wo32P = (Uint32 *)&keyDataBuf[0]; - - // Server Id comes first - keyDataBuf_wo32P[0] = inServerId; - // Then subscriber number - memcpy(&keyDataBuf_charP[sizeof(ServerId)], inNumber, SUBSCRIBER_NUMBER_LENGTH); - - return pNDB->startTransaction(0, keyDataBuf_charP, keyDataLenBytes); -} - -/** - * Transaction 1 - T1 - * - * Update location and changed by/time on a subscriber - * - * Input: - * SubscriberNumber, - * Location, - * ChangedBy, - * ChangedTime - * - * Output: - */ -void -userTransaction_T1(UserHandle * uh, - SubscriberNumber number, - Location new_location, - ChangedBy changed_by, - ChangedTime changed_time){ - Ndb * pNDB = uh->pNDB; - - DEBUG2("T1(%.*s):\n", SUBSCRIBER_NUMBER_LENGTH, number); - - int check; - NdbRecAttr * check2; - - NdbConnection * MyTransaction = pNDB->startTransaction(); - if (MyTransaction != NULL) { - NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - if (MyOperation != NULL) { - MyOperation->updateTuple(); - MyOperation->equal(IND_SUBSCRIBER_NUMBER, - number); - MyOperation->setValue(IND_SUBSCRIBER_LOCATION, - (char *)&new_location); - MyOperation->setValue(IND_SUBSCRIBER_CHANGED_BY, - changed_by); - MyOperation->setValue(IND_SUBSCRIBER_CHANGED_TIME, - changed_time); - check = MyTransaction->execute( Commit ); - if (check != -1) { - pNDB->closeTransaction(MyTransaction); - return; - } else { - CHECK_MINUS_ONE(check, "T1: Commit", - MyTransaction); - }//if - } else { - CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction); - }//if - } else { - error_handler("T1-1: startTranscation", pNDB->getNdbErrorString(), pNDB->getNdbError()); - }//if -} - -/** - * Transaction 2 - T2 - * - * Read from Subscriber: - * - * Input: - * SubscriberNumber - * - * Output: - * Location - * Changed by - * Changed Timestamp - * Name - */ -void -userTransaction_T2(UserHandle * uh, - SubscriberNumber number, - Location * readLocation, - ChangedBy changed_by, - ChangedTime changed_time, - SubscriberName subscriberName){ - Ndb * pNDB = uh->pNDB; - - DEBUG2("T2(%.*s):\n", SUBSCRIBER_NUMBER_LENGTH, number); - - int check; - NdbRecAttr * check2; - - NdbConnection * MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("T2-1: startTransaction", pNDB->getNdbErrorString(), pNDB->getNdbError()); - - NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T2: getNdbOperation", - MyTransaction); - - MyOperation->readTuple(); - MyOperation->equal(IND_SUBSCRIBER_NUMBER, - number); - MyOperation->getValue(IND_SUBSCRIBER_LOCATION, - (char *)readLocation); - MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, - changed_by); - MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, - changed_time); - MyOperation->getValue(IND_SUBSCRIBER_NAME, - subscriberName); - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T2: Commit", - MyTransaction); - pNDB->closeTransaction(MyTransaction); -} - -/** - * Transaction 3 - T3 - * - * Read session details - * - * Input: - * SubscriberNumber - * ServerId - * ServerBit - * - * Output: - * BranchExecuted - * SessionDetails - * ChangedBy - * ChangedTime - * Location - */ -void -userTransaction_T3(UserHandle * uh, - SubscriberNumber inNumber, - ServerId inServerId, - ServerBit inServerBit, - SessionDetails outSessionDetails, - BranchExecuted * outBranchExecuted){ - Ndb * pNDB = uh->pNDB; - - char outChangedBy [sizeof(ChangedBy) +(4-(sizeof(ChangedBy) & 3))]; - char outChangedTime [sizeof(ChangedTime)+(4-(sizeof(ChangedTime) & 3))]; - Location outLocation; - GroupId groupId; - ActiveSessions sessions; - Permission permission; - SubscriberSuffix inSuffix; - - DEBUG3("T3(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); - - int check; - NdbRecAttr * check2; - - NdbConnection * MyTransaction = startTransaction(pNDB, inServerId, inNumber); - if (MyTransaction == NULL) - error_handler("T3-1: startTranscation", pNDB->getNdbErrorString(), pNDB->getNdbError()); - - NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T3-1: getNdbOperation", - MyTransaction); - - MyOperation->readTuple(); - MyOperation->equal(IND_SUBSCRIBER_NUMBER, - inNumber); - MyOperation->getValue(IND_SUBSCRIBER_LOCATION, - (char *)&outLocation); - MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, - outChangedBy); - MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, - outChangedTime); - MyOperation->getValue(IND_SUBSCRIBER_GROUP, - (char *)&groupId); - MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, - (char *)&sessions); - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T3-1: NoCommit", - MyTransaction); - - /* Operation 2 */ - - MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); - CHECK_NULL(MyOperation, "T3-2: getNdbOperation", - MyTransaction); - - - MyOperation->readTuple(); - MyOperation->equal(IND_GROUP_ID, - (char*)&groupId); - MyOperation->getValue(IND_GROUP_ALLOW_READ, - (char *)&permission); - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T3-2: NoCommit", - MyTransaction); - - if(((permission & inServerBit) == inServerBit) && - ((sessions & inServerBit) == inServerBit)){ - - memcpy(inSuffix, - &inNumber[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], SUBSCRIBER_NUMBER_SUFFIX_LENGTH); - DEBUG2("reading(%.*s) - ", SUBSCRIBER_NUMBER_SUFFIX_LENGTH, inSuffix); - - /* Operation 3 */ - MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); - CHECK_NULL(MyOperation, "T3-3: getNdbOperation", - MyTransaction); - - MyOperation->simpleRead(); - - MyOperation->equal(IND_SESSION_SUBSCRIBER, - (char*)inNumber); - MyOperation->equal(IND_SESSION_SERVER, - (char*)&inServerId); - MyOperation->getValue(IND_SESSION_DATA, - (char *)outSessionDetails); - /* Operation 4 */ - MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); - CHECK_NULL(MyOperation, "T3-4: getNdbOperation", - MyTransaction); - - MyOperation->interpretedUpdateTuple(); - MyOperation->equal(IND_SERVER_ID, - (char*)&inServerId); - MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, - (char*)inSuffix); - MyOperation->incValue(IND_SERVER_READS, (uint32)1); - (* outBranchExecuted) = 1; - } else { - (* outBranchExecuted) = 0; - } - DEBUG("commit..."); - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T3: Commit", - MyTransaction); - - pNDB->closeTransaction(MyTransaction); - - DEBUG("done\n"); -} - - -/** - * Transaction 4 - T4 - * - * Create session - * - * Input: - * SubscriberNumber - * ServerId - * ServerBit - * SessionDetails, - * DoRollback - * Output: - * ChangedBy - * ChangedTime - * Location - * BranchExecuted - */ -void -userTransaction_T4(UserHandle * uh, - SubscriberNumber inNumber, - ServerId inServerId, - ServerBit inServerBit, - SessionDetails inSessionDetails, - DoRollback inDoRollback, - BranchExecuted * outBranchExecuted){ - - Ndb * pNDB = uh->pNDB; - - char outChangedBy [sizeof(ChangedBy) +(4-(sizeof(ChangedBy) & 3))]; - char outChangedTime [sizeof(ChangedTime)+(4-(sizeof(ChangedTime) & 3))]; - Location outLocation; - GroupId groupId; - ActiveSessions sessions; - Permission permission; - SubscriberSuffix inSuffix; - - DEBUG3("T4(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); - - int check; - NdbRecAttr * check2; - - NdbConnection * MyTransaction = startTransaction(pNDB, inServerId, inNumber); - if (MyTransaction == NULL) - error_handler("T4-1: startTranscation", pNDB->getNdbErrorString(), pNDB->getNdbError()); - - NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T4-1: getNdbOperation", - MyTransaction); - - MyOperation->interpretedUpdateTuple(); - MyOperation->equal(IND_SUBSCRIBER_NUMBER, - inNumber); - MyOperation->getValue(IND_SUBSCRIBER_LOCATION, - (char *)&outLocation); - MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, - outChangedBy); - MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, - outChangedTime); - MyOperation->getValue(IND_SUBSCRIBER_GROUP, - (char *)&groupId); - MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, - (char *)&sessions); - MyOperation->incValue(IND_SUBSCRIBER_SESSIONS, - (uint32)inServerBit); - check = MyTransaction->execute( NoCommit ); - - /* Operation 2 */ - - MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); - CHECK_NULL(MyOperation, "T4-2: getNdbOperation", - MyTransaction); - - MyOperation->readTuple(); - MyOperation->equal(IND_GROUP_ID, - (char*)&groupId); - MyOperation->getValue(IND_GROUP_ALLOW_INSERT, - (char *)&permission); - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T4-2: NoCommit", - MyTransaction); - - if(((permission & inServerBit) == inServerBit) && - ((sessions & inServerBit) == 0)){ - - memcpy(inSuffix, - &inNumber[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], SUBSCRIBER_NUMBER_SUFFIX_LENGTH); - - DEBUG2("inserting(%.*s) - ", SUBSCRIBER_NUMBER_SUFFIX_LENGTH, inSuffix); - - /* Operation 3 */ - - MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); - CHECK_NULL(MyOperation, "T4-3: getNdbOperation", - MyTransaction); - - MyOperation->insertTuple(); - MyOperation->equal(IND_SESSION_SUBSCRIBER, - (char*)inNumber); - MyOperation->equal(IND_SESSION_SERVER, - (char*)&inServerId); - MyOperation->setValue(SESSION_DATA, - (char *)inSessionDetails); - /* Operation 4 */ - - /* Operation 5 */ - MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); - CHECK_NULL(MyOperation, "T4-5: getNdbOperation", - MyTransaction); - - MyOperation->interpretedUpdateTuple(); - MyOperation->equal(IND_SERVER_ID, - (char*)&inServerId); - MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, - (char*)inSuffix); - MyOperation->incValue(IND_SERVER_INSERTS, (uint32)1); - (* outBranchExecuted) = 1; - } else { - (* outBranchExecuted) = 0; - DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); - DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); - } - - if(!inDoRollback && (* outBranchExecuted)){ - DEBUG("commit\n"); - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T4: Commit", - MyTransaction); - } else { - DEBUG("rollback\n"); - check = MyTransaction->execute(Rollback); - CHECK_MINUS_ONE(check, "T4:Rollback", - MyTransaction); - - } - - pNDB->closeTransaction(MyTransaction); -} - - -/** - * Transaction 5 - T5 - * - * Delete session - * - * Input: - * SubscriberNumber - * ServerId - * ServerBit - * DoRollback - * Output: - * ChangedBy - * ChangedTime - * Location - * BranchExecuted - */ -void -userTransaction_T5(UserHandle * uh, - SubscriberNumber inNumber, - ServerId inServerId, - ServerBit inServerBit, - DoRollback inDoRollback, - BranchExecuted * outBranchExecuted){ - Ndb * pNDB = uh->pNDB; - - DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); - - NdbConnection * MyTransaction = 0; - NdbOperation * MyOperation = 0; - - char outChangedBy [sizeof(ChangedBy) +(4-(sizeof(ChangedBy) & 3))]; - char outChangedTime [sizeof(ChangedTime)+(4-(sizeof(ChangedTime) & 3))]; - Location outLocation; - GroupId groupId; - ActiveSessions sessions; - Permission permission; - SubscriberSuffix inSuffix; - - int check; - NdbRecAttr * check2; - - MyTransaction = pNDB->startTransaction(); - if (MyTransaction == NULL) - error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), pNDB->getNdbError()); - - MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "T5-1: getNdbOperation", - MyTransaction); - - MyOperation->interpretedUpdateTuple(); - MyOperation->equal(IND_SUBSCRIBER_NUMBER, - inNumber); - MyOperation->getValue(IND_SUBSCRIBER_LOCATION, - (char *)&outLocation); - MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, - &outChangedBy[0]); - MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, - &outChangedTime[0]); - MyOperation->getValue(IND_SUBSCRIBER_GROUP, - (char *)&groupId); - MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, - (char *)&sessions); - MyOperation->subValue(IND_SUBSCRIBER_SESSIONS, - (uint32)inServerBit); - MyTransaction->execute( NoCommit ); - /* Operation 2 */ - - MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); - CHECK_NULL(MyOperation, "T5-2: getNdbOperation", - MyTransaction); - - MyOperation->readTuple(); - MyOperation->equal(IND_GROUP_ID, - (char*)&groupId); - MyOperation->getValue(IND_GROUP_ALLOW_DELETE, - (char *)&permission); - check = MyTransaction->execute( NoCommit ); - CHECK_MINUS_ONE(check, "T5-2: NoCommit", - MyTransaction); - - if(((permission & inServerBit) == inServerBit) && - ((sessions & inServerBit) == inServerBit)){ - - memcpy(inSuffix, - &inNumber[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], SUBSCRIBER_NUMBER_SUFFIX_LENGTH); - - DEBUG2("deleting(%.*s) - ", SUBSCRIBER_NUMBER_SUFFIX_LENGTH, inSuffix); - - /* Operation 3 */ - MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); - CHECK_NULL(MyOperation, "T5-3: getNdbOperation", - MyTransaction); - - MyOperation->deleteTuple(); - MyOperation->equal(IND_SESSION_SUBSCRIBER, - (char*)inNumber); - MyOperation->equal(IND_SESSION_SERVER, - (char*)&inServerId); - /* Operation 4 */ - - /* Operation 5 */ - MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); - CHECK_NULL(MyOperation, "T5-5: getNdbOperation", - MyTransaction); - - - MyOperation->interpretedUpdateTuple(); - MyOperation->equal(IND_SERVER_ID, - (char*)&inServerId); - MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, - (char*)inSuffix); - MyOperation->incValue(IND_SERVER_DELETES, (uint32)1); - (* outBranchExecuted) = 1; - } else { - (* outBranchExecuted) = 0; - DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); - DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); - } - - if(!inDoRollback && (* outBranchExecuted)){ - DEBUG("commit\n"); - check = MyTransaction->execute( Commit ); - CHECK_MINUS_ONE(check, "T5: Commit", - MyTransaction); - } else { - DEBUG("rollback\n"); - check = MyTransaction->execute(Rollback); - CHECK_MINUS_ONE(check, "T5:Rollback", - MyTransaction); - - } - - pNDB->closeTransaction(MyTransaction); -} - diff --git a/ndb/test/ndbapi/lmc-bench/src/user/old/Makefile b/ndb/test/ndbapi/lmc-bench/src/user/old/Makefile deleted file mode 100644 index 9b1247d44af..00000000000 --- a/ndb/test/ndbapi/lmc-bench/src/user/old/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -include ../makevars.$(ARCH) - -LIBRARY = ../../lib/libUser.so - -OBJECTS = \ - $(LIBRARY)(localDbPrepare.o)\ - $(LIBRARY)(userInterface.o)\ - $(LIBRARY)(userTransaction.o) - -$(LIBRARY): $(OBJECTS) diff --git a/ndb/test/ndbapi/lmc-bench/src/user/old/userHandle.h b/ndb/test/ndbapi/lmc-bench/src/user/old/userHandle.h deleted file mode 100644 index 1de468d4dad..00000000000 --- a/ndb/test/ndbapi/lmc-bench/src/user/old/userHandle.h +++ /dev/null @@ -1,190 +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 */ - -#ifndef USERHANDLE_H -#define USERHANDLE_H - -/***************************************************************/ -/* I N C L U D E D F I L E S */ -/***************************************************************/ - -#include "sql.h" -#include "sqlext.h" -#include "sqltypes.h" - -#include "testDefinitions.h" - -/*************************************************************** -* M A C R O S * -***************************************************************/ - -/***************************************************************/ -/* C O N S T A N T S */ -/***************************************************************/ - -/*************************************************************** -* D A T A S T R U C T U R E S * -***************************************************************/ - -struct userHandle{ - SQLHENV henv; - SQLHDBC hdbc; - SQLHSTMT stmt; - - /*----------------*/ - /* Transaction T1 */ - /*----------------*/ - struct { - SQLHSTMT stmt; - struct { - SubscriberNumber number; - Location location; - ChangedBy changedBy; - ChangedTime changedTime; - }values; - }updateSubscriber; - - /*----------------*/ - /* Transaction T2 */ - /*----------------*/ - struct { - SQLHSTMT stmt; - struct { - SubscriberNumber number; - SubscriberName name; - Location location; - ChangedBy changedBy; - ChangedTime changedTime; - }values; - }readSubscriber; - - /*----------------*/ - /* Transaction T3 */ - /*----------------*/ - struct { - SQLHSTMT stmt; - struct { - GroupId groupId; - Permission allowRead; - }values; - }readGroupAllowRead; - - struct { - SQLHSTMT stmt; - struct { - SubscriberNumber number; - ServerId serverId; - SessionDetails details; - }values; - }readSessionDetails; - - struct { - SQLHSTMT stmt; - struct { - ServerId serverId; - SubscriberSuffix suffix; - }values; - }updateServerNoOfRead; - - /*----------------*/ - /* Transaction T4 */ - /*----------------*/ - struct { - SQLHSTMT stmt; - struct { - GroupId groupId; - Permission allowInsert; - }values; - }readGroupAllowInsert; - - struct { - SQLHSTMT stmt; - struct { - SubscriberNumber number; - ServerId serverId; - SessionDetails details; - }values; - }insertSession; - - struct { - SQLHSTMT stmt; - struct { - ServerId serverId; - SubscriberSuffix suffix; - }values; - }updateServerNoOfInsert; - - /*----------------*/ - /* Transaction T5 */ - /*----------------*/ - struct { - SQLHSTMT stmt; - struct { - GroupId groupId; - Permission allowDelete; - }values; - }readGroupAllowDelete; - - struct { - SQLHSTMT stmt; - struct { - SubscriberNumber number; - ServerId serverId; - }values; - }deleteSession; - - struct { - SQLHSTMT stmt; - struct { - ServerId serverId; - SubscriberSuffix suffix; - }values; - }updateServerNoOfDelete; - - /*--------------------------*/ - /* Transaction T3 + T4 + T5 */ - /*--------------------------*/ - struct { - SQLHSTMT stmt; - struct { - SubscriberNumber number; - uint32 activeSessions; - GroupId groupId; - ChangedBy changedBy; - ChangedTime changedTime; - }values; - }readSubscriberSession; - - struct { - SQLHSTMT stmt; - struct { - SubscriberNumber number; - uint32 activeSessions; - }values; - }updateSubscriberSession; -}; - -/*************************************************************** -* P U B L I C F U N C T I O N S * -***************************************************************/ - -/*************************************************************** -* E X T E R N A L D A T A * -***************************************************************/ - - -#endif /* USERHANDLE_H */ - diff --git a/ndb/test/ndbapi/lmc-bench/src/user/old/userInterface.c b/ndb/test/ndbapi/lmc-bench/src/user/old/userInterface.c deleted file mode 100644 index bacf1861dde..00000000000 --- a/ndb/test/ndbapi/lmc-bench/src/user/old/userInterface.c +++ /dev/null @@ -1,453 +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 */ - -/*************************************************************** -* I N C L U D E D F I L E S * -***************************************************************/ - -#include - -#include "userInterface.h" -#include "userHandle.h" - -/*************************************************************** -* L O C A L C O N S T A N T S * -***************************************************************/ - -/*************************************************************** -* L O C A L D A T A S T R U C T U R E S * -***************************************************************/ - -/*************************************************************** -* L O C A L F U N C T I O N S * -***************************************************************/ - -extern int localDbPrepare(UserHandle *uh); - -static int dbCreate(UserHandle *uh); - -/*************************************************************** -* L O C A L D A T A * -***************************************************************/ - -static char *create_subscriber_table = -"CREATE TABLE subscriber(\ -subscriberNumber CHAR(12) NOT NULL primary key,\ -subscriberName CHAR(32) NOT NULL,\ -groupId INT NOT NULL,\ -location INT NOT NULL,\ -activeSessions INT NOT NULL,\ -changedBy CHAR(32) NOT NULL,\ -changedTime CHAR(32) NOT NULL)"; - -static char *create_group_table = -"CREATE TABLE userGroup(\ -groupId INT NOT NULL primary key,\ -groupName CHAR(32) NOT NULL,\ -allowRead INT NOT NULL,\ -allowInsert INT NOT NULL,\ -allowDelete INT NOT NULL)"; - -static char *create_server_table = "CREATE TABLE server(\ -serverId INT NOT NULL,\ -subscriberSuffix CHAR(2) NOT NULL,\ -serverName CHAR(32) NOT NULL,\ -noOfRead INT NOT NULL,\ -noOfInsert INT NOT NULL,\ -noOfDelete INT NOT NULL,\ -PRIMARY KEY(serverId,subscriberSuffix))"; - -static char *create_session_table = -"CREATE TABLE userSession(\ -subscriberNumber CHAR(12) NOT NULL,\ -serverId INT NOT NULL,\ -sessionData CHAR(2000) NOT NULL,\ -PRIMARY KEY(subscriberNumber,serverId))"; - -/*************************************************************** -* P U B L I C D A T A * -***************************************************************/ - - -/*************************************************************** -**************************************************************** -* L O C A L F U N C T I O N S C O D E S E C T I O N * -**************************************************************** -***************************************************************/ - -/*************************************************************** -**************************************************************** -* P U B L I C F U N C T I O N S C O D E S E C T I O N * -**************************************************************** -***************************************************************/ - -/*-----------------------------------*/ -/* Time related Functions */ -/* */ -/* Returns a double value in seconds */ -/*-----------------------------------*/ -double userGetTime(void) -{ - static int initialized = 0; - static struct timeval initTime; - double timeValue; - - if( !initialized ) { - initialized = 1; - gettimeofday(&initTime, 0); - timeValue = 0.0; - } - else { - struct timeval tv; - double s; - double us; - - gettimeofday(&tv, 0); - s = (double)tv.tv_sec - (double)initTime.tv_sec; - us = (double)tv.tv_usec - (double)initTime.tv_usec; - - timeValue = s + (us / 1000000.0); - } - - return(timeValue); -} - - -void handle_error(SQLHDBC hdbc, - SQLHENV henv, - SQLHSTMT hstmt, - SQLRETURN rc, - char *filename, - int lineno) -{ -#define MSG_LNG 512 - - int isError = 0; - SQLRETURN ret = SQL_SUCCESS; - SQLCHAR szSqlState[MSG_LNG]; /* SQL state string */ - SQLCHAR szErrorMsg[MSG_LNG]; /* Error msg text buffer pointer */ - SQLINTEGER pfNativeError; /* Native error code */ - SQLSMALLINT pcbErrorMsg; /* Error msg text Available bytes */ - - if ( rc == SQL_SUCCESS || rc == SQL_NO_DATA_FOUND ) - return; - else if ( rc == SQL_INVALID_HANDLE ) { - printf("ERROR in %s, line %d: invalid handle\n", - filename, lineno); - isError = 1; - } - else if ( rc == SQL_SUCCESS_WITH_INFO ) { - printf("WARNING in %s, line %d\n", - filename, lineno); - isError = 0; - } - else if ( rc == SQL_ERROR ) { - printf("ERROR in %s, line %d\n", - filename, lineno); - isError = 1; - } - - fflush(stdout); - - while ( ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO ) { - ret = SQLError(henv, hdbc, hstmt, szSqlState, &pfNativeError, szErrorMsg, - MSG_LNG, &pcbErrorMsg); - - switch (ret) { - case SQL_SUCCESS: - case SQL_SUCCESS_WITH_INFO: - printf("%s\n*** ODBC Error/Warning = %s, " - "Additional Error/Warning = %d\n", - szErrorMsg, szSqlState, pfNativeError); - - if(ret == SQL_SUCCESS_WITH_INFO) - printf("(Note: error message was truncated.\n"); - break; - - case SQL_INVALID_HANDLE: - printf("Call to SQLError failed with return code of " - "SQL_INVALID_HANDLE.\n"); - break; - - case SQL_ERROR: - printf("Call to SQLError failed with return code of SQL_ERROR.\n"); - break; - - case SQL_NO_DATA_FOUND: - break; - - default: - printf("Call to SQLError failed with return code of %d.\n", ret); - } - } - - if ( isError ) - exit(1); -} - -static int dbCreate(UserHandle *uh) -{ - SQLRETURN rc; - SQLHSTMT creatstmt; - - if(!uh) return(-1); - - rc = SQLAllocStmt(uh->hdbc, &creatstmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to allocate create statement\n"); - return(-1); - } - - rc = SQLExecDirect(creatstmt,(SQLCHAR *)create_subscriber_table, SQL_NTS); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to create subscriber table\n"); - return(-1); - } - - rc = SQLExecDirect(creatstmt,(SQLCHAR *)create_group_table, SQL_NTS); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to create group table\n"); - return(-1); - } - - rc = SQLExecDirect(creatstmt,(SQLCHAR *)create_server_table, SQL_NTS); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to create server table\n"); - return(-1); - } - - rc = SQLExecDirect(creatstmt,(SQLCHAR *)create_session_table, SQL_NTS); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to create session table\n"); - return(-1); - } - - rc = SQLTransact(uh->henv, uh->hdbc, SQL_COMMIT); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to commit all create table\n"); - return(-1); - } - - rc = SQLFreeStmt(creatstmt, SQL_DROP); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to free create statement\n"); - return(-1); - } - - return(0); -} - -UserHandle *userDbConnect(uint32 createDb, char *dbName) -{ - char connStrIn[512]; /* ODBC Connection String */ - char connStrOut[2048]; - SQLRETURN rc; - UserHandle *uh; - - /*--------------------------*/ - /* Build the Connect string */ - /*--------------------------*/ - sprintf(connStrIn, - "AutoCreate=%d;OverWrite=%d;DSN=%s", - createDb ? 1 : 0, - createDb ? 1 : 0, - dbName); - - uh = calloc(1, sizeof(UserHandle)); - if( !uh ) { - printf("Unable to allocate memory for Handle\n"); - return(0); - } - - /*---------------------------------*/ - /* Allocate the Environment Handle */ - /*---------------------------------*/ - rc = SQLAllocEnv(&uh->henv); - - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to allocate Environment Handle\n"); - return(0); - } - - /*--------------------------------*/ - /* Allocate the DB Connect Handle */ - /*--------------------------------*/ - rc = SQLAllocConnect(uh->henv, &uh->hdbc); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to allocate a connection handle\n"); - return(0); - } - - /*-------------------------*/ - /* Connect to the Database */ - /*-------------------------*/ - rc = SQLDriverConnect(uh->hdbc, NULL, - (SQLCHAR *)connStrIn, SQL_NTS, - (SQLCHAR *)connStrOut, sizeof (connStrOut), - NULL, SQL_DRIVER_NOPROMPT); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { -handle_error(uh->hdbc, uh->henv, NULL, rc, __FILE__, __LINE__); - printf("Unable to connect to database server\n"); - return(0); - } - - rc = SQLSetConnectOption(uh->hdbc, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to set connection option\n"); - return(0); - } - - rc = SQLAllocStmt(uh->hdbc, &uh->stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to allocate immediate statement\n"); - return(0); - } - - if( createDb ) - dbCreate(uh); - - if( localDbPrepare(uh) < 0 ) - return(0); - - return(uh); -} - -void userDbDisconnect(UserHandle *uh) -{ - SQLRETURN rc; - - if(!uh) return; - - rc = SQLDisconnect(uh->hdbc); - - SQLFreeConnect(uh->hdbc); - SQLFreeEnv(uh->henv); - free(uh); -} - -int userDbInsertServer(UserHandle *uh, - ServerId serverId, - SubscriberSuffix suffix, - ServerName name) -{ - SQLRETURN rc; - char buf[1000]; - - if(!uh) return(-1); - - sprintf(buf, "insert into server values (%d,'%.*s','%s',0,0,0)", - serverId, - SUBSCRIBER_NUMBER_SUFFIX_LENGTH, suffix, - name); - - rc = SQLExecDirect(uh->stmt, (unsigned char *)buf, SQL_NTS); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to execute insert server\n"); - return(-1); - } - - return( userDbCommit(uh) ); -} - -int userDbInsertSubscriber(UserHandle *uh, - SubscriberNumber number, - uint32 groupId, - SubscriberName name) -{ - SQLRETURN rc; - char buf[1000]; - - if(!uh) return(-1); - - sprintf(buf, "insert into subscriber values ('%s','%s',%d,0,0,'','')", - number, - name, - groupId); - - rc = SQLExecDirect(uh->stmt, (unsigned char*)buf, SQL_NTS); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to execute insert subscriber\n"); - return(-1); - } - - return( userDbCommit(uh) ); -} - -int userDbInsertGroup(UserHandle *uh, - GroupId groupId, - GroupName name, - Permission allowRead, - Permission allowInsert, - Permission allowDelete) -{ - SQLRETURN rc; - char buf[1000]; - - if(!uh) return(-1); - - sprintf(buf, "insert into usergroup values (%d,'%s',%d,%d,%d)", - groupId, - name, - allowRead, - allowInsert, - allowDelete); - - rc = SQLExecDirect(uh->stmt, (unsigned char*)buf, SQL_NTS); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to execute insert group\n"); - return(-1); - } - - return( userDbCommit(uh) ); -} - -int userDbCommit(UserHandle *uh) -{ - SQLRETURN rc; - if(!uh) return(-1); - - rc = SQLTransact(uh->henv, uh->hdbc, SQL_COMMIT); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { -handle_error(uh->hdbc, uh->henv, 0, rc, __FILE__, __LINE__); - printf("Unable to commit Transaction\n"); - return(-1); - } - - return(0); -} - -int userDbRollback(UserHandle *uh) -{ - SQLRETURN rc; - if(!uh) return(-1); - - rc = SQLTransact(uh->henv, uh->hdbc, SQL_ROLLBACK); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("Unable to rollback Transaction\n"); - return(-1); - } - - return(0); -} - -void userCheckpoint(UserHandle *uh) -{ - SQLRETURN rc; - if(!uh) return; - - rc = SQLExecDirect(uh->stmt, (SQLCHAR *)"call ttCheckpointFuzzy", SQL_NTS); - userDbCommit(uh); -} diff --git a/ndb/test/ndbapi/lmc-bench/src/user/old/userTransaction.c b/ndb/test/ndbapi/lmc-bench/src/user/old/userTransaction.c deleted file mode 100644 index a2f4787bb0c..00000000000 --- a/ndb/test/ndbapi/lmc-bench/src/user/old/userTransaction.c +++ /dev/null @@ -1,473 +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 */ - -/*************************************************************** -* I N C L U D E D F I L E S * -***************************************************************/ - -#include -#include - -#include "sql.h" -#include "sqlext.h" - - -#include "userInterface.h" -#include "userHandle.h" - -/*************************************************************** -* L O C A L C O N S T A N T S * -***************************************************************/ - -/*************************************************************** -* L O C A L D A T A S T R U C T U R E S * -***************************************************************/ - -/*************************************************************** -* L O C A L F U N C T I O N S * -***************************************************************/ - -static int readSubscriberSessions(UserHandle *uh, - SubscriberNumber number, - char *transactionType); - -/*************************************************************** -* L O C A L D A T A * -***************************************************************/ - -extern void handle_error(SQLHDBC hdbc, - SQLHENV henv, - SQLHSTMT hstmt, - SQLRETURN rc, - char *filename, - int lineno); - -/*************************************************************** -* P U B L I C D A T A * -***************************************************************/ - - -/*************************************************************** -**************************************************************** -* L O C A L F U N C T I O N S C O D E S E C T I O N * -**************************************************************** -***************************************************************/ - -static int readSubscriberSessions(UserHandle *uh, - SubscriberNumber number, - char *transactionType) -{ - SQLRETURN rc; - - /*-----------------------------------------------------*/ - /* SELECT activeSessions,groupId,changedBy,changedTime */ - /* FROM SUBSCRIBER */ - /* WHERE subscriberNumber=x; */ - /*-----------------------------------------------------*/ - strcpy(uh->readSubscriberSession.values.number,number); - - rc = SQLExecute(uh->readSubscriberSession.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("%s %s\n", - transactionType, - "Unable to execute read subscriber session"); - return(-1); - } - - rc = SQLFetch(uh->readSubscriberSession.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("%s %s\n", - transactionType, - "Unable to fetch read subscriber session"); - return(-1); - } - - return(0); -} - -/*************************************************************** -**************************************************************** -* P U B L I C F U N C T I O N S C O D E S E C T I O N * -**************************************************************** -***************************************************************/ - -void userTransaction_T1(UserHandle *uh, - SubscriberNumber number, - Location new_location, - ChangedBy changed_by, - ChangedTime changed_time) -{ - SQLRETURN rc; - - if(!uh) return; - - /*---------------------------------------------*/ - /* Update the subscriber information */ - /* */ - /* UPDATE SUBSCRIBER */ - /* SET location=x, changedBy=x, changedTime=x */ - /* WHERE subscriberNumber=x; */ - /*---------------------------------------------*/ - strcpy(uh->updateSubscriber.values.number, number); - uh->updateSubscriber.values.location = new_location; - strcpy(uh->updateSubscriber.values.changedBy, changed_by); - strcpy(uh->updateSubscriber.values.changedTime, changed_time); - - rc = SQLExecute(uh->updateSubscriber.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T1 Unable to execute update subscriber\n"); - return; - } - - userDbCommit(uh); -} - -void userTransaction_T2(UserHandle *uh, - SubscriberNumber number, - Location *new_location, - ChangedBy changed_by, - ChangedTime changed_time, - SubscriberName subscriberName) -{ - SQLRETURN rc; - - if(!uh) return; - - /*------------------------------------------------------*/ - /* Read the information from the subscriber table */ - /* */ - /* SELECT location,subscriberName,changedBy,changedTime */ - /* FROM SUBSCRIBER */ - /* WHERE subscriberNumber=x; */ - /*------------------------------------------------------*/ - strcpy(uh->readSubscriber.values.number,number); - - rc = SQLExecute(uh->readSubscriber.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T2 Unable to execute read subscriber\n"); - return; - } - - rc = SQLFetch(uh->readSubscriber.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T2 Unable to fetch read subscriber\n"); - return; - } - - userDbCommit(uh); - - strcpy(subscriberName, uh->readSubscriber.values.name); - *new_location = uh->readSubscriber.values.location; - strcpy(changed_by, uh->readSubscriber.values.changedBy); - strcpy(changed_time, uh->readSubscriber.values.changedTime); -} - -void userTransaction_T3(UserHandle *uh, - SubscriberNumber number, - ServerId server_id, - ServerBit server_bit, - SessionDetails session_details, - unsigned int *branch_executed) -{ - SQLRETURN rc; - - if(!uh) return; - - *branch_executed = 0; - - /*--------------------------------------*/ - /* Read active sessions from subscriber */ - /*--------------------------------------*/ - if( readSubscriberSessions(uh, number, "T3") < 0 ) - return; - - /*-----------------------------------------------*/ - /* Read the 'read' Permissions for the userGroup */ - /* */ - /* SELECT allowRead */ - /* FROM USERGROUP */ - /* WHERE groupId=x */ - /*-----------------------------------------------*/ - uh->readGroupAllowRead.values.groupId = uh->readSubscriberSession.values.groupId; - - rc = SQLExecute(uh->readGroupAllowRead.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T3 Unable to execute read group allow read\n"); - return; - } - - rc = SQLFetch(uh->readGroupAllowRead.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T3 Unable to fetch read group allow read\n"); - return; - } - - if( uh->readGroupAllowRead.values.allowRead & server_bit && - uh->readSubscriberSession.values.activeSessions & server_bit ) { - - /*----------------------------------------------------*/ - /* Read the sessionDetails from the userSession table */ - /* */ - /* SELECT sessionData */ - /* FROM userSession */ - /* WHERE subscriberNumber=x, serverId=x */ - /*----------------------------------------------------*/ - strcpy(uh->readSessionDetails.values.number,number); - uh->readSessionDetails.values.serverId = server_id; - - rc = SQLExecute(uh->readSessionDetails.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T3 Unable to execute read session details\n"); - return; - } - - rc = SQLFetch(uh->readSessionDetails.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T3 Unable to fetch read session details\n"); - return; - } - - strcpy(session_details, uh->readSessionDetails.values.details); - - /*----------------------------------------*/ - /* Increment noOfRead field in the server */ - /* */ - /* UPDATE server */ - /* SET noOfRead=noOfRead+1 */ - /* WHERE serverId=x,subscriberSuffix=x */ - /*----------------------------------------*/ - uh->updateServerNoOfRead.values.serverId = server_id; - strcpy(uh->updateServerNoOfRead.values.suffix, - &number[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH]); - - rc = SQLExecute(uh->updateServerNoOfRead.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T3 Unable to execute read no of read\n"); - return; - } - - *branch_executed = 1; - } - - userDbCommit(uh); -} - -void userTransaction_T4(UserHandle *uh, - SubscriberNumber number, - ServerId server_id, - ServerBit server_bit, - SessionDetails session_details, - unsigned int do_rollback, - unsigned int *branch_executed) -{ - SQLRETURN rc; - - if(!uh) return; - - *branch_executed = 0; - - /*--------------------------------------*/ - /* Read active sessions from subscriber */ - /*--------------------------------------*/ - if( readSubscriberSessions(uh, number, "T4") < 0 ) - return; - - /*-------------------------------------------------*/ - /* Read the 'insert' Permissions for the userGroup */ - /* */ - /* SELECT allowInsert */ - /* FROM USERGROUP */ - /* WHERE groupId=x */ - /*-------------------------------------------------*/ - uh->readGroupAllowInsert.values.groupId = uh->readSubscriberSession.values.groupId; - - rc = SQLExecute(uh->readGroupAllowInsert.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T4 Unable to execute read group allow insert\n"); - return; - } - - rc = SQLFetch(uh->readGroupAllowInsert.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T4 Unable to fetch read group allow insert\n"); - return; - } - - if( uh->readGroupAllowInsert.values.allowInsert & server_bit && - !(uh->readSubscriberSession.values.activeSessions & server_bit) ) { - - /*---------------------------------------------*/ - /* Insert the session to the userSession table */ - /* */ - /* INSERT INTO userSession */ - /* VALUES (x,x,x) */ - /*---------------------------------------------*/ - strcpy(uh->insertSession.values.number, number); - uh->insertSession.values.serverId = server_id; - strcpy(uh->insertSession.values.details, session_details); - - rc = SQLExecute(uh->insertSession.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { -handle_error(uh->hdbc, uh->henv, uh->insertSession.stmt, rc, __FILE__, __LINE__); - printf("T4 Unable to execute insert session \n"); - return; - } - - /*----------------------------------------*/ - /* Update subscriber activeSessions field */ - /* */ - /* UPDATE subscriber */ - /* SET activeSessions=x */ - /* WHERE subscriberNumber=x */ - /*----------------------------------------*/ - strcpy(uh->updateSubscriberSession.values.number, number); - uh->updateSubscriberSession.values.activeSessions = - uh->readSubscriberSession.values.activeSessions | server_bit; - - rc = SQLExecute(uh->updateSubscriberSession.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T4 Unable to execute update session \n"); - return; - } - - /*------------------------------------------*/ - /* Increment noOfInsert field in the server */ - /* */ - /* UPDATE server */ - /* SET noOfInsert=noOfInsert+1 */ - /* WHERE serverId=x,subscriberSuffix=x */ - /*------------------------------------------*/ - uh->updateServerNoOfInsert.values.serverId = server_id; - strcpy(uh->updateServerNoOfInsert.values.suffix, - &number[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH]); - - rc = SQLExecute(uh->updateServerNoOfInsert.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T4 Unable to execute update no of read\n"); - return; - } - - *branch_executed = 1; - } - - if(do_rollback) - userDbRollback(uh); - else - userDbCommit(uh); -} - -void userTransaction_T5(UserHandle *uh, - SubscriberNumber number, - ServerId server_id, - ServerBit server_bit, - unsigned int do_rollback, - unsigned int *branch_executed) -{ - SQLRETURN rc; - - if(!uh) return; - - *branch_executed = 0; - - /*--------------------------------------*/ - /* Read active sessions from subscriber */ - /*--------------------------------------*/ - if( readSubscriberSessions(uh, number, "T5") < 0 ) - return; - - /*-------------------------------------------------*/ - /* Read the 'delete' Permissions for the userGroup */ - /* */ - /* SELECT allowDelete */ - /* FROM USERGROUP */ - /* WHERE groupId=x */ - /*-------------------------------------------------*/ - uh->readGroupAllowDelete.values.groupId = uh->readSubscriberSession.values.groupId; - - rc = SQLExecute(uh->readGroupAllowDelete.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T5 Unable to execute read group allow delete\n"); - return; - } - - rc = SQLFetch(uh->readGroupAllowDelete.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T5 Unable to fetch read group allow delete\n"); - return; - } - - if( uh->readGroupAllowDelete.values.allowDelete & server_bit && - uh->readSubscriberSession.values.activeSessions & server_bit ) { - - /*-----------------------------------------------*/ - /* Delete the session from the userSession table */ - /* */ - /* DELETE FROM userSession */ - /* WHERE subscriberNumber=x,serverId=x */ - /*-----------------------------------------------*/ - strcpy(uh->deleteSession.values.number,number); - uh->deleteSession.values.serverId = server_id; - - rc = SQLExecute(uh->deleteSession.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T5 Unable to execute delete session\n"); - return; - } - - /*----------------------------------------*/ - /* Update subscriber activeSessions field */ - /* */ - /* UPDATE subscriber */ - /* SET activeSessions=x */ - /* WHERE subscriberNumber=x */ - /*----------------------------------------*/ - strcpy(uh->updateSubscriberSession.values.number, number); - uh->updateSubscriberSession.values.activeSessions = - uh->readSubscriberSession.values.activeSessions & ~server_bit; - - rc = SQLExecute(uh->updateSubscriberSession.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T5 Unable to execute update subscriber session \n"); - return; - } - - /*------------------------------------------*/ - /* Increment noOfDelete field in the server */ - /* */ - /* UPDATE server */ - /* SET noOfDelete=noOfDelete+1 */ - /* WHERE serverId=x,subscriberSuffix=x */ - /*------------------------------------------*/ - uh->updateServerNoOfDelete.values.serverId = server_id; - strcpy(uh->updateServerNoOfDelete.values.suffix, - &number[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH]); - - rc = SQLExecute(uh->updateServerNoOfDelete.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T5 Unable to execute update no of delete\n"); - return; - } - - *branch_executed = 1; - } - - if(do_rollback) - userDbRollback(uh); - else - userDbCommit(uh); -} - - diff --git a/ndb/test/ndbapi/lmc-bench/src/user/userHandle.h b/ndb/test/ndbapi/lmc-bench/src/user/userHandle.h deleted file mode 100644 index 6da76fc2bff..00000000000 --- a/ndb/test/ndbapi/lmc-bench/src/user/userHandle.h +++ /dev/null @@ -1,51 +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 */ - -#ifndef USERHANDLE_H -#define USERHANDLE_H - -/***************************************************************/ -/* I N C L U D E D F I L E S */ -/***************************************************************/ - -#include -#include "testDefinitions.h" - -/*************************************************************** -* M A C R O S * -***************************************************************/ - -/***************************************************************/ -/* C O N S T A N T S */ -/***************************************************************/ - -/*************************************************************** -* D A T A S T R U C T U R E S * -***************************************************************/ - -typedef Ndb userHandle; - -/*************************************************************** -* P U B L I C F U N C T I O N S * -***************************************************************/ - -/*************************************************************** -* E X T E R N A L D A T A * -***************************************************************/ - - -#endif /* USERHANDLE_H */ - diff --git a/ndb/test/ndbapi/lmc-bench/src/user/userInterface.cpp b/ndb/test/ndbapi/lmc-bench/src/user/userInterface.cpp deleted file mode 100644 index 67c4e037215..00000000000 --- a/ndb/test/ndbapi/lmc-bench/src/user/userInterface.cpp +++ /dev/null @@ -1,740 +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 */ - -/*************************************************************** -* I N C L U D E D F I L E S * -***************************************************************/ - -#include -#ifndef NDB_WIN32 -#include -#endif - -#include "ndb_error.hpp" -#include "userHandle.h" -#include "userInterface.h" -#include -#include -#include -#include -#include "ndb_schema.hpp" -#include - -/*************************************************************** -* L O C A L C O N S T A N T S * -***************************************************************/ - -/*************************************************************** -* L O C A L D A T A S T R U C T U R E S * -***************************************************************/ - -/*************************************************************** -* L O C A L F U N C T I O N S * -***************************************************************/ - -extern int localDbPrepare(UserHandle *uh); - -static int dbCreate(UserHandle *uh); - -/*************************************************************** -* L O C A L D A T A * -***************************************************************/ - -/*************************************************************** -* P U B L I C D A T A * -***************************************************************/ - - -/*************************************************************** -**************************************************************** -* L O C A L F U N C T I O N S C O D E S E C T I O N * -**************************************************************** -***************************************************************/ - -/*************************************************************** -**************************************************************** -* P U B L I C F U N C T I O N S C O D E S E C T I O N * -**************************************************************** -***************************************************************/ - -/*-----------------------------------*/ -/* Time related Functions */ -/* */ -/* Returns a double value in seconds */ -/*-----------------------------------*/ -double userGetTimeSync(void) -{ - static int initialized = 0; - static NDB_TICKS initSecs = 0; - static Uint32 initMicros = 0; - double timeValue = 0; - - if ( !initialized ) { - initialized = 1; - NdbTick_CurrentMicrosecond(&initSecs, &initMicros); - timeValue = 0.0; - } else { - NDB_TICKS secs = 0; - Uint32 micros = 0; - - NdbTick_CurrentMicrosecond(&secs, µs); - - double s = (double)secs - (double)initSecs; - double us = (double)secs - (double)initMicros; - - timeValue = s + (us / 1000000.0); - } - - return timeValue; -} - -// 0 - OK -// 1 - Retry transaction -// 2 - Permanent -int -userDbCommit(UserHandle *uh){ - if(uh->pCurrTrans != 0){ - int check = uh->pCurrTrans->execute( Commit ); - NdbError err = uh->pCurrTrans->getNdbError(); - uh->pNDB->closeTransaction(uh->pCurrTrans); - uh->pCurrTrans = 0; - - if(err.status != NdbError::Success) - ndbout << err << endl; - - if(err.status == NdbError::TemporaryError && - err.classification == NdbError::OverloadError){ - NdbSleep_SecSleep(3); - } - - return err.status; - } - return 2; -} - -/** - * TRUE - Normal table - * FALSE - Table w.o. checkpoing and logging - */ - -#ifdef __cplusplus -extern "C" { -#endif -extern int useTableLogging; -extern int useIndexTables; -#ifdef __cplusplus -} -#endif - - -int -create_table_server(Ndb * pNDB){ - - int check; - - NdbSchemaCon * MySchemaTransaction = pNDB->startSchemaTransaction(); - if( MySchemaTransaction == NULL ) - error_handler("startSchemaTransaction", pNDB->getNdbError(), 0); - - NdbSchemaOp * MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); - if( MySchemaOp == NULL ) - error_handler("getNdbSchemaOp", MySchemaTransaction->getNdbError(), 0); - - // Create table - check = MySchemaOp->createTable( SERVER_TABLE, - 8, // Table size - TupleKey, // Key Type - 1 // Nr of Pages - ,DistributionGroup, - 6, - 78, - 80, - 1, - useTableLogging - ); - if( check == -1 ) - error_handler("createTable", MySchemaTransaction->getNdbError(), 0); - - check = MySchemaOp->createAttribute - ( SERVER_SUBSCRIBER_SUFFIX, - TupleKey, - sizeof(char) << 3, - SUBSCRIBER_NUMBER_SUFFIX_LENGTH, - String, - MMBased, - NotNullAttribute, - NormalStorageAttribute, - 0, - 1, - 16); - if( check == -1 ) - error_handler("createAttribute (subscriber suffix)", - MySchemaTransaction->getNdbError(), 0); - - // Create first column, primary key - check = MySchemaOp->createAttribute( SERVER_ID, - TupleKey, - sizeof(ServerId) << 3, - 1, - UnSigned, - MMBased, - NotNullAttribute ); - if( check == -1 ) - error_handler("createAttribute (serverid)", - MySchemaTransaction->getNdbError(), 0); - - - check = MySchemaOp->createAttribute( SERVER_NAME, - NoKey, - sizeof(char) << 3, - SERVER_NAME_LENGTH, - String, - MMBased, - NotNullAttribute ); - if( check == -1 ) - error_handler("createAttribute (server name)", - MySchemaTransaction->getNdbError(), 0); - - - check = MySchemaOp->createAttribute( SERVER_READS, - NoKey, - sizeof(Counter) << 3, - 1, - UnSigned, - MMBased, - NotNullAttribute ); - if( check == -1 ) - error_handler("createAttribute (server reads)", - MySchemaTransaction->getNdbError(), 0); - - check = MySchemaOp->createAttribute( SERVER_INSERTS, - NoKey, - sizeof(Counter) << 3, - 1, - UnSigned, - MMBased, - NotNullAttribute ); - if( check == -1 ) - error_handler("createAttribute (server inserts)", - MySchemaTransaction->getNdbError(), 0); - - check = MySchemaOp->createAttribute( SERVER_DELETES, - NoKey, - sizeof(Counter) << 3, - 1, - UnSigned, - MMBased, - NotNullAttribute ); - if( check == -1 ) - error_handler("createAttribute (server deletes)", - MySchemaTransaction->getNdbError(), 0); - - if( MySchemaTransaction->execute() == -1 ) { - error_handler("schemaTransaction->execute()", - MySchemaTransaction->getNdbError(), 0); - } - pNDB->closeSchemaTransaction(MySchemaTransaction); - return 0; -} - -int -create_table_group(Ndb * pNDB){ - int check; - - NdbSchemaCon * MySchemaTransaction = pNDB->startSchemaTransaction(); - if( MySchemaTransaction == NULL ) - error_handler("startSchemaTransaction", pNDB->getNdbError(), 0); - - NdbSchemaOp * MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); - if( MySchemaOp == NULL ) - error_handler("getNdbSchemaOp", MySchemaTransaction->getNdbError(), 0); - - // Create table - check = MySchemaOp->createTable( GROUP_TABLE, - 8, // Table size - TupleKey, // Key Type - 1 // Nr of Pages - ,All, - 6, - 78, - 80, - 1, - useTableLogging - ); - - if( check == -1 ) - error_handler("createTable", MySchemaTransaction->getNdbError(), 0); - - // Create first column, primary key - check = MySchemaOp->createAttribute( GROUP_ID, - TupleKey, - sizeof(GroupId) << 3, - 1, - UnSigned, - MMBased, - NotNullAttribute ); - if( check == -1 ) - error_handler("createAttribute (group id)", - MySchemaTransaction->getNdbError(), 0); - - check = MySchemaOp->createAttribute( GROUP_NAME, - NoKey, - sizeof(char) << 3, - GROUP_NAME_LENGTH, - String, - MMBased, - NotNullAttribute ); - if( check == -1 ) - error_handler("createAttribute (group name)", - MySchemaTransaction->getNdbError(), 0); - - - check = MySchemaOp->createAttribute( GROUP_ALLOW_READ, - NoKey, - sizeof(Permission) << 3, - 1, - String, - MMBased, - NotNullAttribute ); - if( check == -1 ) - error_handler("createAttribute (group read)", - MySchemaTransaction->getNdbError(), 0); - - - check = MySchemaOp->createAttribute( GROUP_ALLOW_INSERT, - NoKey, - sizeof(Permission) << 3, - 1, - UnSigned, - MMBased, - NotNullAttribute ); - if( check == -1 ) - error_handler("createAttribute (group insert)", - MySchemaTransaction->getNdbError(), 0); - - check = MySchemaOp->createAttribute( GROUP_ALLOW_DELETE, - NoKey, - sizeof(Permission) << 3, - 1, - UnSigned, - MMBased, - NotNullAttribute ); - if( check == -1 ) - error_handler("createAttribute (group delete)", - MySchemaTransaction->getNdbError(), 0); - - if( MySchemaTransaction->execute() == -1 ) { - error_handler("schemaTransaction->execute()", - MySchemaTransaction->getNdbError(), 0); - } - pNDB->closeSchemaTransaction(MySchemaTransaction); - return 0; -} - -int -create_table_subscriber(Ndb * pNDB){ - int check; - NdbSchemaCon * MySchemaTransaction = pNDB->startSchemaTransaction(); - if( MySchemaTransaction == NULL ) - error_handler("startSchemaTransaction", pNDB->getNdbError(), 0); - - NdbSchemaOp * MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); - if( MySchemaOp == NULL ) - error_handler("getNdbSchemaOp", MySchemaTransaction->getNdbError(), 0); - - // Create table - check = MySchemaOp->createTable( SUBSCRIBER_TABLE, - 8, // Table size - TupleKey, // Key Type - 1 // Nr of Pages - ,DistributionGroup, - 6, - 78, - 80, - 1, - useTableLogging - ); - if( check == -1 ) - error_handler("createTable", MySchemaTransaction->getNdbError(), 0); - - // Create first column, primary key - check = MySchemaOp->createAttribute - ( SUBSCRIBER_NUMBER, - TupleKey, - sizeof(char) << 3, - SUBSCRIBER_NUMBER_LENGTH, - String, - MMBased, - NotNullAttribute, - (useIndexTables ? IndexStorageAttribute : NormalStorageAttribute), - 0, - 1, - 16); - if( check == -1 ) - error_handler("createAttribute (subscriber number)", - MySchemaTransaction->getNdbError(), 0); - - check = MySchemaOp->createAttribute( SUBSCRIBER_NAME, - NoKey, - sizeof(char) << 3, - SUBSCRIBER_NAME_LENGTH, - String, - MMBased, - NotNullAttribute ); - if( check == -1 ) - error_handler("createAttribute (subscriber name)", - MySchemaTransaction->getNdbError(), 0); - - - check = MySchemaOp->createAttribute( SUBSCRIBER_GROUP, - NoKey, - sizeof(GroupId) << 3, - 1, - UnSigned, - MMBased, - NotNullAttribute ); - if( check == -1 ) - error_handler("createAttribute (subscriber_group)", - MySchemaTransaction->getNdbError(), 0); - - - check = MySchemaOp->createAttribute( SUBSCRIBER_LOCATION, - NoKey, - sizeof(Location) << 3, - 1, - UnSigned, - MMBased, - NotNullAttribute ); - if( check == -1 ) - error_handler("createAttribute (server reads)", - MySchemaTransaction->getNdbError(), 0); - - check = MySchemaOp->createAttribute( SUBSCRIBER_SESSIONS, - NoKey, - sizeof(ActiveSessions) << 3, - 1, - UnSigned, - MMBased, - NotNullAttribute ); - if( check == -1 ) - error_handler("createAttribute (subscriber_sessions)", - MySchemaTransaction->getNdbError(), 0); - - check = MySchemaOp->createAttribute( SUBSCRIBER_CHANGED_BY, - NoKey, - sizeof(char) << 3, - CHANGED_BY_LENGTH, - String, - MMBased, - NotNullAttribute ); - if( check == -1 ) - error_handler("createAttribute (subscriber_changed_by)", - MySchemaTransaction->getNdbError(), 0); - - check = MySchemaOp->createAttribute( SUBSCRIBER_CHANGED_TIME, - NoKey, - sizeof(char) << 3, - CHANGED_TIME_LENGTH, - String, - MMBased, - NotNullAttribute ); - if( check == -1 ) - error_handler("createAttribute (subscriber_changed_time)", - MySchemaTransaction->getNdbError(), 0); - - if( MySchemaTransaction->execute() == -1 ) { - error_handler("schemaTransaction->execute()", - MySchemaTransaction->getNdbError(), 0); - } - pNDB->closeSchemaTransaction(MySchemaTransaction); - return 0; -} - -int -create_table_session(Ndb * pNDB){ - int check; - NdbSchemaCon * MySchemaTransaction = pNDB->startSchemaTransaction(); - if( MySchemaTransaction == NULL ) - error_handler("startSchemaTransaction", pNDB->getNdbError(), 0); - - NdbSchemaOp * MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); - if( MySchemaOp == NULL ) - error_handler("getNdbSchemaOp", - MySchemaTransaction->getNdbError(), 0); - - // Create table - check = MySchemaOp->createTable( SESSION_TABLE, - 8, // Table size - TupleKey, // Key Type - 1 // Nr of Pages - ,DistributionGroup, - 6, - 78, - 80, - 1, - useTableLogging - ); - if( check == -1 ) - error_handler("createTable", MySchemaTransaction->getNdbError(), 0); - - check = MySchemaOp->createAttribute( SESSION_SUBSCRIBER, - TupleKey, - sizeof(char) << 3, - SUBSCRIBER_NUMBER_LENGTH, - String, - MMBased, - NotNullAttribute, - NormalStorageAttribute, - 0, - 1, - 16); - if( check == -1 ) - error_handler("createAttribute (session_subscriber)", - MySchemaTransaction->getNdbError(), 0); - - // Create first column, primary key - check = MySchemaOp->createAttribute( SESSION_SERVER, - TupleKey, - sizeof(ServerId) << 3, - 1, - UnSigned, - MMBased, - NotNullAttribute ); - if( check == -1 ) - error_handler("createAttribute (session_server)", - MySchemaTransaction->getNdbError(), 0); - - - check = MySchemaOp->createAttribute( SESSION_DATA, - NoKey, - sizeof(char) << 3, - SESSION_DETAILS_LENGTH, - String, - MMBased, - NotNullAttribute ); - if( check == -1 ) - error_handler("createAttribute (session_data)", - MySchemaTransaction->getNdbError(), 0); - - if( MySchemaTransaction->execute() == -1 ) { - error_handler("schemaTransaction->execute()", - MySchemaTransaction->getNdbError(), 0); - } - pNDB->closeSchemaTransaction(MySchemaTransaction); - return 0; -} - -void -create_table(const char * name, int (* function)(Ndb * pNDB), Ndb* pNDB){ - printf("creating table %s...", name); - if(pNDB->getDictionary()->getTable(name) != 0){ - printf(" it already exists\n"); - return; - } else { - printf("\n"); - } - function(pNDB); - printf("creating table %s... done\n", name); -} - -static int dbCreate(Ndb * pNDB) -{ - create_table(SUBSCRIBER_TABLE, create_table_subscriber, pNDB); - create_table(GROUP_TABLE , create_table_group, pNDB); - create_table(SESSION_TABLE , create_table_session, pNDB); - create_table(SERVER_TABLE , create_table_server, pNDB); - return 0; -} - -#ifndef NDB_WIN32 -#include -#endif - -static NdbMutex* startupMutex = NdbMutex_Create(); - -UserHandle* -userDbConnect(uint32 createDb, char *dbName) -{ - NdbMutex_Lock(startupMutex); - - Ndb * pNDB = new Ndb(""); - - //printf("Initializing...\n"); - pNDB->init(); - - //printf("Waiting..."); - while(pNDB->waitUntilReady() != 0){ - //printf("..."); - } - // printf("done\n"); - - if( createDb ) - dbCreate(pNDB); - - - UserHandle * uh = new UserHandle; - uh->pNDB = pNDB; - uh->pCurrTrans = 0; - - NdbMutex_Unlock(startupMutex); - - return uh; -} - -void userDbDisconnect(UserHandle *uh) -{ - delete uh; -} - -int userDbInsertServer(UserHandle *uh, - ServerId serverId, - SubscriberSuffix suffix, - ServerName name) -{ - int check; - - uint32 noOfRead = 0; - uint32 noOfInsert = 0; - uint32 noOfDelete = 0; - - NdbConnection * MyTransaction = 0; - if(uh->pCurrTrans != 0){ - MyTransaction = uh->pCurrTrans; - } else { - uh->pCurrTrans = MyTransaction = uh->pNDB->startTransaction(); - } - if (MyTransaction == NULL) - error_handler("startTranscation", uh->pNDB->getNdbError(), 0); - - NdbOperation *MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); - CHECK_NULL(MyOperation, "getNdbOperation", MyTransaction); - - check = MyOperation->insertTuple(); - CHECK_MINUS_ONE(check, "insert tuple", MyTransaction); - - check = MyOperation->equal(SERVER_ID, (char*)&serverId); - CHECK_MINUS_ONE(check, "setValue id", MyTransaction); - - check = MyOperation->setValue(SERVER_SUBSCRIBER_SUFFIX, suffix); - CHECK_MINUS_ONE(check, "setValue suffix", MyTransaction); - - check = MyOperation->setValue(SERVER_NAME, name); - CHECK_MINUS_ONE(check, "setValue name", MyTransaction); - - check = MyOperation->setValue(SERVER_READS, (char*)&noOfRead); - CHECK_MINUS_ONE(check, "setValue reads", MyTransaction); - - check = MyOperation->setValue(SERVER_INSERTS, (char*)&noOfInsert); - CHECK_MINUS_ONE(check, "setValue inserts", MyTransaction); - - check = MyOperation->setValue(SERVER_DELETES, (char*)&noOfDelete); - CHECK_MINUS_ONE(check, "setValue deletes", MyTransaction); - - return 0; -} - -int userDbInsertSubscriber(UserHandle *uh, - SubscriberNumber number, - uint32 groupId, - SubscriberName name) -{ - int check; - uint32 activeSessions = 0; - Location l = 0; - ChangedBy changedBy; snprintf(changedBy, sizeof(changedBy), "ChangedBy"); - ChangedTime changedTime; snprintf(changedTime, sizeof(changedTime), "ChangedTime"); - - NdbConnection * MyTransaction = 0; - if(uh->pCurrTrans != 0){ - MyTransaction = uh->pCurrTrans; - } else { - uh->pCurrTrans = MyTransaction = uh->pNDB->startTransaction(); - } - if (MyTransaction == NULL) - error_handler("startTranscation", uh->pNDB->getNdbError(), 0); - - NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); - CHECK_NULL(MyOperation, "getNdbOperation", MyTransaction); - - check = MyOperation->insertTuple(); - CHECK_MINUS_ONE(check, "insertTuple", MyTransaction); - - check = MyOperation->equal(SUBSCRIBER_NUMBER, number); - CHECK_MINUS_ONE(check, "equal", MyTransaction); - - check = MyOperation->setValue(SUBSCRIBER_NAME, name); - CHECK_MINUS_ONE(check, "setValue name", MyTransaction); - - check = MyOperation->setValue(SUBSCRIBER_GROUP, (char*)&groupId); - CHECK_MINUS_ONE(check, "setValue group", MyTransaction); - - check = MyOperation->setValue(SUBSCRIBER_LOCATION, (char*)&l); - CHECK_MINUS_ONE(check, "setValue location", MyTransaction); - - check = MyOperation->setValue(SUBSCRIBER_SESSIONS, (char*)&activeSessions); - CHECK_MINUS_ONE(check, "setValue sessions", MyTransaction); - - check = MyOperation->setValue(SUBSCRIBER_CHANGED_BY, changedBy); - CHECK_MINUS_ONE(check, "setValue changedBy", MyTransaction); - - check = MyOperation->setValue(SUBSCRIBER_CHANGED_TIME, changedTime); - CHECK_MINUS_ONE(check, "setValue changedTime", MyTransaction); - - return 0; -} - -int userDbInsertGroup(UserHandle *uh, - GroupId groupId, - GroupName name, - Permission allowRead, - Permission allowInsert, - Permission allowDelete) -{ - int check; - - NdbConnection * MyTransaction = 0; - if(uh->pCurrTrans != 0){ - MyTransaction = uh->pCurrTrans; - } else { - uh->pCurrTrans = MyTransaction = uh->pNDB->startTransaction(); - } - if (MyTransaction == NULL) - error_handler("startTranscation", uh->pNDB->getNdbError(), 0); - - NdbOperation *MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); - CHECK_NULL(MyOperation, "getNdbOperation", MyTransaction); - - check = MyOperation->insertTuple(); - CHECK_MINUS_ONE(check, "insertTuple", MyTransaction); - - check = MyOperation->equal(GROUP_ID, (char*)&groupId); - CHECK_MINUS_ONE(check, "equal", MyTransaction); - - check = MyOperation->setValue(GROUP_NAME, name); - CHECK_MINUS_ONE(check, "setValue name", MyTransaction); - - check = MyOperation->setValue(GROUP_ALLOW_READ, (char*)&allowRead); - CHECK_MINUS_ONE(check, "setValue allowRead", MyTransaction); - - check = MyOperation->setValue(GROUP_ALLOW_INSERT, (char*)&allowInsert); - CHECK_MINUS_ONE(check, "setValue allowInsert", MyTransaction); - - check = MyOperation->setValue(GROUP_ALLOW_DELETE, (char*)&allowDelete); - CHECK_MINUS_ONE(check, "setValue allowDelete", MyTransaction); - - return 0; -} - diff --git a/ndb/test/ndbapi/lmc-bench/src/user/userTransaction.c b/ndb/test/ndbapi/lmc-bench/src/user/userTransaction.c deleted file mode 100644 index a2f4787bb0c..00000000000 --- a/ndb/test/ndbapi/lmc-bench/src/user/userTransaction.c +++ /dev/null @@ -1,473 +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 */ - -/*************************************************************** -* I N C L U D E D F I L E S * -***************************************************************/ - -#include -#include - -#include "sql.h" -#include "sqlext.h" - - -#include "userInterface.h" -#include "userHandle.h" - -/*************************************************************** -* L O C A L C O N S T A N T S * -***************************************************************/ - -/*************************************************************** -* L O C A L D A T A S T R U C T U R E S * -***************************************************************/ - -/*************************************************************** -* L O C A L F U N C T I O N S * -***************************************************************/ - -static int readSubscriberSessions(UserHandle *uh, - SubscriberNumber number, - char *transactionType); - -/*************************************************************** -* L O C A L D A T A * -***************************************************************/ - -extern void handle_error(SQLHDBC hdbc, - SQLHENV henv, - SQLHSTMT hstmt, - SQLRETURN rc, - char *filename, - int lineno); - -/*************************************************************** -* P U B L I C D A T A * -***************************************************************/ - - -/*************************************************************** -**************************************************************** -* L O C A L F U N C T I O N S C O D E S E C T I O N * -**************************************************************** -***************************************************************/ - -static int readSubscriberSessions(UserHandle *uh, - SubscriberNumber number, - char *transactionType) -{ - SQLRETURN rc; - - /*-----------------------------------------------------*/ - /* SELECT activeSessions,groupId,changedBy,changedTime */ - /* FROM SUBSCRIBER */ - /* WHERE subscriberNumber=x; */ - /*-----------------------------------------------------*/ - strcpy(uh->readSubscriberSession.values.number,number); - - rc = SQLExecute(uh->readSubscriberSession.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("%s %s\n", - transactionType, - "Unable to execute read subscriber session"); - return(-1); - } - - rc = SQLFetch(uh->readSubscriberSession.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("%s %s\n", - transactionType, - "Unable to fetch read subscriber session"); - return(-1); - } - - return(0); -} - -/*************************************************************** -**************************************************************** -* P U B L I C F U N C T I O N S C O D E S E C T I O N * -**************************************************************** -***************************************************************/ - -void userTransaction_T1(UserHandle *uh, - SubscriberNumber number, - Location new_location, - ChangedBy changed_by, - ChangedTime changed_time) -{ - SQLRETURN rc; - - if(!uh) return; - - /*---------------------------------------------*/ - /* Update the subscriber information */ - /* */ - /* UPDATE SUBSCRIBER */ - /* SET location=x, changedBy=x, changedTime=x */ - /* WHERE subscriberNumber=x; */ - /*---------------------------------------------*/ - strcpy(uh->updateSubscriber.values.number, number); - uh->updateSubscriber.values.location = new_location; - strcpy(uh->updateSubscriber.values.changedBy, changed_by); - strcpy(uh->updateSubscriber.values.changedTime, changed_time); - - rc = SQLExecute(uh->updateSubscriber.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T1 Unable to execute update subscriber\n"); - return; - } - - userDbCommit(uh); -} - -void userTransaction_T2(UserHandle *uh, - SubscriberNumber number, - Location *new_location, - ChangedBy changed_by, - ChangedTime changed_time, - SubscriberName subscriberName) -{ - SQLRETURN rc; - - if(!uh) return; - - /*------------------------------------------------------*/ - /* Read the information from the subscriber table */ - /* */ - /* SELECT location,subscriberName,changedBy,changedTime */ - /* FROM SUBSCRIBER */ - /* WHERE subscriberNumber=x; */ - /*------------------------------------------------------*/ - strcpy(uh->readSubscriber.values.number,number); - - rc = SQLExecute(uh->readSubscriber.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T2 Unable to execute read subscriber\n"); - return; - } - - rc = SQLFetch(uh->readSubscriber.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T2 Unable to fetch read subscriber\n"); - return; - } - - userDbCommit(uh); - - strcpy(subscriberName, uh->readSubscriber.values.name); - *new_location = uh->readSubscriber.values.location; - strcpy(changed_by, uh->readSubscriber.values.changedBy); - strcpy(changed_time, uh->readSubscriber.values.changedTime); -} - -void userTransaction_T3(UserHandle *uh, - SubscriberNumber number, - ServerId server_id, - ServerBit server_bit, - SessionDetails session_details, - unsigned int *branch_executed) -{ - SQLRETURN rc; - - if(!uh) return; - - *branch_executed = 0; - - /*--------------------------------------*/ - /* Read active sessions from subscriber */ - /*--------------------------------------*/ - if( readSubscriberSessions(uh, number, "T3") < 0 ) - return; - - /*-----------------------------------------------*/ - /* Read the 'read' Permissions for the userGroup */ - /* */ - /* SELECT allowRead */ - /* FROM USERGROUP */ - /* WHERE groupId=x */ - /*-----------------------------------------------*/ - uh->readGroupAllowRead.values.groupId = uh->readSubscriberSession.values.groupId; - - rc = SQLExecute(uh->readGroupAllowRead.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T3 Unable to execute read group allow read\n"); - return; - } - - rc = SQLFetch(uh->readGroupAllowRead.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T3 Unable to fetch read group allow read\n"); - return; - } - - if( uh->readGroupAllowRead.values.allowRead & server_bit && - uh->readSubscriberSession.values.activeSessions & server_bit ) { - - /*----------------------------------------------------*/ - /* Read the sessionDetails from the userSession table */ - /* */ - /* SELECT sessionData */ - /* FROM userSession */ - /* WHERE subscriberNumber=x, serverId=x */ - /*----------------------------------------------------*/ - strcpy(uh->readSessionDetails.values.number,number); - uh->readSessionDetails.values.serverId = server_id; - - rc = SQLExecute(uh->readSessionDetails.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T3 Unable to execute read session details\n"); - return; - } - - rc = SQLFetch(uh->readSessionDetails.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T3 Unable to fetch read session details\n"); - return; - } - - strcpy(session_details, uh->readSessionDetails.values.details); - - /*----------------------------------------*/ - /* Increment noOfRead field in the server */ - /* */ - /* UPDATE server */ - /* SET noOfRead=noOfRead+1 */ - /* WHERE serverId=x,subscriberSuffix=x */ - /*----------------------------------------*/ - uh->updateServerNoOfRead.values.serverId = server_id; - strcpy(uh->updateServerNoOfRead.values.suffix, - &number[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH]); - - rc = SQLExecute(uh->updateServerNoOfRead.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T3 Unable to execute read no of read\n"); - return; - } - - *branch_executed = 1; - } - - userDbCommit(uh); -} - -void userTransaction_T4(UserHandle *uh, - SubscriberNumber number, - ServerId server_id, - ServerBit server_bit, - SessionDetails session_details, - unsigned int do_rollback, - unsigned int *branch_executed) -{ - SQLRETURN rc; - - if(!uh) return; - - *branch_executed = 0; - - /*--------------------------------------*/ - /* Read active sessions from subscriber */ - /*--------------------------------------*/ - if( readSubscriberSessions(uh, number, "T4") < 0 ) - return; - - /*-------------------------------------------------*/ - /* Read the 'insert' Permissions for the userGroup */ - /* */ - /* SELECT allowInsert */ - /* FROM USERGROUP */ - /* WHERE groupId=x */ - /*-------------------------------------------------*/ - uh->readGroupAllowInsert.values.groupId = uh->readSubscriberSession.values.groupId; - - rc = SQLExecute(uh->readGroupAllowInsert.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T4 Unable to execute read group allow insert\n"); - return; - } - - rc = SQLFetch(uh->readGroupAllowInsert.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T4 Unable to fetch read group allow insert\n"); - return; - } - - if( uh->readGroupAllowInsert.values.allowInsert & server_bit && - !(uh->readSubscriberSession.values.activeSessions & server_bit) ) { - - /*---------------------------------------------*/ - /* Insert the session to the userSession table */ - /* */ - /* INSERT INTO userSession */ - /* VALUES (x,x,x) */ - /*---------------------------------------------*/ - strcpy(uh->insertSession.values.number, number); - uh->insertSession.values.serverId = server_id; - strcpy(uh->insertSession.values.details, session_details); - - rc = SQLExecute(uh->insertSession.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { -handle_error(uh->hdbc, uh->henv, uh->insertSession.stmt, rc, __FILE__, __LINE__); - printf("T4 Unable to execute insert session \n"); - return; - } - - /*----------------------------------------*/ - /* Update subscriber activeSessions field */ - /* */ - /* UPDATE subscriber */ - /* SET activeSessions=x */ - /* WHERE subscriberNumber=x */ - /*----------------------------------------*/ - strcpy(uh->updateSubscriberSession.values.number, number); - uh->updateSubscriberSession.values.activeSessions = - uh->readSubscriberSession.values.activeSessions | server_bit; - - rc = SQLExecute(uh->updateSubscriberSession.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T4 Unable to execute update session \n"); - return; - } - - /*------------------------------------------*/ - /* Increment noOfInsert field in the server */ - /* */ - /* UPDATE server */ - /* SET noOfInsert=noOfInsert+1 */ - /* WHERE serverId=x,subscriberSuffix=x */ - /*------------------------------------------*/ - uh->updateServerNoOfInsert.values.serverId = server_id; - strcpy(uh->updateServerNoOfInsert.values.suffix, - &number[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH]); - - rc = SQLExecute(uh->updateServerNoOfInsert.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T4 Unable to execute update no of read\n"); - return; - } - - *branch_executed = 1; - } - - if(do_rollback) - userDbRollback(uh); - else - userDbCommit(uh); -} - -void userTransaction_T5(UserHandle *uh, - SubscriberNumber number, - ServerId server_id, - ServerBit server_bit, - unsigned int do_rollback, - unsigned int *branch_executed) -{ - SQLRETURN rc; - - if(!uh) return; - - *branch_executed = 0; - - /*--------------------------------------*/ - /* Read active sessions from subscriber */ - /*--------------------------------------*/ - if( readSubscriberSessions(uh, number, "T5") < 0 ) - return; - - /*-------------------------------------------------*/ - /* Read the 'delete' Permissions for the userGroup */ - /* */ - /* SELECT allowDelete */ - /* FROM USERGROUP */ - /* WHERE groupId=x */ - /*-------------------------------------------------*/ - uh->readGroupAllowDelete.values.groupId = uh->readSubscriberSession.values.groupId; - - rc = SQLExecute(uh->readGroupAllowDelete.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T5 Unable to execute read group allow delete\n"); - return; - } - - rc = SQLFetch(uh->readGroupAllowDelete.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T5 Unable to fetch read group allow delete\n"); - return; - } - - if( uh->readGroupAllowDelete.values.allowDelete & server_bit && - uh->readSubscriberSession.values.activeSessions & server_bit ) { - - /*-----------------------------------------------*/ - /* Delete the session from the userSession table */ - /* */ - /* DELETE FROM userSession */ - /* WHERE subscriberNumber=x,serverId=x */ - /*-----------------------------------------------*/ - strcpy(uh->deleteSession.values.number,number); - uh->deleteSession.values.serverId = server_id; - - rc = SQLExecute(uh->deleteSession.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T5 Unable to execute delete session\n"); - return; - } - - /*----------------------------------------*/ - /* Update subscriber activeSessions field */ - /* */ - /* UPDATE subscriber */ - /* SET activeSessions=x */ - /* WHERE subscriberNumber=x */ - /*----------------------------------------*/ - strcpy(uh->updateSubscriberSession.values.number, number); - uh->updateSubscriberSession.values.activeSessions = - uh->readSubscriberSession.values.activeSessions & ~server_bit; - - rc = SQLExecute(uh->updateSubscriberSession.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T5 Unable to execute update subscriber session \n"); - return; - } - - /*------------------------------------------*/ - /* Increment noOfDelete field in the server */ - /* */ - /* UPDATE server */ - /* SET noOfDelete=noOfDelete+1 */ - /* WHERE serverId=x,subscriberSuffix=x */ - /*------------------------------------------*/ - uh->updateServerNoOfDelete.values.serverId = server_id; - strcpy(uh->updateServerNoOfDelete.values.suffix, - &number[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH]); - - rc = SQLExecute(uh->updateServerNoOfDelete.stmt); - if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { - printf("T5 Unable to execute update no of delete\n"); - return; - } - - *branch_executed = 1; - } - - if(do_rollback) - userDbRollback(uh); - else - userDbCommit(uh); -} - - diff --git a/ndb/test/ndbapi/mainAsyncGenerator.cpp b/ndb/test/ndbapi/mainAsyncGenerator.cpp new file mode 100644 index 00000000000..f613c66d07b --- /dev/null +++ b/ndb/test/ndbapi/mainAsyncGenerator.cpp @@ -0,0 +1,392 @@ +/* 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 */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "userInterface.h" +#include "dbGenerator.h" + +static int numProcesses; +static int numSeconds; +static int numWarmSeconds; +static int parallellism; +static int millisSendPoll; +static int minEventSendPoll; +static int forceSendPoll; + +static ThreadData *data; + +static void usage(const char *prog) +{ + const char *progname; + + /*--------------------------------------------*/ + /* Get the name of the program (without path) */ + /*--------------------------------------------*/ + progname = strrchr(prog, '/'); + + if (progname == 0) + progname = prog; + else + ++progname; + + ndbout_c( + "Usage: %s [-proc ] [-warm ] [-time ] [ -p ] " + "[-t ] [ -e ] [ -f ] \n" + " -proc Specifies that is the number of\n" + " threads. The default is 1.\n" + " -time Specifies that the test will run for sec.\n" + " The default is 10 sec\n" + " -warm Specifies the warm-up/cooldown period of " + "sec.\n" + " The default is 10 sec\n" + " -p The no of parallell transactions started by " + "one thread\n" + " -e Minimum no of events before wake up in call to " + "sendPoll\n" + " Default is 1\n" + " -f force parameter to sendPoll\n" + " Default is 0\n", + progname); +} + +static +int +parse_args(int argc, const char **argv) +{ + int i; + + numProcesses = 1; + numSeconds = 10; + numWarmSeconds = 10; + parallellism = 1; + millisSendPoll = 10000; + minEventSendPoll = 1; + forceSendPoll = 0; + + + i = 1; + while (i < argc){ + if (strcmp("-proc",argv[i]) == 0) { + if (i + 1 >= argc) { + return 1; + } + if (sscanf(argv[i+1], "%d", &numProcesses) == -1 || + numProcesses <= 0 || numProcesses > 127) { + ndbout_c("-proc flag requires a positive integer argument [1..127]"); + return 1; + } + i += 2; + } else if (strcmp("-p", argv[i]) == 0){ + if(i + 1 >= argc){ + usage(argv[0]); + return 1; + } + if (sscanf(argv[i+1], "%d", ¶llellism) == -1 || + parallellism <= 0){ + ndbout_c("-p flag requires a positive integer argument"); + return 1; + } + i += 2; + } + else if (strcmp("-time",argv[i]) == 0) { + if (i + 1 >= argc) { + return 1; + } + if (sscanf(argv[i+1], "%d", &numSeconds) == -1 || + numSeconds < 0) { + ndbout_c("-time flag requires a positive integer argument"); + return 1; + } + i += 2; + } + else if (strcmp("-warm",argv[i]) == 0) { + if (i + 1 >= argc) { + return 1; + } + if (sscanf(argv[i+1], "%d", &numWarmSeconds) == -1 || + numWarmSeconds < 0) { + ndbout_c("-warm flag requires a positive integer argument"); + return 1; + } + i += 2; + } + else if (strcmp("-e",argv[i]) == 0) { + if (i + 1 >= argc) { + return 1; + } + if (sscanf(argv[i+1], "%d", &minEventSendPoll) == -1 || + minEventSendPoll < 0) { + ndbout_c("-e flag requires a positive integer argument"); + return 1; + } + i += 2; + } + else if (strcmp("-f",argv[i]) == 0) { + if (i + 1 >= argc) { + usage(argv[0]); + return 1; + } + if (sscanf(argv[i+1], "%d", &forceSendPoll) == -1 || + forceSendPoll < 0) { + ndbout_c("-f flag requires a positive integer argument"); + return 1; + } + i += 2; + } + else { + return 1; + } + } + + if(minEventSendPoll > parallellism){ + ndbout_c("minEventSendPoll(%d) > parallellism(%d)", + minEventSendPoll, parallellism); + ndbout_c("not very good..."); + ndbout_c("very bad..."); + ndbout_c("exiting..."); + return 1; + } + return 0; +} + +static +void +print_transaction(const char *header, + unsigned long totalCount, + TransactionDefinition *trans, + unsigned int printBranch, + unsigned int printRollback) +{ + double f; + + ndbout_c(" %s: %d (%.2f%%) " + "Latency(ms) avg: %d min: %d max: %d std: %d n: %d", + header, + trans->count, + (double)trans->count / (double)totalCount * 100.0, + (int)trans->latency.getMean(), + (int)trans->latency.getMin(), + (int)trans->latency.getMax(), + (int)trans->latency.getStddev(), + (int)trans->latency.getCount() + ); + + if( printBranch ){ + if( trans->count == 0 ) + f = 0.0; + else + f = (double)trans->branchExecuted / (double)trans->count * 100.0; + ndbout_c(" Branches Executed: %d (%.2f%%)", trans->branchExecuted, f); + } + + if( printRollback ){ + if( trans->count == 0 ) + f = 0.0; + else + f = (double)trans->rollbackExecuted / (double)trans->count * 100.0; + ndbout_c(" Rollback Executed: %d (%.2f%%)",trans->rollbackExecuted,f); + } +} + +void +print_stats(const char *title, + unsigned int length, + unsigned int transactionFlag, + GeneratorStatistics *gen, + int numProc, int parallellism) +{ + int i; + char buf[10]; + char name[MAXHOSTNAMELEN]; + + name[0] = 0; + NdbHost_GetHostName(name); + + ndbout_c("\n------ %s ------",title); + ndbout_c("Length : %d %s", + length, + transactionFlag ? "Transactions" : "sec"); + ndbout_c("Processor : %s", name); + ndbout_c("Number of Proc: %d",numProc); + ndbout_c("Parallellism : %d", parallellism); + ndbout_c("\n"); + + if( gen->totalTransactions == 0 ) { + ndbout_c(" No Transactions for this test"); + } + else { + for(i = 0; i < 5; i++) { + sprintf(buf, "T%d",i+1); + print_transaction(buf, + gen->totalTransactions, + &gen->transactions[i], + i >= 2, + i >= 3 ); + } + + ndbout_c("\n"); + ndbout_c(" Overall Statistics:"); + ndbout_c(" Transactions: %d", gen->totalTransactions); + ndbout_c(" Outer : %.0f TPS",gen->outerTps); + ndbout_c("\n"); + } +} + +static +void * +threadRoutine(void *arg) +{ + int i; + ThreadData *data = (ThreadData *)arg; + Ndb * pNDB; + + pNDB = asyncDbConnect(parallellism); + /* NdbSleep_MilliSleep(rand() % 10); */ + + for(i = 0; ipThread = pThread; + } else { + perror("Failed to create thread"); + rc = NDBT_FAILED; + } + } + + showTime(); + + /*--------------------------------*/ + /* Wait for all processes to exit */ + /*--------------------------------*/ + for(i = 0; i < numProcesses; i++) { + NdbThread_WaitFor(data[i*parallellism].pThread, &tmp); + NdbThread_Destroy(&data[i*parallellism].pThread); + } + + ndbout_c("All threads have finished"); + + /*-------------------------------------------*/ + /* Clear all structures for total statistics */ + /*-------------------------------------------*/ + stats.totalTransactions = 0; + stats.outerTps = 0.0; + + for(i = 0; i < NUM_TRANSACTION_TYPES; i++ ) { + stats.transactions[i].count = 0; + stats.transactions[i].branchExecuted = 0; + stats.transactions[i].rollbackExecuted = 0; + stats.transactions[i].latency.reset(); + } + + /*--------------------------------*/ + /* Add the values for all Threads */ + /*--------------------------------*/ + for(i = 0; i < numProcesses; i++) { + for(k = 0; ktotalTransactions; + stats.outerTps += p->outerTps; + + for(j = 0; j < NUM_TRANSACTION_TYPES; j++ ) { + stats.transactions[j].count += + p->transactions[j].count; + stats.transactions[j].branchExecuted += + p->transactions[j].branchExecuted; + stats.transactions[j].rollbackExecuted += + p->transactions[j].rollbackExecuted; + stats.transactions[j].latency += + p->transactions[j].latency; + } + } + } + + print_stats("Test Results", + numSeconds, + 0, + &stats, + numProcesses, + parallellism); + + free(data); + + NDBT_ProgramExit(rc); +} diff --git a/ndb/test/ndbapi/msa.cpp b/ndb/test/ndbapi/msa.cpp new file mode 100644 index 00000000000..39ddaac2019 --- /dev/null +++ b/ndb/test/ndbapi/msa.cpp @@ -0,0 +1,1203 @@ +/* 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 */ + +#include + +#include +#include +#include +#include +#include +#include + +const char* const c_szDatabaseName = "TEST_DB"; + +const char* const c_szTableNameStored = "CCStored"; +const char* const c_szTableNameTemp = "CCTemp"; + +const char* const c_szContextId = "ContextId"; +const char* const c_szVersion = "Version"; +const char* const c_szLockFlag = "LockFlag"; +const char* const c_szLockTime = "LockTime"; +const char* const c_szLockTimeUSec = "LockTimeUSec"; +const char* const c_szContextData = "ContextData"; + +const char* g_szTableName = c_szTableNameStored; + + +#ifdef NDB_WIN32 +HANDLE hShutdownEvent = 0; +#else +#include +bool bShutdownEvent = false; +#endif +long g_nMaxContextIdPerThread = 5000; +long g_nNumThreads = 0; +long g_nMaxCallsPerSecond = 0; +long g_nMaxRetry = 50; +bool g_bWriteTuple = false; +bool g_bInsertInitial = false; +bool g_bVerifyInitial = false; + +NdbMutex* g_pNdbMutexPrintf = 0; +NdbMutex* g_pNdbMutexIncrement = 0; +long g_nNumCallsProcessed = 0; +NDB_TICKS g_tStartTime = 0; +NDB_TICKS g_tEndTime = 0; + +long g_nNumberOfInitialInsert = 0; +long g_nNumberOfInitialVerify = 0; + +const long c_nMaxMillisecForAllCall = 5000; +long* g_plCountMillisecForCall = 0; +const long c_nMaxMillisecForAllTrans = 5000; +long* g_plCountMillisecForTrans = 0; +bool g_bReport = false; +bool g_bReportPlus = false; + + +// data for CALL_CONTEXT and GROUP_RESOURCE +static char STATUS_DATA[]= +"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F" +"101112131415161718191A1B1C1D1E1F000102030405060708090A0B0C0D0E0F" +"202122232425262728292A2B2C2D2E2F000102030405060708090A0B0C0D0E0F" +"303132333435363738393A3B3C3D3E3F000102030405060708090A0B0C0D0E0F" +"404142434445464748494A4B4C4D4E4F000102030405060708090A0B0C0D0E0F" +"505152535455565758595A5B5C5D5E5F000102030405060708090A0B0C0D0E0F" +"606162636465666768696A6B6C6D6E6F000102030405060708090A0B0C0D0E0F" +"707172737475767778797A7B7C7D7E7F000102030405060708090A0B0C0D0E0F" +"808182838485868788898A8B8C8D8E8F000102030405060708090A0B0C0D0E0F" +"909192939495969798999A9B9C9D9E9F000102030405060708090A0B0C0D0E0F" +"10010110210310410510610710810910A000102030405060708090A0B0C0D0EF" +"10B10C10D10E10F110111112113114115000102030405060708090A0B0C0D0EF" +"11611711811911A11B11C11D11E11F120000102030405060708090A0B0C0D0EF" +"12112212312412512612712812912A12B000102030405060708090A0B0C0D0EF" +"12C12D12E12F130131132134135136137000102030405060708090A0B0C0D0EF" +"13813913A13B13C13D13E13F140141142000102030405060708090A0B0C0D0EF" +"14314414514614714814914A14B14C14D000102030405060708090A0B0C0D0EF" +"14E14F150151152153154155156157158000102030405060708090A0B0C0D0EF" +"15915A15B15C15D15E15F160161162163000102030405060708090A0B0C0D0EF" +"16416516616716816916A16B16C16D16E000102030405060708090A0B0C0D0EF" +"16F170171172173174175176177178179000102030405060708090A0B0C0D0EF" +"17A17B17C17D17E17F180181182183184000102030405060708090A0B0C0D0EF" +"18518618718818918A18B18C18D18E18F000102030405060708090A0B0C0D0EF" +"19019119219319419519619719819919A000102030405060708090A0B0C0D0EF" +"19B19C19D19E19F200201202203204205000102030405060708090A0B0C0D0EF" +"20620720820920A20B20C20D20F210211000102030405060708090A0B0C0D0EF" +"21221321421521621721821921A21B21C000102030405060708090A0B0C0D0EF" +"21D21E21F220221222223224225226227000102030405060708090A0B0C0D0EF" +"22822922A22B22C22D22E22F230231232000102030405060708090A0B0C0D0EF" +"23323423523623723823923A23B23C23D000102030405060708090A0B0C0D0EF" +"23E23F240241242243244245246247248000102030405060708090A0B0C0D0EF" +"24924A24B24C24D24E24F250251252253000102030405060708090A0B0C0D0EF" +"101112131415161718191A1B1C1D1E1F000102030405060708090A0B0C0D0E0F" +"202122232425262728292A2B2C2D2E2F000102030405060708090A0B0C0D0E0F" +"303132333435363738393A3B3C3D3E3F000102030405060708090A0B0C0D0E0F" +"404142434445464748494A4B4C4D4E4F000102030405060708090A0B0C0D0E0F" +"505152535455565758595A5B5C5D5E5F000102030405060708090A0B0C0D0E0F" +"606162636465666768696A6B6C6D6E6F000102030405060708090A0B0C0D0E0F" +"707172737475767778797A7B7C7D7E7F000102030405060708090A0B0C0D0E0F" +"808182838485868788898A8B8C8D8E8F000102030405060708090A0B0C0D0E0F" +"909192939495969798999A9B9C9D9E9F000102030405060708090A0B0C0D0E0F" +"10010110210310410510610710810910A000102030405060708090A0B0C0D0EF" +"10B10C10D10E10F110111112113114115000102030405060708090A0B0C0D0EF" +"11611711811911A11B11C11D11E11F120000102030405060708090A0B0C0D0EF" +"12112212312412512612712812912A12B000102030405060708090A0B0C0D0EF" +"12C12D12E12F130131132134135136137000102030405060708090A0B0C0D0EF" +"13813913A13B13C13D13E13F140141142000102030405060708090A0B0C0D0EF" +"14314414514614714814914A14B14C14D000102030405060708090A0B0C0D0EF" +"14E14F150151152153154155156157158000102030405060708090A0B0C0D0EF" +"15915A15B15C15D15E15F160161162163000102030405060708090A0B0C0D0EF" +"16416516616716816916A16B16C16D16E000102030405060708090A0B0C0D0EF" +"16F170171172173174175176177178179000102030405060708090A0B0C0D0EF" +"17A17B17C17D17E17F180181182183184000102030405060708090A0B0C0D0EF" +"18518618718818918A18B18C18D18E18F000102030405060708090A0B0C0D0EF" +"19019119219319419519619719819919A000102030405060708090A0B0C0D0EF" +"19B19C19D19E19F200201202203204205000102030405060708090A0B0C0D0EF" +"20620720820920A20B20C20D20F210211000102030405060708090A0B0C0D0EF" +"21221321421521621721821921A21B21C000102030405060708090A0B0C0D0EF" +"21D21E21F220221222223224225226227000102030405060708090A0B0C0D0EF" +"22822922A22B22C22D22E22F230231232000102030405060708090A0B0C0D0EF" +"23323423523623723823923A23B23C23D000102030405060708090A0B0C0D0EF" +"2366890FE1438751097E7F6325DC0E6326F" +"25425525625725825925A25B25C25D25E25F000102030405060708090A0B0C0F"; + +long g_nStatusDataSize = sizeof(STATUS_DATA); + + +// Thread function for Call Context Inserts + + +#ifdef NDB_WIN32 + +BOOL WINAPI ConsoleCtrlHandler(DWORD dwCtrlType) +{ + if(CTRL_C_EVENT == dwCtrlType) + { + SetEvent(hShutdownEvent); + return TRUE; + } + return FALSE; +} + +#else + +void CtrlCHandler(int) +{ + bShutdownEvent = true; +} + +#endif + + + +void ReportNdbError(const char* szMsg, const NdbError& err) +{ + NdbMutex_Lock(g_pNdbMutexPrintf); + printf("%s: %d: %s\n", szMsg, err.code, (err.message ? err.message : "")); + NdbMutex_Unlock(g_pNdbMutexPrintf); +} + + +void +ReportCallsPerSecond(long nNumCallsProcessed, + NDB_TICKS tStartTime, + NDB_TICKS tEndTime) +{ + NDB_TICKS tElapsed = tEndTime - tStartTime; + long lCallsPerSec; + if(tElapsed>0) + lCallsPerSec = (long)((1000*nNumCallsProcessed)/tElapsed); + else + lCallsPerSec = 0; + + NdbMutex_Lock(g_pNdbMutexPrintf); + printf("Time Taken for %ld Calls is %ld msec (= %ld calls/sec)\n", + nNumCallsProcessed, (long)tElapsed, lCallsPerSec); + NdbMutex_Unlock(g_pNdbMutexPrintf); +} + + +#ifndef NDB_WIN32 +void InterlockedIncrement(long* lp) // expensive +{ + NdbMutex_Lock(g_pNdbMutexIncrement); + (*lp)++; + NdbMutex_Unlock(g_pNdbMutexIncrement); +} +#endif + + +void InterlockedIncrementAndReport(void) +{ + NdbMutex_Lock(g_pNdbMutexIncrement); + ++g_nNumCallsProcessed; + if((g_nNumCallsProcessed%1000)==0) + { + g_tEndTime = NdbTick_CurrentMillisecond(); + if(g_tStartTime) + ReportCallsPerSecond(1000, g_tStartTime, g_tEndTime); + + g_tStartTime = g_tEndTime; + } + NdbMutex_Unlock(g_pNdbMutexIncrement); +} + + +void SleepOneCall(void) +{ + int iMillisecToSleep; + if(g_nMaxCallsPerSecond>0) + iMillisecToSleep = (1000*g_nNumThreads)/g_nMaxCallsPerSecond; + else + iMillisecToSleep = 50; + + if(iMillisecToSleep>0) + NdbSleep_MilliSleep(iMillisecToSleep); + +} + + + +int QueryTransaction(Ndb* pNdb, + long iContextId, + long* piVersion, + long* piLockFlag, + long* piLockTime, + long* piLockTimeUSec, + char* pchContextData, + NdbError& err) +{ + int iRes = -1; + NdbConnection* pNdbConnection = pNdb->startTransaction(0, (const char*)&iContextId, 4); + if(pNdbConnection) + { + NdbOperation* pNdbOperation = pNdbConnection->getNdbOperation(g_szTableName); + if(pNdbOperation) + { + NdbRecAttr* pNdbRecAttrVersion; + NdbRecAttr* pNdbRecAttrLockFlag; + NdbRecAttr* pNdbRecAttrLockTime; + NdbRecAttr* pNdbRecAttrLockTimeUSec; + NdbRecAttr* pNdbRecAttrContextData; + if(!pNdbOperation->readTuple() + && !pNdbOperation->equal(c_szContextId, (Int32)iContextId) + && (pNdbRecAttrVersion=pNdbOperation->getValue(c_szVersion, (char*)piVersion)) + && (pNdbRecAttrLockFlag=pNdbOperation->getValue(c_szLockFlag, (char*)piLockFlag)) + && (pNdbRecAttrLockTime=pNdbOperation->getValue(c_szLockTime, (char*)piLockTime)) + && (pNdbRecAttrLockTimeUSec=pNdbOperation->getValue(c_szLockTimeUSec, (char*)piLockTimeUSec)) + && (pNdbRecAttrContextData=pNdbOperation->getValue(c_szContextData, pchContextData))) + { + if(!pNdbConnection->execute(Commit)) + iRes = 0; + else + err = pNdbConnection->getNdbError(); + } + else + err = pNdbOperation->getNdbError(); + } + else + err = pNdbConnection->getNdbError(); + + pNdb->closeTransaction(pNdbConnection); + } + else + err = pNdb->getNdbError(); + + return iRes; +} + + +int RetryQueryTransaction(Ndb* pNdb, + long iContextId, + long* piVersion, + long* piLockFlag, + long* piLockTime, + long* piLockTimeUSec, + char* pchContextData, + NdbError& err, + int& nRetry) +{ + int iRes = -1; + nRetry = 0; + bool bRetry = true; + while(bRetry && nRetrystartTransaction(0, (const char*)&iContextId, 4); + if(pNdbConnection) + { + NdbOperation* pNdbOperation = pNdbConnection->getNdbOperation(g_szTableName); + if(pNdbOperation) + { + if(!pNdbOperation->deleteTuple() + && !pNdbOperation->equal(c_szContextId, (Int32)iContextId)) + { + if(pNdbConnection->execute(Commit) == 0) + iRes = 0; + else + err = pNdbConnection->getNdbError(); + } + else + err = pNdbOperation->getNdbError(); + } + else + err = pNdbConnection->getNdbError(); + + pNdb->closeTransaction(pNdbConnection); + } + else + err = pNdb->getNdbError(); + + return iRes; +} + + + +int RetryDeleteTransaction(Ndb* pNdb, long iContextId, NdbError& err, int& nRetry) +{ + int iRes = -1; + nRetry = 0; + bool bRetry = true; + bool bUnknown = false; + while(bRetry && nRetrystartTransaction(0, (const char*)&iContextID, 4); + if(pNdbConnection) + { + NdbOperation* pNdbOperation = pNdbConnection->getNdbOperation(g_szTableName); + if(pNdbOperation) + { + if(!(g_bWriteTuple ? pNdbOperation->writeTuple() : pNdbOperation->insertTuple()) + && !pNdbOperation->equal(c_szContextId, (Int32)iContextID) + && !pNdbOperation->setValue(c_szVersion, (Int32)iVersion) + && !pNdbOperation->setValue(c_szLockFlag, (Int32)iLockFlag) + && !pNdbOperation->setValue(c_szLockTime, (Int32)iLockTime) + && !pNdbOperation->setValue(c_szLockTimeUSec, (Int32)iLockTimeUSec) + && !pNdbOperation->setValue(c_szContextData, pchContextData, g_nStatusDataSize)) + { + if(!pNdbConnection->execute(Commit)) + iRes = 0; + else + err = pNdbConnection->getNdbError(); + } + else + err = pNdbOperation->getNdbError(); + } + else + err = pNdbConnection->getNdbError(); + + pNdb->closeTransaction(pNdbConnection); + } + else + err = pNdb->getNdbError(); + + return iRes; +} + + + +int RetryInsertTransaction(Ndb* pNdb, + long iContextId, + long iVersion, + long iLockFlag, + long iLockTime, + long iLockTimeUSec, + const char* pchContextData, + NdbError& err, int& nRetry) +{ + int iRes = -1; + nRetry = 0; + bool bRetry = true; + bool bUnknown = false; + while(bRetry && nRetrystartTransaction(0, (const char*)&iContextId, 4); + if(pNdbConnection) + { + NdbOperation* pNdbOperation = pNdbConnection->getNdbOperation(g_szTableName); + if(pNdbOperation) + { + if(!pNdbOperation->updateTuple() + && !pNdbOperation->equal(c_szContextId, (Int32)iContextId) + && !pNdbOperation->setValue(c_szContextData, STATUS_DATA, g_nStatusDataSize)) + { + if(!pNdbConnection->execute(Commit)) + iRes = 0; + else + err = pNdbConnection->getNdbError(); + } + else + err = pNdbOperation->getNdbError(); + } + else + err = pNdbConnection->getNdbError(); + + pNdb->closeTransaction(pNdbConnection); + } + else + err = pNdb->getNdbError(); + + return iRes; +} + + +int RetryUpdateTransaction(Ndb* pNdb, long iContextId, NdbError& err, int& nRetry) +{ + int iRes = -1; + nRetry = 0; + bool bRetry = true; + while(bRetry && nRetry0) + { + sprintf(szMsg, "insert retried %d times, time %ld msec.", + nRetry, lMillisecForThisTrans); + ReportNdbError(szMsg, err); + } + if(iRes) + { + ReportNdbError("Insert initial record failed", err); + return iRes; + } + InterlockedIncrement(&g_nNumberOfInitialInsert); + } + return iRes; +} + + + +int VerifyInitialRecords(Ndb* pNdb, long nVerify, long nSeed) +{ + int iRes = -1; + char* pchContextData = new char[g_nStatusDataSize]; + char szMsg[100]; + long iPrevLockTime = -1; + long iPrevLockTimeUSec = -1; + for(long i=0; i0) + { + sprintf(szMsg, "verify retried %d times, time %ld msec.", + nRetry, lMillisecForThisTrans); + ReportNdbError(szMsg, err); + } + if(iRes) + { + ReportNdbError("Read initial record failed", err); + delete[] pchContextData; + return iRes; + } + if(memcmp(pchContextData, STATUS_DATA, g_nStatusDataSize)) + { + sprintf(szMsg, "wrong context data in tuple %d", iContextID); + ReportNdbError(szMsg, err); + delete[] pchContextData; + return -1; + } + if(iVersion!=nSeed + || iLockFlag!=iContextID + || iLockTimeinit(1) || pNdb->waitUntilReady()) + { + ReportNdbError("init of Ndb failed", pNdb->getNdbError()); + delete pNdb; + delete[] pchContextData; + return 0; + } + + if(g_bInsertInitial) + { + if(InsertInitialRecords(pNdb, g_nMaxContextIdPerThread, -nStartingRecordID-g_nMaxContextIdPerThread)) + { + delete pNdb; + delete[] pchContextData; + return 0; + } + } + + if(g_bVerifyInitial) + { + NdbError err; + memset(&err, 0, sizeof(err)); + if(VerifyInitialRecords(pNdb, g_nMaxContextIdPerThread, -nStartingRecordID-g_nMaxContextIdPerThread)) + { + delete pNdb; + delete[] pchContextData; + return 0; + } + } + if(g_bInsertInitial || g_bVerifyInitial) + { + delete[] pchContextData; + return 0; + } + + long nContextID = nStartingRecordID; +#ifdef NDB_WIN32 + while(WaitForSingleObject(hShutdownEvent,0) != WAIT_OBJECT_0) +#else + while(!bShutdownEvent) +#endif + { + ++nContextID; + nContextID %= g_nMaxContextIdPerThread; + nContextID += nStartingRecordID; + + bool bTimeLatency = (nContextID==100); + + NDB_TICKS tStartCall = NdbTick_CurrentMillisecond(); + for (int i=0; i < 20; i++) + { + int nRetry = 0; + NdbError err; + memset(&err, 0, sizeof(err)); + NDB_TICKS tStartTrans = NdbTick_CurrentMillisecond(); + switch(i) + { + case 3: + case 6: + case 9: + case 11: + case 12: + case 15: + case 18: // Query Record + szOp = "Read"; + iRes = RetryQueryTransaction(pNdb, nContextID, &iVersion, &iLockFlag, + &iLockTime, &iLockTimeUSec, pchContextData, err, nRetry); + break; + + case 19: // Delete Record + szOp = "Delete"; + iRes = RetryDeleteTransaction(pNdb, nContextID, err, nRetry); + break; + + case 0: // Insert Record + szOp = "Insert"; + iRes = RetryInsertTransaction(pNdb, nContextID, 1, 1, 1, 1, STATUS_DATA, err, nRetry); + break; + + default: // Update Record + szOp = "Update"; + iRes = RetryUpdateTransaction(pNdb, nContextID, err, nRetry); + break; + } + NDB_TICKS tEndTrans = NdbTick_CurrentMillisecond(); + long lMillisecForThisTrans = (long)(tEndTrans-tStartTrans); + + if(g_bReport) + { + assert(lMillisecForThisTrans>=0 && lMillisecForThisTrans0) + { + sprintf(szMsg, "%s retried %d times, time %ld msec.", + szOp, nRetry, lMillisecForThisTrans); + ReportNdbError(szMsg, err); + } + else if(bTimeLatency) + { + NdbMutex_Lock(g_pNdbMutexPrintf); + printf("%s = %ld msec.\n", szOp, lMillisecForThisTrans); + NdbMutex_Unlock(g_pNdbMutexPrintf); + } + + if(iRes) + { + sprintf(szMsg, "%s failed after %ld calls, terminating thread", + szOp, nNumCallsProcessed); + ReportNdbError(szMsg, err); + delete pNdb; + delete[] pchContextData; + return 0; + } + } + NDB_TICKS tEndCall = NdbTick_CurrentMillisecond(); + long lMillisecForThisCall = (long)(tEndCall-tStartCall); + + if(g_bReport) + { + assert(lMillisecForThisCall>=0 && lMillisecForThisCall0) + { + int iMillisecToSleep = (1000*g_nNumThreads)/g_nMaxCallsPerSecond; + iMillisecToSleep -= lMillisecForThisCall; + if(iMillisecToSleep>0) + { + NdbSleep_MilliSleep(iMillisecToSleep); + } + } + } + + NdbMutex_Lock(g_pNdbMutexPrintf); + printf("Terminating thread after %ld calls\n", nNumCallsProcessed); + NdbMutex_Unlock(g_pNdbMutexPrintf); + + delete pNdb; + delete[] pchContextData; + return 0; +} + + +int CreateCallContextTable(Ndb* pNdb, const char* szTableName, bool bStored) +{ + int iRes = -1; + NdbError err; + memset(&err, 0, sizeof(err)); + + NdbSchemaCon* pNdbSchemaCon = pNdb->startSchemaTransaction(); + if(pNdbSchemaCon) + { + NdbSchemaOp* pNdbSchemaOp = pNdbSchemaCon->getNdbSchemaOp(); + if(pNdbSchemaOp) + { + if(!pNdbSchemaOp->createTable(szTableName, 8, TupleKey, 2, + All, 6, 78, 80, 1, bStored) + && !pNdbSchemaOp->createAttribute(c_szContextId, TupleKey, 32, 1, Signed) + && !pNdbSchemaOp->createAttribute(c_szVersion, NoKey, 32, 1, Signed) + && !pNdbSchemaOp->createAttribute(c_szLockFlag, NoKey, 32, 1, Signed) + && !pNdbSchemaOp->createAttribute(c_szLockTime, NoKey, 32, 1, Signed) + && !pNdbSchemaOp->createAttribute(c_szLockTimeUSec, NoKey, 32, 1, Signed) + && !pNdbSchemaOp->createAttribute(c_szContextData, NoKey, 8, g_nStatusDataSize, String)) + { + if(!pNdbSchemaCon->execute()) + iRes = 0; + else + err = pNdbSchemaCon->getNdbError(); + } + else + err = pNdbSchemaOp->getNdbError(); + } + else + err = pNdbSchemaCon->getNdbError(); + pNdb->closeSchemaTransaction(pNdbSchemaCon); + } + else + err = pNdb->getNdbError(); + + if(iRes) + { + ReportNdbError("create call context table failed", err); + } + return iRes; +} + + + +void ReportResponseTimeStatistics(const char* szStat, long* plCount, const long lSize) +{ + long lCount = 0; + Int64 llSum = 0; + Int64 llSum2 = 0; + long lMin = -1; + long lMax = -1; + + for(long l=0; l0) + { + lCount += plCount[l]; + llSum += (Int64)l*(Int64)plCount[l]; + llSum2 += (Int64)l*(Int64)l*(Int64)plCount[l]; + if(lMin==-1 || llMax) + { + lMax = l; + } + } + } + + long lAvg = long(llSum/lCount); + double dblVar = ((double)lCount*(double)llSum2 - (double)llSum*(double)llSum)/((double)lCount*(double)(lCount-1)); + long lStd = long(sqrt(dblVar)); + + long lMed = -1; + long l95 = -1; + long lSel = -1; + for(long l=lMin; l<=lMax; ++l) + { + if(plCount[l]>0) + { + lSel += plCount[l]; + if(lMed==-1 && lSel>=(lCount/2)) + { + lMed = l; + } + if(l95==-1 && lSel>=((lCount*95)/100)) + { + l95 = l; + } + if(g_bReportPlus) + { + printf("%ld\t%ld\n", l, plCount[l]); + } + } + } + + printf("%s: Count=%ld, Min=%ld, Max=%ld, Avg=%ld, Std=%ld, Med=%ld, 95%%=%ld\n", + szStat, lCount, lMin, lMax, lAvg, lStd, lMed, l95); +} + + + +void ShowHelp(const char* szCmd) +{ + printf("%s -t [-s] [-b] [-c] [-m] [-d] [-i] [-v] [-f] [-w] [-r[+]]\n", szCmd); + printf("%s -?\n", szCmd); + puts("-d\t\tcreate the table"); + puts("-i\t\tinsert initial records"); + puts("-v\t\tverify initial records"); + puts("-t\tnumber of threads making calls"); + puts("-s\toffset for primary key"); + puts("-b\tbatch size per thread"); + puts("-c\tmax number of calls per second for this process"); + puts("-m\tsize of context data"); + puts("-f\t\tno checkpointing and no logging"); + puts("-w\t\tuse writeTuple instead of insertTuple"); + puts("-r\t\treport response time statistics"); + puts("-r+\t\treport response time distribution"); + puts("-?\t\thelp"); +} + + +int main(int argc, char* argv[]) +{ + int iRes = -1; + g_nNumThreads = 0; + g_nMaxCallsPerSecond = 0; + long nSeed = 0; + bool bStoredTable = true; + bool bCreateTable = false; + g_bWriteTuple = false; + g_bReport = false; + g_bReportPlus = false; + + for(int i=1; isizeof(STATUS_DATA)) + { + g_nStatusDataSize = sizeof(STATUS_DATA); + } + break; + case 'i': + g_bInsertInitial = true; + break; + case 'v': + g_bVerifyInitial = true; + break; + case 'd': + bCreateTable = true; + break; + case 'f': + bStoredTable = false; + break; + case 'w': + g_bWriteTuple = true; + break; + case 'r': + g_bReport = true; + if(argv[i][2]=='+') + { + g_bReportPlus = true; + } + break; + case 'c': + g_nMaxCallsPerSecond = atol(argv[i]+2); + break; + case '?': + default: + ShowHelp(argv[0]); + return -1; + } + } + else + { + ShowHelp(argv[0]); + return -1; + } + } + if(bCreateTable) + puts("-d\tcreate the table"); + if(g_bInsertInitial) + printf("-i\tinsert initial records\n"); + if(g_bVerifyInitial) + printf("-v\tverify initial records\n"); + if(g_nNumThreads>0) + printf("-t%ld\tnumber of threads making calls\n", g_nNumThreads); + if(g_nNumThreads>0) + { + printf("-s%ld\toffset for primary key\n", nSeed); + printf("-b%ld\tbatch size per thread\n", g_nMaxContextIdPerThread); + } + if(g_nMaxCallsPerSecond>0) + printf("-c%ld\tmax number of calls per second for this process\n", g_nMaxCallsPerSecond); + if(!bStoredTable) + puts("-f\tno checkpointing and no logging to disk"); + if(g_bWriteTuple) + puts("-w\tuse writeTuple instead of insertTuple"); + if(g_bReport) + puts("-r\treport response time statistics"); + if(g_bReportPlus) + puts("-r+\treport response time distribution"); + + if(!bCreateTable && g_nNumThreads<=0) + { + ShowHelp(argv[0]); + return -1; + } + printf("-m%ld\tsize of context data\n", g_nStatusDataSize); + + g_szTableName = (bStoredTable ? c_szTableNameStored : c_szTableNameTemp); + +#ifdef NDB_WIN32 + SetConsoleCtrlHandler(ConsoleCtrlHandler, true); +#else + signal(SIGINT, CtrlCHandler); +#endif + + if(g_bReport) + { + g_plCountMillisecForCall = new long[c_nMaxMillisecForAllCall]; + memset(g_plCountMillisecForCall, 0, c_nMaxMillisecForAllCall*sizeof(long)); + g_plCountMillisecForTrans = new long[c_nMaxMillisecForAllTrans]; + memset(g_plCountMillisecForTrans, 0, c_nMaxMillisecForAllTrans*sizeof(long)); + } + + g_pNdbMutexIncrement = NdbMutex_Create(); + g_pNdbMutexPrintf = NdbMutex_Create(); +#ifdef NDB_WIN32 + hShutdownEvent = CreateEvent(NULL,TRUE,FALSE,NULL); +#endif + + Ndb* pNdb = new Ndb(c_szDatabaseName); + if(!pNdb) + { + printf("could not construct ndb\n"); + return 1; + } + + if(pNdb->init(1) || pNdb->waitUntilReady()) + { + ReportNdbError("could not initialize ndb\n", pNdb->getNdbError()); + delete pNdb; + return 2; + } + + if(bCreateTable) + { + printf("Create CallContext table\n"); + if (bStoredTable) + { + if (CreateCallContextTable(pNdb, c_szTableNameStored, true)) + { + printf("Create table failed\n"); + delete pNdb; + return 3; + } + } + else + { + if (CreateCallContextTable(pNdb, c_szTableNameTemp, false)) + { + printf("Create table failed\n"); + delete pNdb; + return 3; + } + } + } + + if(g_nNumThreads>0) + { + printf("creating %d threads\n", (int)g_nNumThreads); + if(g_bInsertInitial) + { + printf("each thread will insert %ld initial records, total %ld inserts\n", + g_nMaxContextIdPerThread, g_nNumThreads*g_nMaxContextIdPerThread); + } + if(g_bVerifyInitial) + { + printf("each thread will verify %ld initial records, total %ld reads\n", + g_nMaxContextIdPerThread, g_nNumThreads*g_nMaxContextIdPerThread); + } + + g_nNumberOfInitialInsert = 0; + g_nNumberOfInitialVerify = 0; + + NDB_TICKS tStartTime = NdbTick_CurrentMillisecond(); + NdbThread* pThreads[256]; + int pnStartingRecordNum[256]; + int ij; + for(ij=0;ij + +inline +NdbConnection * +startTransaction(Ndb * pNDB, + ServerId inServerId, + const SubscriberNumber inNumber){ + + const int keyDataLenBytes = sizeof(ServerId)+SUBSCRIBER_NUMBER_LENGTH; + const int keyDataLen_64Words = keyDataLenBytes >> 3; + + Uint64 keyDataBuf[keyDataLen_64Words+1]; // The "+1" is for rounding... + + char * keyDataBuf_charP = (char *)&keyDataBuf[0]; + Uint32 * keyDataBuf_wo32P = (Uint32 *)&keyDataBuf[0]; + + // Server Id comes first + keyDataBuf_wo32P[0] = inServerId; + // Then subscriber number + memcpy(&keyDataBuf_charP[sizeof(ServerId)], inNumber, + SUBSCRIBER_NUMBER_LENGTH); + + return pNDB->startTransaction(0, keyDataBuf_charP, keyDataLenBytes); +} + +void T1_Callback(int result, NdbConnection * pCon, void * threadData); +void T2_Callback(int result, NdbConnection * pCon, void * threadData); +void T3_Callback_1(int result, NdbConnection * pCon, void * threadData); +void T3_Callback_2(int result, NdbConnection * pCon, void * threadData); +void T3_Callback_3(int result, NdbConnection * pCon, void * threadData); +void T4_Callback_1(int result, NdbConnection * pCon, void * threadData); +void T4_Callback_2(int result, NdbConnection * pCon, void * threadData); +void T4_Callback_3(int result, NdbConnection * pCon, void * threadData); +void T5_Callback_1(int result, NdbConnection * pCon, void * threadData); +void T5_Callback_2(int result, NdbConnection * pCon, void * threadData); +void T5_Callback_3(int result, NdbConnection * pCon, void * threadData); + +/** + * Transaction 1 - T1 + * + * Update location and changed by/time on a subscriber + * + * Input: + * SubscriberNumber, + * Location, + * ChangedBy, + * ChangedTime + * + * Output: + */ +void +start_T1(Ndb * pNDB, ThreadData * td){ + + DEBUG2("T1(%.*s): - Starting\n", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number); + + int check; + NdbConnection * pCON = pNDB->startTransaction(); + if (pCON != NULL) { + NdbOperation *MyOp = pCON->getNdbOperation(SUBSCRIBER_TABLE); + if (MyOp != NULL) { + MyOp->updateTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->setValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->setValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->setValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + pCON->executeAsynchPrepare( Commit , T1_Callback, td); + } else { + CHECK_NULL(MyOp, "T1: getNdbOperation", pCON); + }//if + } else { + error_handler("T1-1: startTranscation", + pNDB->getNdbErrorString(), + pNDB->getNdbError()); + }//if +} + +void +T1_Callback(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + + DEBUG2("T1(%.*s): - Completing\n", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number); + + CHECK_MINUS_ONE(result, "T1: Commit", + pCON); + td->pNDB->closeTransaction(pCON); + complete_T1(td); +} + +/** + * Transaction 2 - T2 + * + * Read from Subscriber: + * + * Input: + * SubscriberNumber + * + * Output: + * Location + * Changed by + * Changed Timestamp + * Name + */ +void +start_T2(Ndb * pNDB, ThreadData * td){ + + DEBUG3("T2(%.*s, %p): - Starting\n", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.location); + + int check; + NdbRecAttr * check2; + + NdbConnection * pCON = pNDB->startTransaction(); + if (pCON == NULL) + error_handler("T2-1: startTransaction", + pNDB->getNdbErrorString(), + pNDB->getNdbError()); + + NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOp, "T2: getNdbOperation", + pCON); + + MyOp->readTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + MyOp->getValue(IND_SUBSCRIBER_NAME, + td->transactionData.name); + pCON->executeAsynchPrepare( Commit, T2_Callback, td ); +} + +void +T2_Callback(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + DEBUG3("T2(%.*s, %p): - Completing\n", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.location); + + CHECK_MINUS_ONE(result, "T2: Commit", pCON); + td->pNDB->closeTransaction(pCON); + complete_T2(td); +} + +/** + * Transaction 3 - T3 + * + * Read session details + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * + * Output: + * BranchExecuted + * SessionDetails + * ChangedBy + * ChangedTime + * Location + */ +void +start_T3(Ndb * pNDB, ThreadData * td){ + + DEBUG3("T3(%.*s, %.2d): - Starting\n", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + int check; + NdbRecAttr * check2; + + NdbConnection * pCON = startTransaction(pNDB, + td->transactionData.server_id, + td->transactionData.number); + if (pCON == NULL) + error_handler("T3-1: startTranscation", + pNDB->getNdbErrorString(), + pNDB->getNdbError()); + + NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOp, "T3-1: getNdbOperation", + pCON); + + MyOp->readTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + MyOp->getValue(IND_SUBSCRIBER_GROUP, + (char *)&td->transactionData.group_id); + MyOp->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&td->transactionData.sessions); + pCON->executeAsynchPrepare( NoCommit , T3_Callback_1, td); +} + +void +T3_Callback_1(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + DEBUG3("T3(%.*s, %.2d): - Callback 1\n", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + CHECK_MINUS_ONE(result, "T3-1: NoCommit", pCON); + + NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOp, "T3-2: getNdbOperation", + pCON); + + MyOp->readTuple(); + MyOp->equal(IND_GROUP_ID, + (char*)&td->transactionData.group_id); + MyOp->getValue(IND_GROUP_ALLOW_READ, + (char *)&td->transactionData.permission); + pCON->executeAsynchPrepare( NoCommit, T3_Callback_2, td ); +} + +void +T3_Callback_2(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + + CHECK_MINUS_ONE(result, "T3-2: NoCommit", pCON); + + Uint32 permission = td->transactionData.permission; + Uint32 sessions = td->transactionData.sessions; + Uint32 server_bit = td->transactionData.server_bit; + + if(((permission & server_bit) == server_bit) && + ((sessions & server_bit) == server_bit)){ + + memcpy(td->transactionData.suffix, + &td->transactionData.number + [SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], + SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + DEBUG5("T3(%.*s, %.2d): - Callback 2 - reading(%.*s)\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + SUBSCRIBER_NUMBER_SUFFIX_LENGTH, + td->transactionData.suffix); + + /* Operation 3 */ + NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOp, "T3-3: getNdbOperation", + pCON); + + MyOp->simpleRead(); + MyOp->equal(IND_SESSION_SUBSCRIBER, + (char*)td->transactionData.number); + MyOp->equal(IND_SESSION_SERVER, + (char*)&td->transactionData.server_id); + MyOp->getValue(IND_SESSION_DATA, + (char *)td->transactionData.session_details); + + /* Operation 4 */ + MyOp = pCON->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOp, "T3-4: getNdbOperation", + pCON); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SERVER_ID, + (char*)&td->transactionData.server_id); + MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)td->transactionData.suffix); + MyOp->incValue(IND_SERVER_READS, (uint32)1); + td->transactionData.branchExecuted = 1; + } else { + DEBUG3("T3(%.*s, %.2d): - Callback 2 - no read\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + td->transactionData.branchExecuted = 0; + } + pCON->executeAsynchPrepare( Commit, T3_Callback_3, td ); +} + +void +T3_Callback_3(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + DEBUG3("T3(%.*s, %.2d): - Completing\n", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + CHECK_MINUS_ONE(result, "T3-3: Commit", pCON); + + td->pNDB->closeTransaction(pCON); + complete_T3(td); +} + +/** + * Transaction 4 - T4 + * + * Create session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * SessionDetails, + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +void +start_T4(Ndb * pNDB, ThreadData * td){ + + DEBUG3("T4(%.*s, %.2d): - Starting\n", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + int check; + NdbRecAttr * check2; + + NdbConnection * pCON = startTransaction(pNDB, + td->transactionData.server_id, + td->transactionData.number); + if (pCON == NULL) + error_handler("T4-1: startTranscation", + pNDB->getNdbErrorString(), + pNDB->getNdbError()); + + NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOp, "T4-1: getNdbOperation", + pCON); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + MyOp->getValue(IND_SUBSCRIBER_GROUP, + (char *)&td->transactionData.group_id); + MyOp->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&td->transactionData.sessions); + MyOp->incValue(IND_SUBSCRIBER_SESSIONS, + (uint32)td->transactionData.server_bit); + pCON->executeAsynchPrepare( NoCommit , T4_Callback_1, td); +} + +void +T4_Callback_1(int result, NdbConnection * pCON, void * threadData){ + CHECK_MINUS_ONE(result, "T4-1: NoCommit", pCON); + ThreadData * td = (ThreadData *)threadData; + + DEBUG3("T4(%.*s, %.2d): - Callback 1\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + + NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOp, "T4-2: getNdbOperation", + pCON); + + MyOp->readTuple(); + MyOp->equal(IND_GROUP_ID, + (char*)&td->transactionData.group_id); + MyOp->getValue(IND_GROUP_ALLOW_INSERT, + (char *)&td->transactionData.permission); + pCON->executeAsynchPrepare( NoCommit , T4_Callback_2, td); +} + +void +T4_Callback_2(int result, NdbConnection * pCON, void * threadData){ + CHECK_MINUS_ONE(result, "T4-2: NoCommit", pCON); + ThreadData * td = (ThreadData *)threadData; + + Uint32 permission = td->transactionData.permission; + Uint32 sessions = td->transactionData.sessions; + Uint32 server_bit = td->transactionData.server_bit; + + if(((permission & server_bit) == server_bit) && + ((sessions & server_bit) == 0)){ + + memcpy(td->transactionData.suffix, + &td->transactionData.number + [SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], + SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + + DEBUG5("T4(%.*s, %.2d): - Callback 2 - inserting(%.*s)\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + SUBSCRIBER_NUMBER_SUFFIX_LENGTH, + td->transactionData.suffix); + + /* Operation 3 */ + + NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOp, "T4-3: getNdbOperation", + pCON); + + MyOp->insertTuple(); + MyOp->equal(IND_SESSION_SUBSCRIBER, + (char*)td->transactionData.number); + MyOp->equal(IND_SESSION_SERVER, + (char*)&td->transactionData.server_id); + MyOp->setValue(SESSION_DATA, + (char *)td->transactionData.session_details); + /* Operation 4 */ + + /* Operation 5 */ + MyOp = pCON->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOp, "T4-5: getNdbOperation", + pCON); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SERVER_ID, + (char*)&td->transactionData.server_id); + MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)td->transactionData.suffix); + MyOp->incValue(IND_SERVER_INSERTS, (uint32)1); + td->transactionData.branchExecuted = 1; + } else { + td->transactionData.branchExecuted = 0; + DEBUG5("T4(%.*s, %.2d): - Callback 2 - %s %s\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + ((permission & server_bit) ? + "permission - " : "no permission - "), + ((sessions & server_bit) ? + "in session - " : "no in session - ")); + } + + if(!td->transactionData.do_rollback && td->transactionData.branchExecuted){ + pCON->executeAsynchPrepare(Commit, T4_Callback_3, td); + } else { + pCON->executeAsynchPrepare(Rollback, T4_Callback_3, td); + } +} + +void +T4_Callback_3(int result, NdbConnection * pCON, void * threadData){ + CHECK_MINUS_ONE(result, "T4-3: Commit", pCON); + ThreadData * td = (ThreadData *)threadData; + + DEBUG3("T4(%.*s, %.2d): - Completing\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + td->pNDB->closeTransaction(pCON); + complete_T4(td); +} + +/** + * Transaction 5 - T5 + * + * Delete session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +void +start_T5(Ndb * pNDB, ThreadData * td){ + + DEBUG3("T5(%.*s, %.2d): - Starting\n", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + int check; + NdbRecAttr * check2; + + NdbConnection * pCON = pNDB->startTransaction(); + if (pCON == NULL) + error_handler("T5-1: startTranscation", + pNDB->getNdbErrorString(), + pNDB->getNdbError()); + + NdbOperation * MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOp, "T5-1: getNdbOperation", + pCON); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + MyOp->getValue(IND_SUBSCRIBER_GROUP, + (char *)&td->transactionData.group_id); + MyOp->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&td->transactionData.sessions); + MyOp->subValue(IND_SUBSCRIBER_SESSIONS, + (uint32)td->transactionData.server_bit); + pCON->executeAsynchPrepare( NoCommit, T5_Callback_1, td ); +} + +void +T5_Callback_1(int result, NdbConnection * pCON, void * threadData){ + CHECK_MINUS_ONE(result, "T5-1: NoCommit", pCON); + ThreadData * td = (ThreadData *)threadData; + + DEBUG3("T5(%.*s, %.2d): - Callback 1\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOp, "T5-2: getNdbOperation", + pCON); + + MyOp->readTuple(); + MyOp->equal(IND_GROUP_ID, + (char*)&td->transactionData.group_id); + MyOp->getValue(IND_GROUP_ALLOW_DELETE, + (char *)&td->transactionData.permission); + pCON->executeAsynchPrepare( NoCommit, T5_Callback_2, td ); +} + +void +T5_Callback_2(int result, NdbConnection * pCON, void * threadData){ + CHECK_MINUS_ONE(result, "T5-2: NoCommit", pCON); + ThreadData * td = (ThreadData *)threadData; + + Uint32 permission = td->transactionData.permission; + Uint32 sessions = td->transactionData.sessions; + Uint32 server_bit = td->transactionData.server_bit; + + if(((permission & server_bit) == server_bit) && + ((sessions & server_bit) == server_bit)){ + + memcpy(td->transactionData.suffix, + &td->transactionData.number + [SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], + SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + + DEBUG5("T5(%.*s, %.2d): - Callback 2 - deleting(%.*s)\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + SUBSCRIBER_NUMBER_SUFFIX_LENGTH, + td->transactionData.suffix); + + /* Operation 3 */ + NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOp, "T5-3: getNdbOperation", + pCON); + + MyOp->deleteTuple(); + MyOp->equal(IND_SESSION_SUBSCRIBER, + (char*)td->transactionData.number); + MyOp->equal(IND_SESSION_SERVER, + (char*)&td->transactionData.server_id); + /* Operation 4 */ + + /* Operation 5 */ + MyOp = pCON->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOp, "T5-5: getNdbOperation", + pCON); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SERVER_ID, + (char*)&td->transactionData.server_id); + MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)td->transactionData.suffix); + MyOp->incValue(IND_SERVER_DELETES, (uint32)1); + td->transactionData.branchExecuted = 1; + } else { + td->transactionData.branchExecuted = 0; + + DEBUG5("T5(%.*s, %.2d): - Callback 2 - no delete - %s %s\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + ((permission & server_bit) ? + "permission - " : "no permission - "), + ((sessions & server_bit) ? + "in session - " : "no in session - ")); + } + + if(!td->transactionData.do_rollback && td->transactionData.branchExecuted){ + pCON->executeAsynchPrepare(Commit, T5_Callback_3, td); + } else { + pCON->executeAsynchPrepare(Rollback, T5_Callback_3, td); + } +} + +void +T5_Callback_3(int result, NdbConnection * pCON, void * threadData){ + CHECK_MINUS_ONE(result, "T5-3: Commit", pCON); + ThreadData * td = (ThreadData *)threadData; + + DEBUG3("T5(%.*s, %.2d): - Completing\n", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + td->pNDB->closeTransaction(pCON); + complete_T5(td); +} diff --git a/ndb/test/ndbapi/ndb_async2.cpp b/ndb/test/ndbapi/ndb_async2.cpp new file mode 100644 index 00000000000..0c1d138defb --- /dev/null +++ b/ndb/test/ndbapi/ndb_async2.cpp @@ -0,0 +1,754 @@ +/* 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 */ + +//#define DEBUG_ON + +#include +#include "userInterface.h" + +#include "macros.h" +#include "ndb_schema.hpp" +#include "ndb_error.hpp" +#include + +#include + +void T1_Callback(int result, NdbConnection * pCon, void * threadData); +void T2_Callback(int result, NdbConnection * pCon, void * threadData); +void T3_Callback_1(int result, NdbConnection * pCon, void * threadData); +void T3_Callback_2(int result, NdbConnection * pCon, void * threadData); +void T3_Callback_3(int result, NdbConnection * pCon, void * threadData); +void T4_Callback_1(int result, NdbConnection * pCon, void * threadData); +void T4_Callback_2(int result, NdbConnection * pCon, void * threadData); +void T4_Callback_3(int result, NdbConnection * pCon, void * threadData); +void T5_Callback_1(int result, NdbConnection * pCon, void * threadData); +void T5_Callback_2(int result, NdbConnection * pCon, void * threadData); +void T5_Callback_3(int result, NdbConnection * pCon, void * threadData); + +static int stat_async = 0; + +/** + * Transaction 1 - T1 + * + * Update location and changed by/time on a subscriber + * + * Input: + * SubscriberNumber, + * Location, + * ChangedBy, + * ChangedTime + * + * Output: + */ + +#define SFX_START (SUBSCRIBER_NUMBER_LENGTH - SUBSCRIBER_NUMBER_SUFFIX_LENGTH) + +inline +NdbConnection * +startTransaction(Ndb * pNDB, ThreadData * td){ + return pNDB->startTransactionDGroup (0, + &td->transactionData.number[SFX_START], + 1); +} + +void +start_T1(Ndb * pNDB, ThreadData * td, int async){ + + DEBUG2("T1(%.*s): - Starting", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number); + + NdbConnection * pCON = 0; + while((pCON = startTransaction(pNDB, td)) == 0){ + CHECK_ALLOWED_ERROR("T1: startTransaction", td, pNDB->getNdbError()); + NdbSleep_MilliSleep(10); + } + + NdbOperation *MyOp = pCON->getNdbOperation(SUBSCRIBER_TABLE); + if (MyOp != NULL) { + MyOp->updateTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->setValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->setValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->setValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + if (async == 1) { + pCON->executeAsynchPrepare( Commit , T1_Callback, td); + } else { + int result = pCON->execute(Commit); + T1_Callback(result, pCON, (void*)td); + return; + }//if + } else { + CHECK_NULL(MyOp, "T1: getNdbOperation", td, pCON->getNdbError()); + }//if +} + +void +T1_Callback(int result, NdbConnection * pCON, void * threadData) { + ThreadData * td = (ThreadData *)threadData; + + DEBUG2("T1(%.*s): - Completing", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number); + + if (result == -1) { + CHECK_ALLOWED_ERROR("T1: Commit", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T1(td->pNDB, td, stat_async); + return; + }//if + td->pNDB->closeTransaction(pCON); + complete_T1(td); +} + +/** + * Transaction 2 - T2 + * + * Read from Subscriber: + * + * Input: + * SubscriberNumber + * + * Output: + * Location + * Changed by + * Changed Timestamp + * Name + */ +void +start_T2(Ndb * pNDB, ThreadData * td, int async){ + + DEBUG3("T2(%.*s, %d): - Starting", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.location); + + NdbConnection * pCON = 0; + + while((pCON = startTransaction(pNDB, td)) == 0){ + CHECK_ALLOWED_ERROR("T2-1: startTransaction", td, pNDB->getNdbError()); + NdbSleep_MilliSleep(10); + } + + NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOp, "T2: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->readTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + MyOp->getValue(IND_SUBSCRIBER_NAME, + td->transactionData.name); + if (async == 1) { + pCON->executeAsynchPrepare( Commit , T2_Callback, td); + } else { + int result = pCON->execute(Commit); + T2_Callback(result, pCON, (void*)td); + return; + }//if +} + +void +T2_Callback(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + DEBUG3("T2(%.*s, %d): - Completing", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.location); + + if (result == -1) { + CHECK_ALLOWED_ERROR("T2: Commit", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T2(td->pNDB, td, stat_async); + return; + }//if + td->pNDB->closeTransaction(pCON); + complete_T2(td); +} + +/** + * Transaction 3 - T3 + * + * Read session details + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * + * Output: + * BranchExecuted + * SessionDetails + * ChangedBy + * ChangedTime + * Location + */ +void +start_T3(Ndb * pNDB, ThreadData * td, int async){ + + DEBUG3("T3(%.*s, %.2d): - Starting", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + NdbConnection * pCON = 0; + + while((pCON = startTransaction(pNDB, td)) == 0){ + CHECK_ALLOWED_ERROR("T3-1: startTransaction", td, pNDB->getNdbError()); + NdbSleep_MilliSleep(10); + } + + NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOp, "T3-1: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->readTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + MyOp->getValue(IND_SUBSCRIBER_GROUP, + (char *)&td->transactionData.group_id); + MyOp->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&td->transactionData.sessions); + stat_async = async; + if (async == 1) { + pCON->executeAsynchPrepare( NoCommit , T3_Callback_1, td); + } else { + int result = pCON->execute( NoCommit ); + T3_Callback_1(result, pCON, (void*)td); + return; + }//if +} + +void +T3_Callback_1(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + DEBUG3("T3(%.*s, %.2d): - Callback 1", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + if (result == -1) { + CHECK_ALLOWED_ERROR("T3-1: execute", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T3(td->pNDB, td, stat_async); + return; + }//if + + NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOp, "T3-2: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->readTuple(); + MyOp->equal(IND_GROUP_ID, + (char*)&td->transactionData.group_id); + MyOp->getValue(IND_GROUP_ALLOW_READ, + (char *)&td->transactionData.permission); + if (stat_async == 1) { + pCON->executeAsynchPrepare( NoCommit , T3_Callback_2, td); + } else { + int result = pCON->execute( NoCommit ); + T3_Callback_2(result, pCON, (void*)td); + return; + }//if +} + +void +T3_Callback_2(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + + if (result == -1) { + CHECK_ALLOWED_ERROR("T3-2: execute", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T3(td->pNDB, td, stat_async); + return; + }//if + + Uint32 permission = td->transactionData.permission; + Uint32 sessions = td->transactionData.sessions; + Uint32 server_bit = td->transactionData.server_bit; + + if(((permission & server_bit) == server_bit) && + ((sessions & server_bit) == server_bit)){ + + memcpy(td->transactionData.suffix, + &td->transactionData.number[SFX_START], + SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + DEBUG5("T3(%.*s, %.2d): - Callback 2 - reading(%.*s)", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + SUBSCRIBER_NUMBER_SUFFIX_LENGTH, + td->transactionData.suffix); + + /* Operation 3 */ + NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOp, "T3-3: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->simpleRead(); + MyOp->equal(IND_SESSION_SUBSCRIBER, + (char*)td->transactionData.number); + MyOp->equal(IND_SESSION_SERVER, + (char*)&td->transactionData.server_id); + MyOp->getValue(IND_SESSION_DATA, + (char *)td->transactionData.session_details); + + /* Operation 4 */ + MyOp = pCON->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOp, "T3-4: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SERVER_ID, + (char*)&td->transactionData.server_id); + MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)td->transactionData.suffix); + MyOp->incValue(IND_SERVER_READS, (uint32)1); + td->transactionData.branchExecuted = 1; + } else { + DEBUG3("T3(%.*s, %.2d): - Callback 2 - no read", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + td->transactionData.branchExecuted = 0; + } + if (stat_async == 1) { + pCON->executeAsynchPrepare( Commit , T3_Callback_3, td); + } else { + int result = pCON->execute( Commit ); + T3_Callback_3(result, pCON, (void*)td); + return; + }//if +} + +void +T3_Callback_3(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + DEBUG3("T3(%.*s, %.2d): - Completing", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + if (result == -1) { + CHECK_ALLOWED_ERROR("T3-3: Commit", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T3(td->pNDB, td, stat_async); + return; + }//if + td->pNDB->closeTransaction(pCON); + complete_T3(td); +} + +/** + * Transaction 4 - T4 + * + * Create session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * SessionDetails, + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +void +start_T4(Ndb * pNDB, ThreadData * td, int async){ + + DEBUG3("T4(%.*s, %.2d): - Starting", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + NdbConnection * pCON = 0; + while((pCON = startTransaction(pNDB, td)) == 0){ + CHECK_ALLOWED_ERROR("T4-1: startTransaction", td, pNDB->getNdbError()); + NdbSleep_MilliSleep(10); + } + + NdbOperation *MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOp, "T4-1: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + MyOp->getValue(IND_SUBSCRIBER_GROUP, + (char *)&td->transactionData.group_id); + MyOp->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&td->transactionData.sessions); + MyOp->incValue(IND_SUBSCRIBER_SESSIONS, + (uint32)td->transactionData.server_bit); + stat_async = async; + if (async == 1) { + pCON->executeAsynchPrepare( NoCommit , T4_Callback_1, td); + } else { + int result = pCON->execute( NoCommit ); + T4_Callback_1(result, pCON, (void*)td); + return; + }//if +} + +void +T4_Callback_1(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + if (result == -1) { + CHECK_ALLOWED_ERROR("T4-1: execute", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T4(td->pNDB, td, stat_async); + return; + }//if + + DEBUG3("T4(%.*s, %.2d): - Callback 1", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + + NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOp, "T4-2: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->readTuple(); + MyOp->equal(IND_GROUP_ID, + (char*)&td->transactionData.group_id); + MyOp->getValue(IND_GROUP_ALLOW_INSERT, + (char *)&td->transactionData.permission); + if (stat_async == 1) { + pCON->executeAsynchPrepare( NoCommit , T4_Callback_2, td); + } else { + int result = pCON->execute( NoCommit ); + T4_Callback_2(result, pCON, (void*)td); + return; + }//if +} + +void +T4_Callback_2(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + if (result == -1) { + CHECK_ALLOWED_ERROR("T4-2: execute", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T4(td->pNDB, td, stat_async); + return; + }//if + + Uint32 permission = td->transactionData.permission; + Uint32 sessions = td->transactionData.sessions; + Uint32 server_bit = td->transactionData.server_bit; + + if(((permission & server_bit) == server_bit) && + ((sessions & server_bit) == 0)){ + + memcpy(td->transactionData.suffix, + &td->transactionData.number[SFX_START], + SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + + DEBUG5("T4(%.*s, %.2d): - Callback 2 - inserting(%.*s)", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + SUBSCRIBER_NUMBER_SUFFIX_LENGTH, + td->transactionData.suffix); + + /* Operation 3 */ + + NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOp, "T4-3: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->insertTuple(); + MyOp->equal(IND_SESSION_SUBSCRIBER, + (char*)td->transactionData.number); + MyOp->equal(IND_SESSION_SERVER, + (char*)&td->transactionData.server_id); + MyOp->setValue(SESSION_DATA, + (char *)td->transactionData.session_details); + /* Operation 4 */ + + /* Operation 5 */ + MyOp = pCON->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOp, "T4-5: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SERVER_ID, + (char*)&td->transactionData.server_id); + MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)td->transactionData.suffix); + MyOp->incValue(IND_SERVER_INSERTS, (uint32)1); + td->transactionData.branchExecuted = 1; + } else { + td->transactionData.branchExecuted = 0; + DEBUG5("T4(%.*s, %.2d): - Callback 2 - %s %s", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + ((permission & server_bit) ? + "permission - " : "no permission - "), + ((sessions & server_bit) ? + "in session - " : "no in session - ")); + } + + if(!td->transactionData.do_rollback && td->transactionData.branchExecuted){ + if (stat_async == 1) { + pCON->executeAsynchPrepare( Commit , T4_Callback_3, td); + } else { + int result = pCON->execute( Commit ); + T4_Callback_3(result, pCON, (void*)td); + return; + }//if + } else { + if (stat_async == 1) { + pCON->executeAsynchPrepare( Rollback , T4_Callback_3, td); + } else { + int result = pCON->execute( Rollback ); + T4_Callback_3(result, pCON, (void*)td); + return; + }//if + } +} + +void +T4_Callback_3(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + if (result == -1) { + CHECK_ALLOWED_ERROR("T4-3: Commit", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T4(td->pNDB, td, stat_async); + return; + }//if + + DEBUG3("T4(%.*s, %.2d): - Completing", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + td->pNDB->closeTransaction(pCON); + complete_T4(td); +} + +/** + * Transaction 5 - T5 + * + * Delete session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +void +start_T5(Ndb * pNDB, ThreadData * td, int async){ + + DEBUG3("T5(%.*s, %.2d): - Starting", SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + NdbConnection * pCON = 0; + while((pCON = startTransaction(pNDB, td)) == 0){ + CHECK_ALLOWED_ERROR("T5-1: startTransaction", td, pNDB->getNdbError()); + NdbSleep_MilliSleep(10); + } + + NdbOperation * MyOp= pCON->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOp, "T5-1: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SUBSCRIBER_NUMBER, + td->transactionData.number); + MyOp->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&td->transactionData.location); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_BY, + td->transactionData.changed_by); + MyOp->getValue(IND_SUBSCRIBER_CHANGED_TIME, + td->transactionData.changed_time); + MyOp->getValue(IND_SUBSCRIBER_GROUP, + (char *)&td->transactionData.group_id); + MyOp->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&td->transactionData.sessions); + MyOp->subValue(IND_SUBSCRIBER_SESSIONS, + (uint32)td->transactionData.server_bit); + stat_async = async; + if (async == 1) { + pCON->executeAsynchPrepare( NoCommit , T5_Callback_1, td); + } else { + int result = pCON->execute( NoCommit ); + T5_Callback_1(result, pCON, (void*)td); + return; + }//if +} + +void +T5_Callback_1(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + if (result == -1) { + CHECK_ALLOWED_ERROR("T5-1: execute", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T5(td->pNDB, td, stat_async); + return; + }//if + + DEBUG3("T5(%.*s, %.2d): - Callback 1", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + NdbOperation * MyOp = pCON->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOp, "T5-2: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->readTuple(); + MyOp->equal(IND_GROUP_ID, + (char*)&td->transactionData.group_id); + MyOp->getValue(IND_GROUP_ALLOW_DELETE, + (char *)&td->transactionData.permission); + if (stat_async == 1) { + pCON->executeAsynchPrepare( NoCommit , T5_Callback_2, td); + } else { + int result = pCON->execute( NoCommit ); + T5_Callback_2(result, pCON, (void*)td); + return; + }//if +} + +void +T5_Callback_2(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + if (result == -1) { + CHECK_ALLOWED_ERROR("T5-2: execute", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T5(td->pNDB, td, stat_async); + return; + }//if + + Uint32 permission = td->transactionData.permission; + Uint32 sessions = td->transactionData.sessions; + Uint32 server_bit = td->transactionData.server_bit; + + if(((permission & server_bit) == server_bit) && + ((sessions & server_bit) == server_bit)){ + + memcpy(td->transactionData.suffix, + &td->transactionData.number[SFX_START], + SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + + DEBUG5("T5(%.*s, %.2d): - Callback 2 - deleting(%.*s)", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + SUBSCRIBER_NUMBER_SUFFIX_LENGTH, + td->transactionData.suffix); + + /* Operation 3 */ + NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOp, "T5-3: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->deleteTuple(); + MyOp->equal(IND_SESSION_SUBSCRIBER, + (char*)td->transactionData.number); + MyOp->equal(IND_SESSION_SERVER, + (char*)&td->transactionData.server_id); + /* Operation 4 */ + + /* Operation 5 */ + MyOp = pCON->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOp, "T5-5: getNdbOperation", td, + pCON->getNdbError()); + + MyOp->interpretedUpdateTuple(); + MyOp->equal(IND_SERVER_ID, + (char*)&td->transactionData.server_id); + MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)td->transactionData.suffix); + MyOp->incValue(IND_SERVER_DELETES, (uint32)1); + td->transactionData.branchExecuted = 1; + } else { + td->transactionData.branchExecuted = 0; + + DEBUG5("T5(%.*s, %.2d): - Callback 2 - no delete - %s %s", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id, + ((permission & server_bit) ? + "permission - " : "no permission - "), + ((sessions & server_bit) ? + "in session - " : "no in session - ")); + } + + if(!td->transactionData.do_rollback && td->transactionData.branchExecuted){ + if (stat_async == 1) { + pCON->executeAsynchPrepare( Commit , T5_Callback_3, td); + } else { + int result = pCON->execute( Commit ); + T5_Callback_3(result, pCON, (void*)td); + return; + }//if + } else { + if (stat_async == 1) { + pCON->executeAsynchPrepare( Rollback , T5_Callback_3, td); + } else { + int result = pCON->execute( Rollback ); + T5_Callback_3(result, pCON, (void*)td); + return; + }//if + } +} + +void +T5_Callback_3(int result, NdbConnection * pCON, void * threadData){ + ThreadData * td = (ThreadData *)threadData; + if (result == -1) { + CHECK_ALLOWED_ERROR("T5-3: Commit", td, pCON->getNdbError()); + td->pNDB->closeTransaction(pCON); + start_T5(td->pNDB, td, stat_async); + return; + }//if + + DEBUG3("T5(%.*s, %.2d): - Completing", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number, + td->transactionData.server_id); + + td->pNDB->closeTransaction(pCON); + complete_T5(td); +} diff --git a/ndb/test/ndbapi/ndb_user_populate.cpp b/ndb/test/ndbapi/ndb_user_populate.cpp new file mode 100644 index 00000000000..ce3a76cdd59 --- /dev/null +++ b/ndb/test/ndbapi/ndb_user_populate.cpp @@ -0,0 +1,165 @@ +/* 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 */ + + +extern "C" { +#include "user_populate.h" +} + +#include +#include + +#include "ndb_schema.hpp" +#include "ndb_error.hpp" + +int +insert_subscriber(void * obj, + SubscriberNumber number, + SubscriberName name, + GroupId groupId, + Location l, + ActiveSessions activeSessions, + ChangedBy changedBy, + ChangedTime changedTime){ + Ndb * pNDB = (Ndb *)obj; + int check; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "getNdbOperation", MyTransaction); + + check = MyOperation->insertTuple(); + CHECK_MINUS_ONE(check, "insertTuple", MyTransaction); + + check = MyOperation->equal(SUBSCRIBER_NUMBER, number); + CHECK_MINUS_ONE(check, "equal", MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_NAME, name); + CHECK_MINUS_ONE(check, "setValue name", MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_GROUP, (char*)&groupId); + CHECK_MINUS_ONE(check, "setValue group", MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_LOCATION, (char*)&l); + CHECK_MINUS_ONE(check, "setValue location", MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_SESSIONS, (char*)&activeSessions); + CHECK_MINUS_ONE(check, "setValue sessions", MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_CHANGED_BY, changedBy); + CHECK_MINUS_ONE(check, "setValue changedBy", MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_CHANGED_TIME, changedTime); + CHECK_MINUS_ONE(check, "setValue changedTime", MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "commit", MyTransaction); + + pNDB->closeTransaction(MyTransaction); + return 0; +} + +int +insert_server(void * obj, + ServerId serverId, + SubscriberSuffix suffix, + ServerName name, + Counter noOfRead, + Counter noOfInsert, + Counter noOfDelete){ + Ndb * pNDB = (Ndb *)obj; + int check; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "getNdbOperation", MyTransaction); + + check = MyOperation->insertTuple(); + CHECK_MINUS_ONE(check, "insert tuple", MyTransaction); + + check = MyOperation->equal(SERVER_ID, (char*)&serverId); + CHECK_MINUS_ONE(check, "setValue id", MyTransaction); + + check = MyOperation->setValue(SERVER_SUBSCRIBER_SUFFIX, suffix); + CHECK_MINUS_ONE(check, "setValue suffix", MyTransaction); + + check = MyOperation->setValue(SERVER_NAME, name); + CHECK_MINUS_ONE(check, "setValue name", MyTransaction); + + check = MyOperation->setValue(SERVER_READS, (char*)&noOfRead); + CHECK_MINUS_ONE(check, "setValue reads", MyTransaction); + + check = MyOperation->setValue(SERVER_INSERTS, (char*)&noOfInsert); + CHECK_MINUS_ONE(check, "setValue inserts", MyTransaction); + + check = MyOperation->setValue(SERVER_DELETES, (char*)&noOfDelete); + CHECK_MINUS_ONE(check, "setValue deletes", MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "commit", MyTransaction); + + pNDB->closeTransaction(MyTransaction); + return 0; +} + +int +insert_group(void * obj, + GroupId groupId, + GroupName name, + Permission allowRead, + Permission allowInsert, + Permission allowDelete){ + Ndb * pNDB = (Ndb *)obj; + int check; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "getNdbOperation", MyTransaction); + + check = MyOperation->insertTuple(); + CHECK_MINUS_ONE(check, "insertTuple", MyTransaction); + + check = MyOperation->equal(GROUP_ID, (char*)&groupId); + CHECK_MINUS_ONE(check, "equal", MyTransaction); + + check = MyOperation->setValue(GROUP_NAME, name); + CHECK_MINUS_ONE(check, "setValue name", MyTransaction); + + check = MyOperation->setValue(GROUP_ALLOW_READ, (char*)&allowRead); + CHECK_MINUS_ONE(check, "setValue allowRead", MyTransaction); + + check = MyOperation->setValue(GROUP_ALLOW_INSERT, (char*)&allowInsert); + CHECK_MINUS_ONE(check, "setValue allowInsert", MyTransaction); + + check = MyOperation->setValue(GROUP_ALLOW_DELETE, (char*)&allowDelete); + CHECK_MINUS_ONE(check, "setValue allowDelete", MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "commit", MyTransaction); + + pNDB->closeTransaction(MyTransaction); + return 0; +} + diff --git a/ndb/test/ndbapi/ndb_user_transaction.cpp b/ndb/test/ndbapi/ndb_user_transaction.cpp new file mode 100644 index 00000000000..182f1f99586 --- /dev/null +++ b/ndb/test/ndbapi/ndb_user_transaction.cpp @@ -0,0 +1,825 @@ +/* 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 */ + +//#define DEBUG_ON + +extern "C" { +#include "user_transaction.h" +}; + +#include "macros.h" +#include "ndb_schema.hpp" +#include "ndb_error.hpp" + +#include +#include + +/** + * Transaction 1 - T1 + * + * Update location and changed by/time on a subscriber + * + * Input: + * SubscriberNumber, + * Location, + * ChangedBy, + * ChangedTime + * + * Output: + */ +int +T1(void * obj, + const SubscriberNumber number, + const Location new_location, + const ChangedBy changed_by, + const ChangedTime changed_time, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction); + + check = MyOperation->updateTuple(); + CHECK_MINUS_ONE(check, "T1: updateTuple", + MyTransaction); + + check = MyOperation->equal(SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T1: equal subscriber", + MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_LOCATION, + (char *)&new_location); + CHECK_MINUS_ONE(check, "T1: setValue location", + MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_MINUS_ONE(check, "T1: setValue changed_by", + MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_MINUS_ONE(check, "T1: setValue changed_time", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T1: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 2 - T2 + * + * Read from Subscriber: + * + * Input: + * SubscriberNumber + * + * Output: + * Location + * Changed by + * Changed Timestamp + * Name + */ +int +T2(void * obj, + const SubscriberNumber number, + Location * readLocation, + ChangedBy changed_by, + ChangedTime changed_time, + SubscriberName subscriberName, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T2: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T2: readTuple", + MyTransaction); + + check = MyOperation->equal(SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T2: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_LOCATION, + (char *)readLocation); + CHECK_NULL(check2, "T2: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_NULL(check2, "T2: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_NULL(check2, "T2: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_NAME, + subscriberName); + CHECK_NULL(check2, "T2: getValue name", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T2: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 3 - T3 + * + * Read session details + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * + * Output: + * BranchExecuted + * SessionDetails + * ChangedBy + * ChangedTime + * Location + */ +int +T3(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + SessionDetails outSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T3-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T3-1: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-1: readTuple", + MyTransaction); + + check = MyOperation->equal(SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T3-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T3-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T3-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T3-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T3-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T3-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T3-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-2: readTuple", + MyTransaction); + + check = MyOperation->equal(GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T3-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(GROUP_ALLOW_READ, + (char *)&permission); + CHECK_NULL(check2, "T3-2: getValue allow_read", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-2: NoCommit", + MyTransaction); + + DEBUG3("T3(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("reading - "); + + /* Operation 3 */ + + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T3-3: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-3: readTuple", + MyTransaction); + + check = MyOperation->equal(SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T3-3: equal number", + MyTransaction); + + check = MyOperation->equal(SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-3: equal server id", + MyTransaction); + + check2 = MyOperation->getValue(SESSION_DATA, + (char *)outSessionDetails); + CHECK_NULL(check2, "T3-3: getValue session details", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-3: NoCommit", + MyTransaction); + + /* Operation 4 */ + + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T3-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T3-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-4: equal serverId", + MyTransaction); + + check = MyOperation->equal(SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T3-4: equal suffix", + MyTransaction); + + check = MyOperation->incValue(SERVER_READS, (uint32)1); + CHECK_MINUS_ONE(check, "T3-4: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-4: NoCommit", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + (* outBranchExecuted) = 0; + } + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T3: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 4 - T4 + * + * Create session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * SessionDetails, + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T4(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + const SessionDetails inSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T4-1: startTranscation", pNDB->getNdbErrorString(), 0); + + DEBUG3("T4(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + NdbOperation * MyOperation = 0; + + MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T4-1: getNdbOperation", + MyTransaction); + + check = MyOperation->readTupleExclusive(); + CHECK_MINUS_ONE(check, "T4-1: readTuple", + MyTransaction); + + check = MyOperation->equal(SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T4-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T4-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T4-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T4-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T4-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T4-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T4-2: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T4-2: readTuple", + MyTransaction); + + check = MyOperation->equal(GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T4-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(GROUP_ALLOW_INSERT, + (char *)&permission); + CHECK_NULL(check2, "T4-2: getValue allow_insert", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-2: NoCommit", + MyTransaction); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == 0)){ + + DEBUG("inserting - "); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T4-3: getNdbOperation", + MyTransaction); + + check = MyOperation->insertTuple(); + CHECK_MINUS_ONE(check, "T4-3: insertTuple", + MyTransaction); + + check = MyOperation->equal(SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T4-3: equal number", + MyTransaction); + + check = MyOperation->equal(SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-3: equal server id", + MyTransaction); + + check = MyOperation->setValue(SESSION_DATA, + (char *)inSessionDetails); + CHECK_MINUS_ONE(check, "T4-3: setValue session details", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-3: NoCommit", + MyTransaction); + + /* Operation 4 */ + MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T4-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(SUBSCRIBER_NUMBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T4-4: equal number", + MyTransaction); + + check = MyOperation->incValue(SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T4-4: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-4: NoCommit", + MyTransaction); + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T4-5: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T4-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(SERVER_INSERTS, (uint32)1); + CHECK_MINUS_ONE(check, "T4-5: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-5: NoCommit", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T4: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T4:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 5 - T5 + * + * Delete session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T5(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + NdbConnection * MyTransaction = 0; + NdbOperation * MyOperation = 0; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), 0); + + MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T5-1: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTupleExclusive(); + CHECK_MINUS_ONE(check, "T5-1: readTuple", + MyTransaction); + + check = MyOperation->equal(SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T5-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T5-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T5-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T5-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T5-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T5-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T5-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T5-2: readTuple", + MyTransaction); + + check = MyOperation->equal(GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T5-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(GROUP_ALLOW_DELETE, + (char *)&permission); + CHECK_NULL(check2, "T5-2: getValue allow_delete", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-2: NoCommit", + MyTransaction); + + DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("deleting - "); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T5-3: getNdbOperation", + MyTransaction); + + check = MyOperation->deleteTuple(); + CHECK_MINUS_ONE(check, "T5-3: deleteTuple", + MyTransaction); + + check = MyOperation->equal(SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T5-3: equal number", + MyTransaction); + + check = MyOperation->equal(SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-3: equal server id", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-3: NoCommit", + MyTransaction); + + /* Operation 4 */ + MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T5-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(SUBSCRIBER_NUMBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T5-4: equal number", + MyTransaction); + + check = MyOperation->subValue(SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T5-4: dec value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-4: NoCommit", + MyTransaction); + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T5-5: getNdbOperation", + MyTransaction); + + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T5-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(SERVER_DELETES, (uint32)1); + CHECK_MINUS_ONE(check, "T5-5: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-5: NoCommit", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T5: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T5:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + diff --git a/ndb/test/ndbapi/ndb_user_transaction2.cpp b/ndb/test/ndbapi/ndb_user_transaction2.cpp new file mode 100644 index 00000000000..df3c7a7989e --- /dev/null +++ b/ndb/test/ndbapi/ndb_user_transaction2.cpp @@ -0,0 +1,825 @@ +/* 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 */ + +//#define DEBUG_ON + +extern "C" { +#include "user_transaction.h" +}; + +#include "macros.h" +#include "ndb_schema.hpp" +#include "ndb_error.hpp" + +#include +#include + +/** + * Transaction 1 - T1 + * + * Update location and changed by/time on a subscriber + * + * Input: + * SubscriberNumber, + * Location, + * ChangedBy, + * ChangedTime + * + * Output: + */ +int +T1(void * obj, + const SubscriberNumber number, + const Location new_location, + const ChangedBy changed_by, + const ChangedTime changed_time, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction); + + check = MyOperation->updateTuple(); + CHECK_MINUS_ONE(check, "T1: updateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T1: equal subscriber", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_LOCATION, + (char *)&new_location); + CHECK_MINUS_ONE(check, "T1: setValue location", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_MINUS_ONE(check, "T1: setValue changed_by", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_MINUS_ONE(check, "T1: setValue changed_time", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T1: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 2 - T2 + * + * Read from Subscriber: + * + * Input: + * SubscriberNumber + * + * Output: + * Location + * Changed by + * Changed Timestamp + * Name + */ +int +T2(void * obj, + const SubscriberNumber number, + Location * readLocation, + ChangedBy changed_by, + ChangedTime changed_time, + SubscriberName subscriberName, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T2: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T2: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)readLocation); + CHECK_NULL(check2, "T2: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_NULL(check2, "T2: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_NULL(check2, "T2: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_NAME, + subscriberName); + CHECK_NULL(check2, "T2: getValue name", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T2: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 3 - T3 + * + * Read session details + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * + * Output: + * BranchExecuted + * SessionDetails + * ChangedBy + * ChangedTime + * Location + */ +int +T3(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + SessionDetails outSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T3-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T3-1: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T3-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T3-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T3-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T3-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T3-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T3-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T3-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T3-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_READ, + (char *)&permission); + CHECK_NULL(check2, "T3-2: getValue allow_read", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-2: NoCommit", + MyTransaction); + + DEBUG3("T3(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("reading - "); + + /* Operation 3 */ + + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T3-3: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-3: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T3-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-3: equal server id", + MyTransaction); + + check2 = MyOperation->getValue(IND_SESSION_DATA, + (char *)outSessionDetails); + CHECK_NULL(check2, "T3-3: getValue session details", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-3: NoCommit", + MyTransaction); + + /* Operation 4 */ + + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T3-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T3-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-4: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T3-4: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_READS, (uint32)1); + CHECK_MINUS_ONE(check, "T3-4: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-4: NoCommit", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + (* outBranchExecuted) = 0; + } + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T3: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 4 - T4 + * + * Create session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * SessionDetails, + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T4(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + const SessionDetails inSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T4-1: startTranscation", pNDB->getNdbErrorString(), 0); + + DEBUG3("T4(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + NdbOperation * MyOperation = 0; + + MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T4-1: getNdbOperation", + MyTransaction); + + check = MyOperation->readTupleExclusive(); + CHECK_MINUS_ONE(check, "T4-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T4-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T4-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T4-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T4-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T4-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T4-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T4-2: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T4-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T4-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_INSERT, + (char *)&permission); + CHECK_NULL(check2, "T4-2: getValue allow_insert", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-2: NoCommit", + MyTransaction); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == 0)){ + + DEBUG("inserting - "); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T4-3: getNdbOperation", + MyTransaction); + + check = MyOperation->insertTuple(); + CHECK_MINUS_ONE(check, "T4-3: insertTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T4-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-3: equal server id", + MyTransaction); + + check = MyOperation->setValue(SESSION_DATA, + (char *)inSessionDetails); + CHECK_MINUS_ONE(check, "T4-3: setValue session details", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-3: NoCommit", + MyTransaction); + + /* Operation 4 */ + MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T4-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T4-4: equal number", + MyTransaction); + + check = MyOperation->incValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T4-4: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-4: NoCommit", + MyTransaction); + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T4-5: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T4-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_INSERTS, (uint32)1); + CHECK_MINUS_ONE(check, "T4-5: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-5: NoCommit", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T4: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T4:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 5 - T5 + * + * Delete session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T5(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + NdbConnection * MyTransaction = 0; + NdbOperation * MyOperation = 0; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), 0); + + MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T5-1: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTupleExclusive(); + CHECK_MINUS_ONE(check, "T5-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T5-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T5-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T5-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T5-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T5-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T5-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T5-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T5-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T5-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_DELETE, + (char *)&permission); + CHECK_NULL(check2, "T5-2: getValue allow_delete", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-2: NoCommit", + MyTransaction); + + DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("deleting - "); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T5-3: getNdbOperation", + MyTransaction); + + check = MyOperation->deleteTuple(); + CHECK_MINUS_ONE(check, "T5-3: deleteTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T5-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-3: equal server id", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-3: NoCommit", + MyTransaction); + + /* Operation 4 */ + MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T5-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T5-4: equal number", + MyTransaction); + + check = MyOperation->subValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T5-4: dec value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-4: NoCommit", + MyTransaction); + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T5-5: getNdbOperation", + MyTransaction); + + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T5-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_DELETES, (uint32)1); + CHECK_MINUS_ONE(check, "T5-5: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-5: NoCommit", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T5: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T5:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + diff --git a/ndb/test/ndbapi/ndb_user_transaction3.cpp b/ndb/test/ndbapi/ndb_user_transaction3.cpp new file mode 100644 index 00000000000..d2c92ecd424 --- /dev/null +++ b/ndb/test/ndbapi/ndb_user_transaction3.cpp @@ -0,0 +1,793 @@ +/* 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 */ + +//#define DEBUG_ON + +extern "C" { +#include "user_transaction.h" +}; + +#include "macros.h" +#include "ndb_schema.hpp" +#include "ndb_error.hpp" + +#include +#include + +/** + * Transaction 1 - T1 + * + * Update location and changed by/time on a subscriber + * + * Input: + * SubscriberNumber, + * Location, + * ChangedBy, + * ChangedTime + * + * Output: + */ +int +T1(void * obj, + const SubscriberNumber number, + const Location new_location, + const ChangedBy changed_by, + const ChangedTime changed_time, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction); + + check = MyOperation->updateTuple(); + CHECK_MINUS_ONE(check, "T1: updateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T1: equal subscriber", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_LOCATION, + (char *)&new_location); + CHECK_MINUS_ONE(check, "T1: setValue location", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_MINUS_ONE(check, "T1: setValue changed_by", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_MINUS_ONE(check, "T1: setValue changed_time", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T1: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 2 - T2 + * + * Read from Subscriber: + * + * Input: + * SubscriberNumber + * + * Output: + * Location + * Changed by + * Changed Timestamp + * Name + */ +int +T2(void * obj, + const SubscriberNumber number, + Location * readLocation, + ChangedBy changed_by, + ChangedTime changed_time, + SubscriberName subscriberName, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T2: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T2: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)readLocation); + CHECK_NULL(check2, "T2: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_NULL(check2, "T2: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_NULL(check2, "T2: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_NAME, + subscriberName); + CHECK_NULL(check2, "T2: getValue name", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T2: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 3 - T3 + * + * Read session details + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * + * Output: + * BranchExecuted + * SessionDetails + * ChangedBy + * ChangedTime + * Location + */ +int +T3(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + SessionDetails outSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T3-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T3-1: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T3-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T3-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T3-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T3-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T3-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T3-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T3-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T3-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_READ, + (char *)&permission); + CHECK_NULL(check2, "T3-2: getValue allow_read", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-2: NoCommit", + MyTransaction); + + DEBUG3("T3(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("reading - "); + + /* Operation 3 */ + + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T3-3: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-3: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T3-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-3: equal server id", + MyTransaction); + + check2 = MyOperation->getValue(IND_SESSION_DATA, + (char *)outSessionDetails); + CHECK_NULL(check2, "T3-3: getValue session details", + MyTransaction); + + /* Operation 4 */ + + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T3-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T3-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-4: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T3-4: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_READS, (uint32)1); + CHECK_MINUS_ONE(check, "T3-4: inc value", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + (* outBranchExecuted) = 0; + } + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T3: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 4 - T4 + * + * Create session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * SessionDetails, + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T4(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + const SessionDetails inSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T4-1: startTranscation", pNDB->getNdbErrorString(), 0); + + DEBUG3("T4(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + NdbOperation * MyOperation = 0; + + MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T4-1: getNdbOperation", + MyTransaction); + + check = MyOperation->readTupleExclusive(); + CHECK_MINUS_ONE(check, "T4-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T4-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T4-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T4-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T4-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T4-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T4-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T4-2: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T4-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T4-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_INSERT, + (char *)&permission); + CHECK_NULL(check2, "T4-2: getValue allow_insert", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-2: NoCommit", + MyTransaction); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == 0)){ + + DEBUG("inserting - "); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T4-3: getNdbOperation", + MyTransaction); + + check = MyOperation->insertTuple(); + CHECK_MINUS_ONE(check, "T4-3: insertTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T4-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-3: equal server id", + MyTransaction); + + check = MyOperation->setValue(SESSION_DATA, + (char *)inSessionDetails); + CHECK_MINUS_ONE(check, "T4-3: setValue session details", + MyTransaction); + + /* Operation 4 */ + MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T4-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T4-4: equal number", + MyTransaction); + + check = MyOperation->incValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T4-4: inc value", + MyTransaction); + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T4-5: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T4-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_INSERTS, (uint32)1); + CHECK_MINUS_ONE(check, "T4-5: inc value", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T4: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T4:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 5 - T5 + * + * Delete session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T5(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + NdbConnection * MyTransaction = 0; + NdbOperation * MyOperation = 0; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), 0); + + MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T5-1: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTupleExclusive(); + CHECK_MINUS_ONE(check, "T5-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T5-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T5-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T5-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T5-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T5-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T5-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T5-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T5-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T5-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_DELETE, + (char *)&permission); + CHECK_NULL(check2, "T5-2: getValue allow_delete", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-2: NoCommit", + MyTransaction); + + DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("deleting - "); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T5-3: getNdbOperation", + MyTransaction); + + check = MyOperation->deleteTuple(); + CHECK_MINUS_ONE(check, "T5-3: deleteTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T5-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-3: equal server id", + MyTransaction); + + /* Operation 4 */ + MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T5-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T5-4: equal number", + MyTransaction); + + check = MyOperation->subValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T5-4: dec value", + MyTransaction); + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T5-5: getNdbOperation", + MyTransaction); + + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T5-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_DELETES, (uint32)1); + CHECK_MINUS_ONE(check, "T5-5: inc value", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T5: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T5:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + diff --git a/ndb/test/ndbapi/ndb_user_transaction4.cpp b/ndb/test/ndbapi/ndb_user_transaction4.cpp new file mode 100644 index 00000000000..e652c7bfed8 --- /dev/null +++ b/ndb/test/ndbapi/ndb_user_transaction4.cpp @@ -0,0 +1,770 @@ +/* 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 */ + +//#define DEBUG_ON + +extern "C" { +#include "user_transaction.h" +}; + +#include "macros.h" +#include "ndb_schema.hpp" +#include "ndb_error.hpp" + +#include +#include + +/** + * Transaction 1 - T1 + * + * Update location and changed by/time on a subscriber + * + * Input: + * SubscriberNumber, + * Location, + * ChangedBy, + * ChangedTime + * + * Output: + */ +int +T1(void * obj, + const SubscriberNumber number, + const Location new_location, + const ChangedBy changed_by, + const ChangedTime changed_time, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + DEBUG2("T1(%.*s):\n", SUBSCRIBER_NUMBER_LENGTH, number); + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T1-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction); + + check = MyOperation->updateTuple(); + CHECK_MINUS_ONE(check, "T1: updateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T1: equal subscriber", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_LOCATION, + (char *)&new_location); + CHECK_MINUS_ONE(check, "T1: setValue location", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_MINUS_ONE(check, "T1: setValue changed_by", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_MINUS_ONE(check, "T1: setValue changed_time", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T1: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 2 - T2 + * + * Read from Subscriber: + * + * Input: + * SubscriberNumber + * + * Output: + * Location + * Changed by + * Changed Timestamp + * Name + */ +int +T2(void * obj, + const SubscriberNumber number, + Location * readLocation, + ChangedBy changed_by, + ChangedTime changed_time, + SubscriberName subscriberName, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + DEBUG2("T2(%.*s):\n", SUBSCRIBER_NUMBER_LENGTH, number); + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T2-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T2: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)readLocation); + CHECK_NULL(check2, "T2: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_NULL(check2, "T2: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_NULL(check2, "T2: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_NAME, + subscriberName); + CHECK_NULL(check2, "T2: getValue name", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T2: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 3 - T3 + * + * Read session details + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * + * Output: + * BranchExecuted + * SessionDetails + * ChangedBy + * ChangedTime + * Location + */ +int +T3(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + SessionDetails outSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + DEBUG3("T3(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T3-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T3-1: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T3-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T3-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T3-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T3-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T3-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T3-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T3-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T3-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_READ, + (char *)&permission); + CHECK_NULL(check2, "T3-2: getValue allow_read", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-2: NoCommit", + MyTransaction); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("reading - "); + + /* Operation 3 */ + + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T3-3: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-3: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T3-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-3: equal server id", + MyTransaction); + + check2 = MyOperation->getValue(IND_SESSION_DATA, + (char *)outSessionDetails); + CHECK_NULL(check2, "T3-3: getValue session details", + MyTransaction); + + /* Operation 4 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T3-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T3-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-4: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T3-4: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_READS, (uint32)1); + CHECK_MINUS_ONE(check, "T3-4: inc value", + MyTransaction); + (* outBranchExecuted) = 1; + } else { + (* outBranchExecuted) = 0; + } + DEBUG("commit..."); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T3: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + DEBUG("done\n"); + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 4 - T4 + * + * Create session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * SessionDetails, + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T4(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + const SessionDetails inSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + DEBUG3("T4(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T4-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T4-1: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T4-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T4-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T4-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T4-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T4-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T4-1: getValue sessions", + MyTransaction); + + check = MyOperation->incValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T4-4: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T4-2: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T4-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T4-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_INSERT, + (char *)&permission); + CHECK_NULL(check2, "T4-2: getValue allow_insert", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-2: NoCommit", + MyTransaction); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == 0)){ + + DEBUG("inserting - "); + + /* Operation 3 */ + + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T4-3: getNdbOperation", + MyTransaction); + + check = MyOperation->insertTuple(); + CHECK_MINUS_ONE(check, "T4-3: insertTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T4-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-3: equal server id", + MyTransaction); + + check = MyOperation->setValue(SESSION_DATA, + (char *)inSessionDetails); + CHECK_MINUS_ONE(check, "T4-3: setValue session details", + MyTransaction); + + /* Operation 4 */ + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T4-5: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T4-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_INSERTS, (uint32)1); + CHECK_MINUS_ONE(check, "T4-5: inc value", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback && (* outBranchExecuted)){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T4: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T4:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 5 - T5 + * + * Delete session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T5(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + Ndb * pNDB = (Ndb *) obj; + NdbConnection * MyTransaction = 0; + NdbOperation * MyOperation = 0; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), 0); + + MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T5-1: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T5-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T5-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T5-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T5-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T5-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T5-1: getValue sessions", + MyTransaction); + + check = MyOperation->subValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T5-4: dec value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T5-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T5-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T5-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_DELETE, + (char *)&permission); + CHECK_NULL(check2, "T5-2: getValue allow_delete", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-2: NoCommit", + MyTransaction); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("deleting - "); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T5-3: getNdbOperation", + MyTransaction); + + check = MyOperation->deleteTuple(); + CHECK_MINUS_ONE(check, "T5-3: deleteTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T5-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-3: equal server id", + MyTransaction); + + /* Operation 4 */ + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T5-5: getNdbOperation", + MyTransaction); + + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T5-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_DELETES, (uint32)1); + CHECK_MINUS_ONE(check, "T5-5: inc value", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback && (* outBranchExecuted)){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T5: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T5:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + diff --git a/ndb/test/ndbapi/ndb_user_transaction5.cpp b/ndb/test/ndbapi/ndb_user_transaction5.cpp new file mode 100644 index 00000000000..86580008d10 --- /dev/null +++ b/ndb/test/ndbapi/ndb_user_transaction5.cpp @@ -0,0 +1,769 @@ +/* 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 */ + +//#define DEBUG_ON + +extern "C" { +#include "user_transaction.h" +}; + +#include "macros.h" +#include "ndb_schema.hpp" +#include "ndb_error.hpp" + +#include +#include + +/** + * Transaction 1 - T1 + * + * Update location and changed by/time on a subscriber + * + * Input: + * SubscriberNumber, + * Location, + * ChangedBy, + * ChangedTime + * + * Output: + */ +int +T1(void * obj, + const SubscriberNumber number, + const Location new_location, + const ChangedBy changed_by, + const ChangedTime changed_time, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + DEBUG2("T1(%.*s):\n", SUBSCRIBER_NUMBER_LENGTH, number); + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T1-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction); + + check = MyOperation->updateTuple(); + CHECK_MINUS_ONE(check, "T1: updateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T1: equal subscriber", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_LOCATION, + (char *)&new_location); + CHECK_MINUS_ONE(check, "T1: setValue location", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_MINUS_ONE(check, "T1: setValue changed_by", + MyTransaction); + + check = MyOperation->setValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_MINUS_ONE(check, "T1: setValue changed_time", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T1: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 2 - T2 + * + * Read from Subscriber: + * + * Input: + * SubscriberNumber + * + * Output: + * Location + * Changed by + * Changed Timestamp + * Name + */ +int +T2(void * obj, + const SubscriberNumber number, + Location * readLocation, + ChangedBy changed_by, + ChangedTime changed_time, + SubscriberName subscriberName, + BenchmarkTime * transaction_time){ + + Ndb * pNDB = (Ndb *) obj; + + DEBUG2("T2(%.*s):\n", SUBSCRIBER_NUMBER_LENGTH, number); + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T2-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + CHECK_MINUS_ONE(check, "T2: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)readLocation); + CHECK_NULL(check2, "T2: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + CHECK_NULL(check2, "T2: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + CHECK_NULL(check2, "T2: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_NAME, + subscriberName); + CHECK_NULL(check2, "T2: getValue name", + MyTransaction); + + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T2: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + get_time(transaction_time); + time_diff(transaction_time, &start); + return 0; +} + +/** + * Transaction 3 - T3 + * + * Read session details + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * + * Output: + * BranchExecuted + * SessionDetails + * ChangedBy + * ChangedTime + * Location + */ +int +T3(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + SessionDetails outSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T3-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T3-1: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T3-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T3-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T3-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T3-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T3-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T3-1: getValue sessions", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T3-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T3-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T3-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_READ, + (char *)&permission); + CHECK_NULL(check2, "T3-2: getValue allow_read", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-2: NoCommit", + MyTransaction); + + DEBUG3("T3(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("reading - "); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T3-3: getNdbOperation", + MyTransaction); + + check = MyOperation->simpleRead(); + CHECK_MINUS_ONE(check, "T3-3: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T3-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-3: equal server id", + MyTransaction); + + check2 = MyOperation->getValue(IND_SESSION_DATA, + (char *)outSessionDetails); + CHECK_NULL(check2, "T3-3: getValue session details", + MyTransaction); + + /* Operation 4 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T3-4: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T3-4: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T3-4: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T3-4: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_READS, (uint32)1); + CHECK_MINUS_ONE(check, "T3-4: inc value", + MyTransaction); + (* outBranchExecuted) = 1; + } else { + (* outBranchExecuted) = 0; + } + DEBUG("commit..."); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T3: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + DEBUG("done\n"); + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 4 - T4 + * + * Create session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * SessionDetails, + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T4(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + const SessionDetails inSessionDetails, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T4-1: startTranscation", pNDB->getNdbErrorString(), 0); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T4-1: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T4-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T4-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T4-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T4-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T4-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T4-1: getValue sessions", + MyTransaction); + + check = MyOperation->incValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T4-4: inc value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T4-2: getNdbOperation", + MyTransaction); + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T4-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T4-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_INSERT, + (char *)&permission); + CHECK_NULL(check2, "T4-2: getValue allow_insert", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-2: NoCommit", + MyTransaction); + + DEBUG3("T4(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == 0)){ + + DEBUG("inserting - "); + + /* Operation 3 */ + + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T4-3: getNdbOperation", + MyTransaction); + + check = MyOperation->insertTuple(); + CHECK_MINUS_ONE(check, "T4-3: insertTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T4-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-3: equal server id", + MyTransaction); + + check = MyOperation->setValue(SESSION_DATA, + (char *)inSessionDetails); + CHECK_MINUS_ONE(check, "T4-3: setValue session details", + MyTransaction); + + /* Operation 4 */ + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T4-5: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T4-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T4-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T4-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_INSERTS, (uint32)1); + CHECK_MINUS_ONE(check, "T4-5: inc value", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback && (* outBranchExecuted)){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T4: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T4:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + + +/** + * Transaction 5 - T5 + * + * Delete session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +int +T5(void * obj, + const SubscriberNumber inNumber, + const SubscriberSuffix inSuffix, + const ServerId inServerId, + const ServerBit inServerBit, + ChangedBy outChangedBy, + ChangedTime outChangedTime, + Location * outLocation, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted, + BenchmarkTime * outTransactionTime){ + + Ndb * pNDB = (Ndb *) obj; + NdbConnection * MyTransaction = 0; + NdbOperation * MyOperation = 0; + + GroupId groupId; + ActiveSessions sessions; + Permission permission; + + BenchmarkTime start; + get_time(&start); + + int check; + NdbRecAttr * check2; + + MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), 0); + + MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T5-1: getNdbOperation", + MyTransaction); + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-1: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + CHECK_MINUS_ONE(check, "T5-1: equal subscriber", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)outLocation); + CHECK_NULL(check2, "T5-1: getValue location", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + CHECK_NULL(check2, "T5-1: getValue changed_by", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + CHECK_NULL(check2, "T5-1: getValue changed_time", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + CHECK_NULL(check2, "T5-1: getValue group", + MyTransaction); + + check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + CHECK_NULL(check2, "T5-1: getValue sessions", + MyTransaction); + + check = MyOperation->subValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + CHECK_MINUS_ONE(check, "T5-4: dec value", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T5-2: getNdbOperation", + MyTransaction); + + + check = MyOperation->readTuple(); + CHECK_MINUS_ONE(check, "T5-2: readTuple", + MyTransaction); + + check = MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + CHECK_MINUS_ONE(check, "T5-2: equal group", + MyTransaction); + + check2 = MyOperation->getValue(IND_GROUP_ALLOW_DELETE, + (char *)&permission); + CHECK_NULL(check2, "T5-2: getValue allow_delete", + MyTransaction); + + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-2: NoCommit", + MyTransaction); + + DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + DEBUG("deleting - "); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T5-3: getNdbOperation", + MyTransaction); + + check = MyOperation->deleteTuple(); + CHECK_MINUS_ONE(check, "T5-3: deleteTuple", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + CHECK_MINUS_ONE(check, "T5-3: equal number", + MyTransaction); + + check = MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-3: equal server id", + MyTransaction); + + /* Operation 4 */ + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T5-5: getNdbOperation", + MyTransaction); + + + check = MyOperation->interpretedUpdateTuple(); + CHECK_MINUS_ONE(check, "T5-5: interpretedUpdateTuple", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + CHECK_MINUS_ONE(check, "T5-5: equal serverId", + MyTransaction); + + check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + CHECK_MINUS_ONE(check, "T5-5: equal suffix", + MyTransaction); + + check = MyOperation->incValue(IND_SERVER_DELETES, (uint32)1); + CHECK_MINUS_ONE(check, "T5-5: inc value", + MyTransaction); + + (* outBranchExecuted) = 1; + } else { + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + (* outBranchExecuted) = 0; + } + + if(!inDoRollback && (* outBranchExecuted)){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T5: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T5:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); + + get_time(outTransactionTime); + time_diff(outTransactionTime, &start); + return 0; +} + diff --git a/ndb/test/ndbapi/ndb_user_transaction6.cpp b/ndb/test/ndbapi/ndb_user_transaction6.cpp new file mode 100644 index 00000000000..262f38e9ffb --- /dev/null +++ b/ndb/test/ndbapi/ndb_user_transaction6.cpp @@ -0,0 +1,561 @@ +/* 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 */ + +//#define DEBUG_ON + +#include +#include "userHandle.h" +#include "userInterface.h" + +#include "macros.h" +#include "ndb_schema.hpp" +#include "ndb_error.hpp" + +#include + + +void +userCheckpoint(UserHandle *uh){ +} + +inline +NdbConnection * +startTransaction(Ndb * pNDB, ServerId inServerId, const SubscriberNumber inNumber){ + + const int keyDataLenBytes = sizeof(ServerId)+SUBSCRIBER_NUMBER_LENGTH; + const int keyDataLen_64Words = keyDataLenBytes >> 3; + + Uint64 keyDataBuf[keyDataLen_64Words+1]; // The "+1" is for rounding... + + char * keyDataBuf_charP = (char *)&keyDataBuf[0]; + Uint32 * keyDataBuf_wo32P = (Uint32 *)&keyDataBuf[0]; + + // Server Id comes first + keyDataBuf_wo32P[0] = inServerId; + // Then subscriber number + memcpy(&keyDataBuf_charP[sizeof(ServerId)], inNumber, SUBSCRIBER_NUMBER_LENGTH); + + return pNDB->startTransaction(0, keyDataBuf_charP, keyDataLenBytes); +} + +/** + * Transaction 1 - T1 + * + * Update location and changed by/time on a subscriber + * + * Input: + * SubscriberNumber, + * Location, + * ChangedBy, + * ChangedTime + * + * Output: + */ +void +userTransaction_T1(UserHandle * uh, + SubscriberNumber number, + Location new_location, + ChangedBy changed_by, + ChangedTime changed_time){ + Ndb * pNDB = uh->pNDB; + + DEBUG2("T1(%.*s):\n", SUBSCRIBER_NUMBER_LENGTH, number); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction != NULL) { + NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + if (MyOperation != NULL) { + MyOperation->updateTuple(); + MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + MyOperation->setValue(IND_SUBSCRIBER_LOCATION, + (char *)&new_location); + MyOperation->setValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + MyOperation->setValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + check = MyTransaction->execute( Commit ); + if (check != -1) { + pNDB->closeTransaction(MyTransaction); + return; + } else { + CHECK_MINUS_ONE(check, "T1: Commit", + MyTransaction); + }//if + } else { + CHECK_NULL(MyOperation, "T1: getNdbOperation", MyTransaction); + }//if + } else { + error_handler("T1-1: startTranscation", pNDB->getNdbErrorString(), pNDB->getNdbError()); + }//if +} + +/** + * Transaction 2 - T2 + * + * Read from Subscriber: + * + * Input: + * SubscriberNumber + * + * Output: + * Location + * Changed by + * Changed Timestamp + * Name + */ +void +userTransaction_T2(UserHandle * uh, + SubscriberNumber number, + Location * readLocation, + ChangedBy changed_by, + ChangedTime changed_time, + SubscriberName subscriberName){ + Ndb * pNDB = uh->pNDB; + + DEBUG2("T2(%.*s):\n", SUBSCRIBER_NUMBER_LENGTH, number); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T2-1: startTransaction", pNDB->getNdbErrorString(), pNDB->getNdbError()); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T2: getNdbOperation", + MyTransaction); + + MyOperation->readTuple(); + MyOperation->equal(IND_SUBSCRIBER_NUMBER, + number); + MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)readLocation); + MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + changed_by); + MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + changed_time); + MyOperation->getValue(IND_SUBSCRIBER_NAME, + subscriberName); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T2: Commit", + MyTransaction); + pNDB->closeTransaction(MyTransaction); +} + +/** + * Transaction 3 - T3 + * + * Read session details + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * + * Output: + * BranchExecuted + * SessionDetails + * ChangedBy + * ChangedTime + * Location + */ +void +userTransaction_T3(UserHandle * uh, + SubscriberNumber inNumber, + ServerId inServerId, + ServerBit inServerBit, + SessionDetails outSessionDetails, + BranchExecuted * outBranchExecuted){ + Ndb * pNDB = uh->pNDB; + + char outChangedBy [sizeof(ChangedBy) +(4-(sizeof(ChangedBy) & 3))]; + char outChangedTime [sizeof(ChangedTime)+(4-(sizeof(ChangedTime) & 3))]; + Location outLocation; + GroupId groupId; + ActiveSessions sessions; + Permission permission; + SubscriberSuffix inSuffix; + + DEBUG3("T3(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = startTransaction(pNDB, inServerId, inNumber); + if (MyTransaction == NULL) + error_handler("T3-1: startTranscation", pNDB->getNdbErrorString(), pNDB->getNdbError()); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T3-1: getNdbOperation", + MyTransaction); + + MyOperation->readTuple(); + MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&outLocation); + MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-1: NoCommit", + MyTransaction); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T3-2: getNdbOperation", + MyTransaction); + + + MyOperation->readTuple(); + MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + MyOperation->getValue(IND_GROUP_ALLOW_READ, + (char *)&permission); + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T3-2: NoCommit", + MyTransaction); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + memcpy(inSuffix, + &inNumber[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + DEBUG2("reading(%.*s) - ", SUBSCRIBER_NUMBER_SUFFIX_LENGTH, inSuffix); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T3-3: getNdbOperation", + MyTransaction); + + MyOperation->simpleRead(); + + MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + MyOperation->getValue(IND_SESSION_DATA, + (char *)outSessionDetails); + /* Operation 4 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T3-4: getNdbOperation", + MyTransaction); + + MyOperation->interpretedUpdateTuple(); + MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + MyOperation->incValue(IND_SERVER_READS, (uint32)1); + (* outBranchExecuted) = 1; + } else { + (* outBranchExecuted) = 0; + } + DEBUG("commit..."); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T3: Commit", + MyTransaction); + + pNDB->closeTransaction(MyTransaction); + + DEBUG("done\n"); +} + + +/** + * Transaction 4 - T4 + * + * Create session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * SessionDetails, + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +void +userTransaction_T4(UserHandle * uh, + SubscriberNumber inNumber, + ServerId inServerId, + ServerBit inServerBit, + SessionDetails inSessionDetails, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted){ + + Ndb * pNDB = uh->pNDB; + + char outChangedBy [sizeof(ChangedBy) +(4-(sizeof(ChangedBy) & 3))]; + char outChangedTime [sizeof(ChangedTime)+(4-(sizeof(ChangedTime) & 3))]; + Location outLocation; + GroupId groupId; + ActiveSessions sessions; + Permission permission; + SubscriberSuffix inSuffix; + + DEBUG3("T4(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + int check; + NdbRecAttr * check2; + + NdbConnection * MyTransaction = startTransaction(pNDB, inServerId, inNumber); + if (MyTransaction == NULL) + error_handler("T4-1: startTranscation", pNDB->getNdbErrorString(), pNDB->getNdbError()); + + NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T4-1: getNdbOperation", + MyTransaction); + + MyOperation->interpretedUpdateTuple(); + MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&outLocation); + MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + outChangedBy); + MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + outChangedTime); + MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + MyOperation->incValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + check = MyTransaction->execute( NoCommit ); + + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T4-2: getNdbOperation", + MyTransaction); + + MyOperation->readTuple(); + MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + MyOperation->getValue(IND_GROUP_ALLOW_INSERT, + (char *)&permission); + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T4-2: NoCommit", + MyTransaction); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == 0)){ + + memcpy(inSuffix, + &inNumber[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + + DEBUG2("inserting(%.*s) - ", SUBSCRIBER_NUMBER_SUFFIX_LENGTH, inSuffix); + + /* Operation 3 */ + + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T4-3: getNdbOperation", + MyTransaction); + + MyOperation->insertTuple(); + MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + MyOperation->setValue(SESSION_DATA, + (char *)inSessionDetails); + /* Operation 4 */ + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T4-5: getNdbOperation", + MyTransaction); + + MyOperation->interpretedUpdateTuple(); + MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + MyOperation->incValue(IND_SERVER_INSERTS, (uint32)1); + (* outBranchExecuted) = 1; + } else { + (* outBranchExecuted) = 0; + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + } + + if(!inDoRollback && (* outBranchExecuted)){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T4: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T4:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); +} + + +/** + * Transaction 5 - T5 + * + * Delete session + * + * Input: + * SubscriberNumber + * ServerId + * ServerBit + * DoRollback + * Output: + * ChangedBy + * ChangedTime + * Location + * BranchExecuted + */ +void +userTransaction_T5(UserHandle * uh, + SubscriberNumber inNumber, + ServerId inServerId, + ServerBit inServerBit, + DoRollback inDoRollback, + BranchExecuted * outBranchExecuted){ + Ndb * pNDB = uh->pNDB; + + DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId); + + NdbConnection * MyTransaction = 0; + NdbOperation * MyOperation = 0; + + char outChangedBy [sizeof(ChangedBy) +(4-(sizeof(ChangedBy) & 3))]; + char outChangedTime [sizeof(ChangedTime)+(4-(sizeof(ChangedTime) & 3))]; + Location outLocation; + GroupId groupId; + ActiveSessions sessions; + Permission permission; + SubscriberSuffix inSuffix; + + int check; + NdbRecAttr * check2; + + MyTransaction = pNDB->startTransaction(); + if (MyTransaction == NULL) + error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), pNDB->getNdbError()); + + MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "T5-1: getNdbOperation", + MyTransaction); + + MyOperation->interpretedUpdateTuple(); + MyOperation->equal(IND_SUBSCRIBER_NUMBER, + inNumber); + MyOperation->getValue(IND_SUBSCRIBER_LOCATION, + (char *)&outLocation); + MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, + &outChangedBy[0]); + MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, + &outChangedTime[0]); + MyOperation->getValue(IND_SUBSCRIBER_GROUP, + (char *)&groupId); + MyOperation->getValue(IND_SUBSCRIBER_SESSIONS, + (char *)&sessions); + MyOperation->subValue(IND_SUBSCRIBER_SESSIONS, + (uint32)inServerBit); + MyTransaction->execute( NoCommit ); + /* Operation 2 */ + + MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "T5-2: getNdbOperation", + MyTransaction); + + MyOperation->readTuple(); + MyOperation->equal(IND_GROUP_ID, + (char*)&groupId); + MyOperation->getValue(IND_GROUP_ALLOW_DELETE, + (char *)&permission); + check = MyTransaction->execute( NoCommit ); + CHECK_MINUS_ONE(check, "T5-2: NoCommit", + MyTransaction); + + if(((permission & inServerBit) == inServerBit) && + ((sessions & inServerBit) == inServerBit)){ + + memcpy(inSuffix, + &inNumber[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH], SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + + DEBUG2("deleting(%.*s) - ", SUBSCRIBER_NUMBER_SUFFIX_LENGTH, inSuffix); + + /* Operation 3 */ + MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE); + CHECK_NULL(MyOperation, "T5-3: getNdbOperation", + MyTransaction); + + MyOperation->deleteTuple(); + MyOperation->equal(IND_SESSION_SUBSCRIBER, + (char*)inNumber); + MyOperation->equal(IND_SESSION_SERVER, + (char*)&inServerId); + /* Operation 4 */ + + /* Operation 5 */ + MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "T5-5: getNdbOperation", + MyTransaction); + + + MyOperation->interpretedUpdateTuple(); + MyOperation->equal(IND_SERVER_ID, + (char*)&inServerId); + MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX, + (char*)inSuffix); + MyOperation->incValue(IND_SERVER_DELETES, (uint32)1); + (* outBranchExecuted) = 1; + } else { + (* outBranchExecuted) = 0; + DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - ")); + DEBUG1("%s", ((sessions & inServerBit) ? "in session - " : "no in session - ")); + } + + if(!inDoRollback && (* outBranchExecuted)){ + DEBUG("commit\n"); + check = MyTransaction->execute( Commit ); + CHECK_MINUS_ONE(check, "T5: Commit", + MyTransaction); + } else { + DEBUG("rollback\n"); + check = MyTransaction->execute(Rollback); + CHECK_MINUS_ONE(check, "T5:Rollback", + MyTransaction); + + } + + pNDB->closeTransaction(MyTransaction); +} + diff --git a/ndb/test/ndbapi/old_dirs/acid/Makefile b/ndb/test/ndbapi/old_dirs/acid/Makefile new file mode 100644 index 00000000000..33dc49fcdea --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/acid/Makefile @@ -0,0 +1,10 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := acid + +# Source files of non-templated classes (.C files) +SOURCES = acid.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/acid2/Makefile b/ndb/test/ndbapi/old_dirs/acid2/Makefile new file mode 100644 index 00000000000..69c9d409b9e --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/acid2/Makefile @@ -0,0 +1,10 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := acid2 + +# Source files of non-templated classes (.C files) +SOURCES = acid2.cpp TraceNdbApi.cpp VerifyNdbApi.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/acid2/TraceNdbApi.hpp b/ndb/test/ndbapi/old_dirs/acid2/TraceNdbApi.hpp new file mode 100644 index 00000000000..2bd4eab6b70 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/acid2/TraceNdbApi.hpp @@ -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; 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 */ + + +#ifndef TraceNdbApi_hpp +#define TraceNdbApi_hpp + + +class CTraceNdbSchemaOp : public NdbSchemaOp +{ +public: + int createTable(const char* aTableName); + int createAttribute(const char* aAttrName, KeyType aTupleyKey); +}; + + + +class CTraceNdbSchemaCon : public NdbSchemaCon +{ +public: + CTraceNdbSchemaOp* getNdbSchemaOp(); + int execute(); +}; + + + +class CTraceNdbRecAttr : public NdbRecAttr +{ +public: + Uint32 u_32_value(); +}; + + +class CTraceNdbOperation : public NdbOperation +{ +public: + int insertTuple(); + int updateTuple(); + int interpretedUpdateTuple(); + int readTuple(); + int readTupleExclusive(); + int deleteTuple(); + int equal(const char* anAttrName, Uint32 aValue); + int setValue(const char* anAttrName, Uint32 aValue); + int incValue(const char* anAttrName, Uint32 aValue); + CTraceNdbRecAttr* getValue(const char* anAttrName); + +}; + + +class CTraceNdbIndexOperation : public NdbIndexOperation +{ +public: + int insertTuple(); + int updateTuple(); + int interpretedUpdateTuple(); + int readTuple(); + int readTupleExclusive(); + int deleteTuple(); + int equal(const char* anAttrName, Uint32 aValue); + int setValue(const char* anAttrName, Uint32 aValue); + int incValue(const char* anAttrName, Uint32 aValue); + CTraceNdbRecAttr* getValue(const char* anAttrName); +}; + + + +class CTraceNdbConnection : public NdbConnection +{ +public: + CTraceNdbOperation* getNdbOperation(const char* aTableName); + CTraceNdbIndexOperation* getNdbIndexOperation(const char* anIndexName, const char* aTableName); + + int execute(ExecType aTypeOfExec); + + int execute_ok(ExecType aTypeOfExec) + { + return execute(aTypeOfExec); + }; + + const NdbError & getNdbError(void) const; +}; + + + +class CTraceNdbDictionary : public NdbDictionary +{ +public: + class CTraceTable : public Table + { + }; + + class CTraceIndex : public Index + { + }; + + class CTraceColumn : public Column + { + }; + + int createTable(const CTraceTable &); + int createIndex(const CTraceIndex &); +}; + + + +class CTraceNdb : public Ndb +{ +public: + CTraceNdb(const char* aDataBase); + CTraceNdbSchemaCon* startSchemaTransaction(); + void closeSchemaTransaction(CTraceNdbSchemaCon* aSchemaCon); + CTraceNdbConnection* startTransaction(); + void closeTransaction(CTraceNdbConnection* aConnection); +}; + + + +#endif // TraceNdbApi_hpp diff --git a/ndb/test/ndbapi/old_dirs/acid2/VerifyNdbApi.hpp b/ndb/test/ndbapi/old_dirs/acid2/VerifyNdbApi.hpp new file mode 100644 index 00000000000..4a5b8cc8111 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/acid2/VerifyNdbApi.hpp @@ -0,0 +1,466 @@ +/* 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 */ + + +#ifndef VerifyNdbApi_hpp +#define VerifyNdbApi_hpp + + +class CVerifyNdbSchemaOp : public NdbSchemaOp +{ +public: + int createTable(const char* aTableName) + { + int i = NdbSchemaOp::createTable(aTableName); + VerifyInt(i, "createTable"); + return i; + }; + + int createAttribute(const char* aAttrName, KeyType aTupleyKey) + { + int i = NdbSchemaOp::createAttribute(aAttrName, aTupleyKey); + VerifyInt(i, "createAttribute"); + return i; + }; + +private: + void VerifyInt(const int i, const char* szMethod) + { + if(i) + { + VerifyIntError(i, szMethod); + } + } + + void VerifyIntError(const int i, const char* szMethod); +}; + + + +class CVerifyNdbSchemaCon : public NdbSchemaCon +{ +public: + CVerifyNdbSchemaOp* getNdbSchemaOp() + { + NdbSchemaOp* p = NdbSchemaCon::getNdbSchemaOp(); + VerifyPtr(p, "getNdbSchemaOp"); + return (CVerifyNdbSchemaOp*)p; + }; + + int execute() + { + int i = NdbSchemaCon::execute(); + VerifyInt(i, "execute"); + return i; + }; + +private: + void VerifyInt(const int i, const char* szMethod) + { + if(i) + { + VerifyIntError(i, szMethod); + } + } + + void VerifyPtr(void* p, const char* szMethod) + { + if(!p) + { + VerifyPtrError(p, szMethod); + } + } + + void VerifyIntError(const int i, const char* szMethod); + void VerifyPtrError(void* p, const char* szMethod); +}; + + + +class CVerifyNdbRecAttr : public NdbRecAttr +{ +public: + Uint32 u_32_value() + { + Uint32 n = NdbRecAttr::u_32_value(); + VerifyValue("u_32_value"); + return n; + }; + +private: + void VerifyValue(const char* szMethod) + { + int iNull = NdbRecAttr::isNULL(); + if(iNull) + { + VerifyValueError(iNull, szMethod); + } + }; + + void VerifyValueError(const int iNull, const char* szMethod); +}; + + +class CVerifyNdbOperation : public NdbOperation +{ +public: + int insertTuple() + { + int i = NdbOperation::insertTuple(); + VerifyInt(i, "insertTuple"); + return i; + }; + + int updateTuple() + { + int i = NdbOperation::updateTuple(); + VerifyInt(i, "updateTuple"); + return i; + }; + + int interpretedUpdateTuple() + { + int i = NdbOperation::interpretedUpdateTuple(); + VerifyInt(i, "interpretedUpdateTuple"); + return i; + } + + int readTuple() + { + int i = NdbOperation::readTuple(); + VerifyInt(i, "readTuple"); + return i; + } + + int readTupleExclusive() + { + int i = NdbOperation::readTupleExclusive(); + VerifyInt(i, "readTupleExclusive"); + return i; + } + + int deleteTuple() + { + int i = NdbOperation::deleteTuple(); + VerifyInt(i, "deleteTuple"); + return i; + } + + int equal(const char* anAttrName, Uint32 aValue) + { + int i = NdbOperation::equal(anAttrName, aValue); + VerifyInt(i, "equal"); + return i; + } + + int setValue(const char* anAttrName, Uint32 aValue) + { + int i = NdbOperation::setValue(anAttrName, aValue); + VerifyInt(i, "setValue"); + return i; + } + + int incValue(const char* anAttrName, Uint32 aValue) + { + int i = NdbOperation::incValue(anAttrName, aValue); + VerifyInt(i, "incValue"); + return i; + } + + CVerifyNdbRecAttr* getValue(const char* anAttrName) + { + NdbRecAttr* p = NdbOperation::getValue(anAttrName); + VerifyPtr(p, "getValue"); + return (CVerifyNdbRecAttr*)p; + } + + +private: + void VerifyInt(const int i, const char* szMethod) + { + if(i) + { + VerifyIntError(i, szMethod); + } + } + + void VerifyPtr(void* p, const char* szMethod) + { + if(!p) + { + VerifyPtrError(p, szMethod); + } + } + + void VerifyIntError(const int i, const char* szMethod); + void VerifyPtrError(void* p, const char* szMethod); +}; + + +class CVerifyNdbIndexOperation : public NdbIndexOperation +{ +public: + int insertTuple() + { + int i = NdbIndexOperation::insertTuple(); + VerifyInt(i, "insertTuple"); + return i; + }; + + int updateTuple() + { + int i = NdbIndexOperation::updateTuple(); + VerifyInt(i, "updateTuple"); + return i; + }; + + int interpretedUpdateTuple() + { + int i = NdbIndexOperation::interpretedUpdateTuple(); + VerifyInt(i, "interpretedUpdateTuple"); + return i; + } + + int readTuple() + { + int i = NdbIndexOperation::readTuple(); + VerifyInt(i, "readTuple"); + return i; + } + + int readTupleExclusive() + { + int i = NdbIndexOperation::readTupleExclusive(); + VerifyInt(i, "readTupleExclusive"); + return i; + } + + int deleteTuple() + { + int i = NdbIndexOperation::deleteTuple(); + VerifyInt(i, "deleteTuple"); + return i; + } + + int equal(const char* anAttrName, Uint32 aValue) + { + int i = NdbIndexOperation::equal(anAttrName, aValue); + VerifyInt(i, "equal"); + return i; + } + + int setValue(const char* anAttrName, Uint32 aValue) + { + int i = NdbIndexOperation::setValue(anAttrName, aValue); + VerifyInt(i, "setValue"); + return i; + } + + int incValue(const char* anAttrName, Uint32 aValue) + { + int i = NdbIndexOperation::incValue(anAttrName, aValue); + VerifyInt(i, "incValue"); + return i; + } + + CVerifyNdbRecAttr* getValue(const char* anAttrName) + { + NdbRecAttr* p = NdbIndexOperation::getValue(anAttrName); + VerifyPtr(p, "getValue"); + return (CVerifyNdbRecAttr*)p; + } + + +private: + void VerifyInt(const int i, const char* szMethod) + { + if(i) + { + VerifyIntError(i, szMethod); + } + } + + void VerifyPtr(void* p, const char* szMethod) + { + if(!p) + { + VerifyPtrError(p, szMethod); + } + } + + void VerifyIntError(const int i, const char* szMethod); + void VerifyPtrError(void* p, const char* szMethod); +}; + + +class CVerifyNdbConnection : public NdbConnection +{ +public: + CVerifyNdbOperation* getNdbOperation(const char* aTableName) + { + NdbOperation* p = NdbConnection::getNdbOperation(aTableName); + VerifyPtr(p, "getNdbOperation"); + return (CVerifyNdbOperation*)p; + } + + CVerifyNdbIndexOperation* getNdbIndexOperation(const char* anIndexName, const char* aTableName) + { + NdbIndexOperation* p = NdbConnection::getNdbIndexOperation(anIndexName, aTableName); + VerifyPtr(p, "getNdbIndexOperation"); + return (CVerifyNdbIndexOperation*)p; + } + + int execute(ExecType aTypeOfExec) + { + int i = NdbConnection::execute(aTypeOfExec); + VerifyInt(i, "execute"); + return i; + } + + int execute_ok(ExecType aTypeOfExec) + { + int iExec = NdbConnection::execute(aTypeOfExec); + NdbError err = NdbConnection::getNdbError(); + int iCode = err.code; + if(iExec + && ((aTypeOfExec==NoCommit && iCode!=0) + || (aTypeOfExec==Commit && iCode!=626 && iCode!=630))) + { + VerifyInt(iExec, "execute"); + } + return iExec; + } + + +private: + void VerifyInt(const int i, const char* szMethod) + { + if(i) + { + VerifyIntError(i, szMethod); + } + } + + void VerifyPtr(void* p, const char* szMethod) + { + if(!p) + { + VerifyPtrError(p, szMethod); + } + } + + void VerifyIntError(const int i, const char* szMethod); + void VerifyPtrError(void* p, const char* szMethod); +}; + + +//class CVerifyTable : public NdbDictionary::Table +//{ +//public: +//}; + + +class CVerifyNdbDictionary : public NdbDictionary +{ +public: + class CVerifyTable : public Table + { + public: + private: + }; + + class CVerifyIndex : public Index + { + public: + private: + }; + + class CVerifyColumn : public Column + { + public: + private: + }; + + int createTable(const CVerifyTable &); + int createIndex(const CVerifyIndex &); + + +private: +}; + + +class CVerifyNdb : public Ndb +{ +public: + CVerifyNdb(const char* aDataBase) + : Ndb(aDataBase) + { + VerifyVoid("Ndb"); + }; + + CVerifyNdbSchemaCon* startSchemaTransaction() + { + NdbSchemaCon* p = Ndb::startSchemaTransaction(); + VerifyPtr(p, "startSchemaTransaction"); + return (CVerifyNdbSchemaCon*)p; + }; + + void closeSchemaTransaction(CVerifyNdbSchemaCon* aSchemaCon) + { + Ndb::closeSchemaTransaction(aSchemaCon); + VerifyVoid("closeSchemaTransaction"); + }; + + CVerifyNdbConnection* startTransaction() + { + NdbConnection* p = Ndb::startTransaction(); + VerifyPtr(p, "startTransaction"); + return (CVerifyNdbConnection*)p; + }; + + void closeTransaction(CVerifyNdbConnection* aConnection) + { + Ndb::closeTransaction(aConnection); + VerifyVoid("closeTransaction"); + }; + + +private: + void VerifyPtr(void* p, const char* szMethod) + { + if(!p) + { + VerifyPtrError(p, szMethod); + } + } + + void VerifyVoid(const char* szMethod) + { + NdbError err = Ndb::getNdbError(); + int iCode = err.code; + if(iCode) + { + VerifyVoidError(iCode, szMethod); + } + } + + void VerifyPtrError(void* p, const char* szMethod); + void VerifyVoidError(const int iCode, const char* szMethod); +}; + + + +#endif // VerifyNdbApi_hpp diff --git a/ndb/test/ndbapi/old_dirs/basicAsynch/Makefile b/ndb/test/ndbapi/old_dirs/basicAsynch/Makefile new file mode 100755 index 00000000000..802c5e5a2bd --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/basicAsynch/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := testBasicAsynch + +SOURCES := testBasicAsynch.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/bulk_copy/Makefile b/ndb/test/ndbapi/old_dirs/bulk_copy/Makefile new file mode 100644 index 00000000000..22c05b138b7 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/bulk_copy/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := bulk_copy + +SOURCES := bulk_copy.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/create_all_tabs/Makefile b/ndb/test/ndbapi/old_dirs/create_all_tabs/Makefile new file mode 100644 index 00000000000..58309807682 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/create_all_tabs/Makefile @@ -0,0 +1,11 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := create_all_tabs + +# Source files of non-templated classes (.C files) +SOURCES = create_all_tabs.cpp + +include $(NDB_TOP)/Epilogue.mk + diff --git a/ndb/test/ndbapi/old_dirs/create_tab/Makefile b/ndb/test/ndbapi/old_dirs/create_tab/Makefile new file mode 100644 index 00000000000..c2ea0b52b15 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/create_tab/Makefile @@ -0,0 +1,11 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := create_tab + +# Source files of non-templated classes (.C files) +SOURCES = create_tab.cpp + +include $(NDB_TOP)/Epilogue.mk + diff --git a/ndb/test/ndbapi/old_dirs/drop_all_tabs/Makefile b/ndb/test/ndbapi/old_dirs/drop_all_tabs/Makefile new file mode 100644 index 00000000000..96db0781417 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/drop_all_tabs/Makefile @@ -0,0 +1,11 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := drop_all_tabs + +# Source files of non-templated classes (.C files) +SOURCES = drop_all_tabs.cpp + +include $(NDB_TOP)/Epilogue.mk + diff --git a/ndb/test/ndbapi/old_dirs/flexAsynch/Makefile b/ndb/test/ndbapi/old_dirs/flexAsynch/Makefile new file mode 100644 index 00000000000..2c77c8e21df --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/flexAsynch/Makefile @@ -0,0 +1,11 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := flexAsynch + +# Source files of non-templated classes (.C files) +SOURCES = flexAsynch.cpp + +include $(NDB_TOP)/Epilogue.mk + diff --git a/ndb/test/ndbapi/old_dirs/flexBench/Makefile.am b/ndb/test/ndbapi/old_dirs/flexBench/Makefile.am new file mode 100644 index 00000000000..d4de4b92b60 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/flexBench/Makefile.am @@ -0,0 +1,10 @@ + +bin_PROGRAMS = flexBench + +flexBench_SOURCES = flexBench.cpp + +include $(top_srcdir)/ndb/config/common.mk.am +include $(top_srcdir)/ndb/config/type_ndbapitest.mk.am + +# Don't update the files from bitkeeper +%::SCCS/s.% diff --git a/ndb/test/ndbapi/old_dirs/flexBench/Makefile_old b/ndb/test/ndbapi/old_dirs/flexBench/Makefile_old new file mode 100644 index 00000000000..bfff5cd161a --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/flexBench/Makefile_old @@ -0,0 +1,11 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := flexBench + +# Source files of non-templated classes (.C files) +SOURCES = flexBench.cpp + +include $(NDB_TOP)/Epilogue.mk + diff --git a/ndb/test/ndbapi/old_dirs/flexBench/ndbplot.pl b/ndb/test/ndbapi/old_dirs/flexBench/ndbplot.pl new file mode 100755 index 00000000000..b16f6d5897d --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/flexBench/ndbplot.pl @@ -0,0 +1,305 @@ +#! /usr/bin/perl + +use strict; +use Getopt::Long; +use Symbol; +use Socket; + +my $progname = $0; +$progname =~ s!^.*/|\.pl$!!g; +my $defaultport = 27127; +my $defaulttotal = 120; +my $defaultsample = 5; +my $defaultrange = 5000; + +sub printhelp { + print < \$helpflag, + 'debug' => \$debug, + 'port=i' => \$serverport, + 'total=i' => \$totaltime, + 'sample=i' => \$sampletime, + 'range=i' => \$range, + 'nopct' => \$nopct, + 'z=s' => \@zopts, +) or die "try: $progname -h\n"; +$helpflag && printhelp(); + +# calculate number of data points +my $samplecnt; +$samplecnt = int($totaltime / $sampletime) + 1; +$totaltime = ($samplecnt - 1) * $sampletime; +warn "total time = $totaltime sec, sample time = $sampletime sec\n"; + +# open gnuplot +my $plotfile; +sub openplot { + $plotfile = gensym(); + if (! open($plotfile, "| gnuplot @zopts")) { + die "open plot: $!\n"; + } + my $sav = select($plotfile); + $| = 1; + select($sav); + print $plotfile "clear\n"; +} + +# samples +my @sample; # samples 0..$samplecnt in time order +my $sampleready = 0; # samples 1..$samplecnt are ready (true/false) + +@sample = map({ start => 0 }, 0..$samplecnt); + +sub adddata { + my($node, $type, $value) = @_; + my $now = time; + my $s = $sample[0]; + if ($now - $s->{start} >= $sampletime) { + unshift(@sample, { + start => $now, + total => 0, + }); + $s = $sample[0]; + pop(@sample); # delete oldest + $sampleready = 1; + } + # if no type then this is just a time tick + if ($type) { + $s->{$type} += $value; + $s->{total} += $value; + } +} + +# data file name +my $datadir; +if ($ENV{NDB_BASE}) { + $datadir = "$ENV{NDB_BASE}/var/plot"; +} else { + $datadir = "/var/tmp"; +} +(-d $datadir || mkdir($datadir, 0777)) + or die "mkdir $datadir failed: $!\n"; +my $datafile = "$datadir/plot$$.dat"; +warn "writing plot data to $datafile\n"; + +# refresh the plot +sub plotsample { + my $fh = gensym(); + if (! open($fh, ">$datafile")) { + die "$datafile: $!\n"; + } + # sample 0 is never ready + my $currops = ""; + my $currpct = {}; + for (my $i = @sample; $i >= 1; $i--) { + my $s = $sample[$i]; + if (! $s->{start}) { # initial empty sample + next; + } + printf $fh "%d", -($i - 1) * $sampletime; + printf $fh " %.0f", 1.01 * $s->{"total"} / $sampletime; + for my $k (qw(insert update select delete)) { + printf $fh " %.0f", $s->{$k} / $sampletime; + } + printf $fh "\n"; + if ($i == 1) { + $currops = sprintf("%.0f", $s->{"total"} / $sampletime); + if (! $nopct && $currops > 0) { + $currpct->{"total"} = sprintf("%5s", ""); + for my $k (qw(insert update select delete)) { + $currpct->{$k} = sprintf(" %3.0f%%", + 100.0 * $s->{$k} / $s->{"total"}); + } + } + } + } + close($fh); + print $plotfile <{insert}" \\ + with lines lt 2, \\ + '$datafile' \\ + using 1:4 \\ + title "update$currpct->{update}" \\ + with lines lt 3, \\ + '$datafile' \\ + using 1:5 \\ + title "select$currpct->{select}" \\ + with lines lt 4, \\ + '$datafile' \\ + using 1:6 \\ + title "delete$currpct->{delete}" \\ + with lines lt 5, \\ + '$datafile' \\ + using 1:2 \\ + title "total$currpct->{total}" \\ + with lines lt 1 lw 2 +END +} + +# set up server socket +my $sock = gensym(); +if (! socket($sock, PF_INET, SOCK_STREAM, getprotobyname("tcp"))) { + die "socket: $!\n"; +} +if (! setsockopt($sock, SOL_SOCKET, SO_REUSEADDR, pack("l*", 1))) { + die "setsockopt: $!\n"; +} +if (! bind($sock, pack_sockaddr_in($serverport, INADDR_ANY))) { + die "bind: $!\n"; +} +if (! listen($sock, SOMAXCONN)) { + die "listen: $!\n"; +} + +# bit vectors for select on server socket and clients +my $readin = ''; +vec($readin, fileno($sock), 1) = 1; + +# clients +my @client = (); +my $clientid = 0; +sub addclient { + my($conn) = @_; + my $c = { + conn => $conn, + data => "", + name => "client " . ++$clientid, + }; + push(@client, $c); + vec($readin, fileno($c->{conn}), 1) = 1; + if (1 || $debug) { + warn "added $c->{name}\n"; + } +} +sub deleteclient { + my($c) = @_; + @client = grep($_ ne $c, @client); + vec($readin, fileno($c->{conn}), 1) = 0; + shutdown($c->{conn}, 2); + if (1 || $debug) { + warn "deleted $c->{name}\n"; + } +} +sub readclient { + my($c) = @_; + my $data; + my $n; + eval { + local $SIG{ALRM} = sub { die "timeout\n" }; + alarm(5); + $n = sysread($c->{conn}, $data, 512); + alarm(0); + }; + if ($@) { + chomp($@); + warn "$c->{name}: read: $@\n"; + return undef; + } + if (!defined($n)) { + warn "$c->{name}: read: $!\n"; + return undef; + } + $c->{data} .= $data; + if ($debug) { + warn "$c->{name}: read @{[ length($data) ]} bytes\n"; + } + return $n; +} +sub processclient { + my($c) = @_; + my $i; + while (($i = index($c->{data}, "\n")) >= 0) { + my $line = substr($c->{data}, 0, $i); + $c->{data} = substr($c->{data}, $i+1); + my($node, $type, $value) = split(' ', $line); + if ($node !~ /^\d+$/) { + warn "$c->{name}: $line: bad node id\n"; + next; + } + if ($type !~ /^(insert|update|read|delete|verify|verifydelete)$/) { + warn "$c->{name}: $line: bad type\n"; + next; + } + if ($value !~ /^\d+$/) { + warn "$c->{name}: $line: bad value\n"; + next; + } + if ($type eq "read") { + $type = "select"; + } + adddata($node, $type, $value); + } +} + +# main loop +openplot(); +while (1) { + my $readout = ''; + my $ret = select($readout = $readin, undef, undef, 1.0); + if (vec($readout, fileno($sock), 1)) { + my $conn = gensym(); + if (! accept($conn, $sock)) { + warn "accept failed: $!\n"; + } else { + addclient($conn); + } + } + for my $c (@client) { + if (vec($readout, fileno($c->{conn}), 1)) { + my $n = readclient($c); + if (! defined($n)) { + deleteclient($c); + } else { + processclient($c); + if ($n == 0) { # end of file + deleteclient($c); + } + } + } + } + adddata(); # keep clock ticking + if ($sampleready) { + if ($debug) { + warn "sample ready\n"; + } + plotsample(); + $sampleready = 0; + } +} +# vim: set sw=4: diff --git a/ndb/test/ndbapi/old_dirs/flexHammer/Makefile b/ndb/test/ndbapi/old_dirs/flexHammer/Makefile new file mode 100644 index 00000000000..c8e436fb7f5 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/flexHammer/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := flexHammer + +SOURCES := flexHammer.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/flexHammer/README b/ndb/test/ndbapi/old_dirs/flexHammer/README new file mode 100644 index 00000000000..556582aab96 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/flexHammer/README @@ -0,0 +1,67 @@ + +Executing flexHammer-tests automatically +======================================== + + +It is possible to execute almost al the flexHammer-tests +automatically. The procedure contains three steps: +- increase the number of tabels (flexHammer -c number) +- increase the number of threads (flexHammer -t number) +- increase the number of records (flexHammer -r number) +- increase the number of tabels and threads alternately + +Each of these steps are performed by the scripts test1.sh, +test2.sh, test3.sh and test4.sh. Each test will start Ndb, +execute the test and close Ndb again in order to execute +each test in a 'clean' Ndb-environment. So make sure that +there is no Ndb running when you start the test. + + +1. Setup + +To perform the tests automatically, the following issues +have to be taken care of: + +- be sure that you have a directory bin in your home-directory. + In this directory, you need to have a link 'runndb' to the + ndb executable. You can do this by executing a shell-command like: + ln -s ndb/Emulator/Main/ndb runndb + The script is not yet so far that it performs checks, so if + you forget about this, things will get messy. +- In this directory you need a Ndb.cfg for a server-configuration. + + +2. Command + +I assume you have Ndb and the API compiled or you use the +'released' version. Compile flexHammer as usual with 'make'. +Now you can start the tests by typing 'make test'. The +execution of the test will take a while. + + +3. Results + +The scripts will write their results in the file report.txt. +The scripts will start with a short summary on the test. Then +it will add 1 line documenting each run of flexHammer that is +ececuted. Finally, it will print highest 'score'. The file +report.txt is probably good enough to check in directly as +testprotocol in ndb/test/docs/testprotocols. + + +4. Log files. + +To make it possible to investigate errors, the output from +the flexScan-run where the error occurred is stored in +test1.log, test2.log, test3.log or test4.log respectively. +They are overwritten each time you start 'make test'. + + +HINT + +The number of iterations in each test-script is not directly +limited by the number of attributes or the size of the +attributes but by the number of tables that you are allowed +to create. Probably this will be the error that occurs if +you execute the test. You migh adjust the begin-values and +the step-size in the individual scripts if you want. diff --git a/ndb/test/ndbapi/old_dirs/flexScan/Makefile b/ndb/test/ndbapi/old_dirs/flexScan/Makefile new file mode 100644 index 00000000000..78f9d481063 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/flexScan/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := flexScan + +SOURCES := flexScan.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/flexScan/README b/ndb/test/ndbapi/old_dirs/flexScan/README new file mode 100644 index 00000000000..cddbdea5336 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/flexScan/README @@ -0,0 +1,66 @@ + +Executing flexScan-tests automatically +====================================== + + +It is possible to execute almost al the flexBench-tests +automatically. The procedure contains three steps: +- increase the number of attributes (flexScan -a number) +- increase the size of attributes (flexScan -s number) +- increase the number of threads (flexScan -t number) + +Each of these steps are performed by the scripts test1.sh +test2.sh and test3.sh. Each test will start Ndb, execute +the test and close Ndb again in order to execute each test +in a 'clean' Ndb-environment. So make sure that there is +no Ndb running when you start the test. + + +1. Setup + +To perform the tests automatically, the following issues +have to be taken care of: + +- be sure that you have a directory bin in your home-directory. + In this directory, you need to have a link 'runndb' to the + ndb executable. You can do this by executing a shell-command like: + ln -s ndb/Emulator/Main/ndb runndb + The script is not yet so far that it performs checks, so if + you forget about this, things will get messy. +- In this directory you need a Ndb.cfg for a server-configuration. + + +2. Command + +I assume you have Ndb and the API compiled or you use the +'released' version. Compile flexScan as usual with 'make'. +Now you can start the tests by typing 'make test'. The +execution of the test will take a while. + + +3. Results + +The scripts will write their results in the file report.txt. +The scripts will start with a short summary on the test. Then +it will add 1 line documenting each run of flexScan that is +ececuted. Finally, it will print highest 'score'. The file +report.txt is probably good enough to check in directly as +testprotocol in ndb/test/docs/testprotocols. + + +4. Log files. + +To make it possible to investigate errors, the output from +the flexScan-run where the error occurred is stored in +test1.log, test2.log or test3.log respectively. They are +overwritten each time you start 'make test'. + + +HINT + +The number of iterations in each test-script is not directly +limited by the number of attributes or the size of the +attributes but by the number of tables that you are allowed +to create. Probably this will be the error that occurs if +you execute the test. You migh adjust the begin-values and +the step-size in the individual scripts if you want. diff --git a/ndb/test/ndbapi/old_dirs/flexTT/Makefile b/ndb/test/ndbapi/old_dirs/flexTT/Makefile new file mode 100644 index 00000000000..a63bd803d95 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/flexTT/Makefile @@ -0,0 +1,11 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := flexTT + +# Source files of non-templated classes (.C files) +SOURCES = flexTT.cpp + +include $(NDB_TOP)/Epilogue.mk + diff --git a/ndb/test/ndbapi/old_dirs/flexTimedAsynch/Makefile b/ndb/test/ndbapi/old_dirs/flexTimedAsynch/Makefile new file mode 100644 index 00000000000..e9995dbd16f --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/flexTimedAsynch/Makefile @@ -0,0 +1,11 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := flexTimedAsynch + +# Source files of non-templated classes (.C files) +SOURCES = flexTimedAsynch.cpp + +include $(NDB_TOP)/Epilogue.mk + diff --git a/ndb/test/ndbapi/old_dirs/flex_bench_mysql/Makefile b/ndb/test/ndbapi/old_dirs/flex_bench_mysql/Makefile new file mode 100644 index 00000000000..d2608526cae --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/flex_bench_mysql/Makefile @@ -0,0 +1,15 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := flex_bench_mysql + +# Source files of non-templated classes (.C files) +SOURCES = flex_bench_mysql.cpp + +CCFLAGS_LOC += -I$(call fixpath,$(NDB_TOP)/../include) +BIN_TARGET_LIBS_DIRS += $(NDB_TOP)/../libmysql_r/.libs +BIN_TARGET_LIBS += z mysqlclient_r + +include $(NDB_TOP)/Epilogue.mk + diff --git a/ndb/test/ndbapi/old_dirs/indexTest/Makefile b/ndb/test/ndbapi/old_dirs/indexTest/Makefile new file mode 100644 index 00000000000..d842e487ee5 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/indexTest/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := index + +SOURCES := index.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/indexTest2/Makefile b/ndb/test/ndbapi/old_dirs/indexTest2/Makefile new file mode 100644 index 00000000000..ad78fd51986 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/indexTest2/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := index2 + +SOURCES := index2.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/interpreterInTup/Makefile b/ndb/test/ndbapi/old_dirs/interpreterInTup/Makefile new file mode 100644 index 00000000000..074adbf674a --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/interpreterInTup/Makefile @@ -0,0 +1,10 @@ +include .defs.mk + +TYPE := ndbapitest + + +BIN_TARGET := interpreterInTup + +SOURCES := interpreterInTup.cc + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/Makefile b/ndb/test/ndbapi/old_dirs/lmc-bench/Makefile new file mode 100644 index 00000000000..af472b1589f --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/Makefile @@ -0,0 +1,6 @@ +include .defs.mk + +DIRS := src async-src script + +include $(NDB_TOP)/Epilogue.mk + diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/Makefile b/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/Makefile new file mode 100644 index 00000000000..744d6171139 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/Makefile @@ -0,0 +1,8 @@ +include .defs.mk + +DIRS = \ + user \ + generator + +include $(NDB_TOP)/Epilogue.mk + diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/generator/Makefile b/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/generator/Makefile new file mode 100644 index 00000000000..c1f84a3ef70 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/generator/Makefile @@ -0,0 +1,13 @@ +include .defs.mk + +TYPE := ndbapitest + +SOURCES = mainAsyncGenerator.cpp asyncGenerator.cpp + +CCFLAGS_LOC := -I../include -I../../include + +BIN_TARGET := DbAsyncGenerator +BIN_TARGET_ARCHIVES := lmc_AsyncUser + +include $(NDB_TOP)/Epilogue.mk + diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/include/dbGenerator.h b/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/include/dbGenerator.h new file mode 100644 index 00000000000..2256498e151 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/include/dbGenerator.h @@ -0,0 +1,63 @@ +/* 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 */ + +#ifndef DBGENERATOR_H +#define DBGENERATOR_H + +/*************************************************************** +* I N C L U D E D F I L E S * +***************************************************************/ + +#include "testData.h" +#include "userInterface.h" + +/*************************************************************** +* M A C R O S * +***************************************************************/ + +/***************************************************************/ +/* C O N S T A N T S */ +/***************************************************************/ + +/*************************************************************** +* D A T A S T R U C T U R E S * +***************************************************************/ + +/*************************************************************** +* P U B L I C F U N C T I O N S * +***************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +extern void asyncGenerator(ThreadData *d, int parallellism, + int millisSendPoll, + int minEventSendPoll, + int forceSendPoll); + +#ifdef __cplusplus +} +#endif + +/*************************************************************** +* E X T E R N A L D A T A * +***************************************************************/ + + + +#endif /* DBGENERATOR_H */ + diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/include/testData.h b/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/include/testData.h new file mode 100644 index 00000000000..3db85e7342e --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/include/testData.h @@ -0,0 +1,156 @@ +/* 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 */ + +#ifndef TESTDATA_H +#define TESTDATA_H + +/*************************************************************** +* I N C L U D E D F I L E S * +***************************************************************/ +#include +#include +#include +#include +#include "testDefinitions.h" + +/*************************************************************** +* M A C R O S * +***************************************************************/ + +/***************************************************************/ +/* C O N S T A N T S */ +/***************************************************************/ + +#define NUM_TRANSACTION_TYPES 5 +#define SESSION_LIST_LENGTH 1000 + +/*************************************************************** +* D A T A S T R U C T U R E S * +***************************************************************/ + +typedef struct { + SubscriberNumber subscriberNumber; + ServerId serverId; +} SessionElement; + +typedef struct { + SessionElement list[SESSION_LIST_LENGTH]; + unsigned int readIndex; + unsigned int writeIndex; + unsigned int numberInList; +} SessionList; + +typedef struct { + unsigned int count; + unsigned int branchExecuted; + unsigned int rollbackExecuted; + + /** + * Latency measures + */ + NDB_TICKS startTime; + NDBT_Stats latency; + unsigned int latencyCounter; + + inline void startLatency(){ + if((latencyCounter & 127) == 127) + startTime = NdbTick_CurrentMillisecond(); + } + + inline void stopLatency(){ + if((latencyCounter & 127) == 127){ + const NDB_TICKS tmp = NdbTick_CurrentMillisecond() - startTime; + latency.addObservation(tmp); + } + latencyCounter++; + } +} TransactionDefinition; + +typedef struct { + RandomSequence transactionSequence; + RandomSequence rollbackSequenceT4; + RandomSequence rollbackSequenceT5; + + TransactionDefinition transactions[NUM_TRANSACTION_TYPES]; + + unsigned int totalTransactions; + + double outerLoopTime; + double outerTps; + + SessionList activeSessions; + +} GeneratorStatistics; + +typedef enum{ + Runnable, + Running +} RunState ; + +typedef struct { + SubscriberNumber number; + SubscriberSuffix suffix; + SubscriberName name; + Location location; + ChangedBy changed_by; + ChangedTime changed_time; + ServerId server_id; + ServerBit server_bit; + SessionDetails session_details; + + GroupId group_id; + ActiveSessions sessions; + Permission permission; + + unsigned int do_rollback; + + unsigned int branchExecuted; + unsigned int sessionElement; +} TransactionData ; + +typedef struct { + struct NdbThread* pThread; + + unsigned long randomSeed; + unsigned long changedTime; + + unsigned int warmUpSeconds; + unsigned int testSeconds; + unsigned int coolDownSeconds; + + GeneratorStatistics generator; + + /** + * For async execution + */ + RunState runState; + double startTime; + TransactionData transactionData; + struct Ndb * pNDB; +} ThreadData; + +/*************************************************************** + * P U B L I C F U N C T I O N S * + ***************************************************************/ + +/*************************************************************** + * E X T E R N A L D A T A * + ***************************************************************/ + + + +#endif /* TESTDATA_H */ + diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/include/userInterface.h b/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/include/userInterface.h new file mode 100644 index 00000000000..94bd1e80ab3 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/include/userInterface.h @@ -0,0 +1,79 @@ +/* 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 */ + +#ifndef DBINTERFACE_H +#define DBINTERFACE_H + +/***************************************************************/ +/* I N C L U D E D F I L E S */ +/***************************************************************/ + +#include "testDefinitions.h" +#include "testData.h" + +/*************************************************************** +* M A C R O S * +***************************************************************/ + +/***************************************************************/ +/* C O N S T A N T S */ +/***************************************************************/ + +/*-----------------------*/ +/* Default Database Name */ +/*-----------------------*/ +#define DEFAULTDB "TestDbClient" + +/*************************************************************** +* D A T A S T R U C T U R E S * +***************************************************************/ + +/*************************************************************** +* P U B L I C F U N C T I O N S * +***************************************************************/ + +typedef struct Ndb Ndb; + +#ifdef __cplusplus +extern "C" { +#endif + extern void showTime(); + extern double userGetTime(void); + extern Ndb *asyncDbConnect(int parallellism); + extern void asyncDbDisconnect(Ndb* pNDB); + + extern void start_T1(Ndb * uh, ThreadData * data, int async); + extern void start_T2(Ndb * uh, ThreadData * data, int async); + extern void start_T3(Ndb * uh, ThreadData * data, int async); + extern void start_T4(Ndb * uh, ThreadData * data, int async); + extern void start_T5(Ndb * uh, ThreadData * data, int async); + + extern void complete_T1(ThreadData * data); + extern void complete_T2(ThreadData * data); + extern void complete_T3(ThreadData * data); + extern void complete_T4(ThreadData * data); + extern void complete_T5(ThreadData * data); + +#ifdef __cplusplus +} +#endif + +/*************************************************************** +* E X T E R N A L D A T A * +***************************************************************/ + +#endif /* DBINTERFACE_H */ + diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/user/Makefile b/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/user/Makefile new file mode 100644 index 00000000000..c0b532a8359 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/user/Makefile @@ -0,0 +1,11 @@ +include .defs.mk + +TYPE := ndbapitest + +ARCHIVE_TARGET := lmc_AsyncUser + +SOURCES := userInterface.C ndb_async2.C + +CCFLAGS_LOC = -I../include -I../../include + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/user/macros.h b/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/user/macros.h new file mode 100644 index 00000000000..22b7f564490 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/user/macros.h @@ -0,0 +1,51 @@ +/* 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 */ + +#ifndef MACROS_H +#define MACROS_H + +#include +#include + +#define ERROR(x) {ndbout_c((x));} +#define ERROR1(x,y) {ndbout_c((x), (y));} +#define ERROR2(x,y,z) {ndbout_c((x), (y), (z));} +#define ERROR3(x,y,z,u) {ndbout_c((x), (y), (z), (u));} +#define ERROR4(x,y,z,u,w) {ndbout_c((x), (y), (z), (u), (w));} + +#define INIT_RANDOM(x) srand48((x)) +#define UI_RANDOM(x) ((unsigned int)(lrand48()%(x))) + +#define ASSERT(cond, message) \ + { if(!(cond)) { ERROR(message); exit(-1); }} + +#ifdef DEBUG_ON +#define DEBUG(x) {ndbout_c((x));} +#define DEBUG1(x,y) {ndbout_c((x), (y));} +#define DEBUG2(x,y,z) {ndbout_c((x), (y), (z));} +#define DEBUG3(x,y,z,u) {ndbout_c((x), (y), (z), (u));} +#define DEBUG4(x,y,z,u,w) {ndbout_c((x), (y), (z), (u), (w));} +#define DEBUG5(x,y,z,u,w, v) {ndbout_c((x), (y), (z), (u), (w), (v));} +#else +#define DEBUG(x) +#define DEBUG1(x,y) +#define DEBUG2(x,y,z) +#define DEBUG3(x,y,z,u) +#define DEBUG4(x,y,z,u,w) +#define DEBUG5(x,y,z,u,w, v) +#endif + +#endif diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/user/ndb_error.hpp b/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/user/ndb_error.hpp new file mode 100644 index 00000000000..9e6c5e55e73 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/async-src/user/ndb_error.hpp @@ -0,0 +1,63 @@ +/* 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 */ + +#ifndef NDB_ERROR_H +#define NDB_ERROR_H + +#include +#include +#include "userInterface.h" +#include + +inline +void +CHECK_ALLOWED_ERROR(const char * str, + const ThreadData * td, + const struct NdbError & error){ + + char buf[100]; + snprintf(buf, sizeof(buf), "subscriber = %.*s ", + SUBSCRIBER_NUMBER_LENGTH, + td->transactionData.number); + ndbout << str << " " << error << endl + << buf; + showTime(); + + switch(error.classification) { + case NdbError::TimeoutExpired: + case NdbError::OverloadError: + case NdbError::TemporaryResourceError: + case NdbError::NodeRecoveryError: + break; + default: + if(error.status != NdbError::TemporaryError) + exit(-1); + } +} + +inline +void +CHECK_NULL(void * null, + const char * str, + const ThreadData * td, + const struct NdbError & err){ + if(null == 0){ + CHECK_ALLOWED_ERROR(str, td, err); + exit(-1); + } +} + +#endif diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/bin/.empty b/ndb/test/ndbapi/old_dirs/lmc-bench/bin/.empty new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/include/ndb_schema.hpp b/ndb/test/ndbapi/old_dirs/lmc-bench/include/ndb_schema.hpp new file mode 100644 index 00000000000..af08bc2eecd --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/include/ndb_schema.hpp @@ -0,0 +1,78 @@ +/* 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 */ + +#ifndef NDB_SCHEMA_H +#define NDB_SCHEMA_H + +#include "testDefinitions.h" + +#define SUBSCRIBER_TABLE "SUBSCRIBER" +#define SUBSCRIBER_NUMBER "NUMBER" +#define SUBSCRIBER_LOCATION "LOCATION" +#define SUBSCRIBER_NAME "NAME" +#define SUBSCRIBER_GROUP "GROUP_ID" +#define SUBSCRIBER_SESSIONS "SESSIONS" +#define SUBSCRIBER_CHANGED_BY "CHANGED_BY" +#define SUBSCRIBER_CHANGED_TIME "CHANGED_TIME" + +#define SERVER_TABLE "SERVER" +#define SERVER_ID "SERVER_ID" +#define SERVER_SUBSCRIBER_SUFFIX "SUFFIX" +#define SERVER_NAME "NAME" +#define SERVER_READS "NO_OF_READ" +#define SERVER_INSERTS "NO_OF_INSERT" +#define SERVER_DELETES "NO_OF_DELETE" + +#define GROUP_TABLE "GROUP" +#define GROUP_ID "GROUP_ID" +#define GROUP_NAME "GROUP_NAME" +#define GROUP_ALLOW_READ "ALLOW_READ" +#define GROUP_ALLOW_INSERT "ALLOW_INSERT" +#define GROUP_ALLOW_DELETE "ALLOW_DELETE" + +#define SESSION_TABLE "SESSION" +#define SESSION_SERVER "SERVER_ID" +#define SESSION_SUBSCRIBER "NUMBER" +#define SESSION_DATA "DATA" + +/** Numbers */ + +#define IND_SUBSCRIBER_NUMBER (unsigned)0 +#define IND_SUBSCRIBER_NAME (unsigned)1 +#define IND_SUBSCRIBER_GROUP (unsigned)2 +#define IND_SUBSCRIBER_LOCATION (unsigned)3 +#define IND_SUBSCRIBER_SESSIONS (unsigned)4 +#define IND_SUBSCRIBER_CHANGED_BY (unsigned)5 +#define IND_SUBSCRIBER_CHANGED_TIME (unsigned)6 + +#define IND_SERVER_SUBSCRIBER_SUFFIX (unsigned)0 +#define IND_SERVER_ID (unsigned)1 +#define IND_SERVER_NAME (unsigned)2 +#define IND_SERVER_READS (unsigned)3 +#define IND_SERVER_INSERTS (unsigned)4 +#define IND_SERVER_DELETES (unsigned)5 + +#define IND_GROUP_ID (unsigned)0 +#define IND_GROUP_NAME (unsigned)1 +#define IND_GROUP_ALLOW_READ (unsigned)2 +#define IND_GROUP_ALLOW_INSERT (unsigned)3 +#define IND_GROUP_ALLOW_DELETE (unsigned)4 + +#define IND_SESSION_SUBSCRIBER (unsigned)0 +#define IND_SESSION_SERVER (unsigned)1 +#define IND_SESSION_DATA (unsigned)2 + +#endif diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/include/testDefinitions.h b/ndb/test/ndbapi/old_dirs/lmc-bench/include/testDefinitions.h new file mode 100644 index 00000000000..2f4aeb30975 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/include/testDefinitions.h @@ -0,0 +1,90 @@ +/* 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 */ + +#ifndef TESTDEFINITIONS_H +#define TESTDEFINITIONS_H + +/***************************************************************/ +/* I N C L U D E D F I L E S */ +/***************************************************************/ + +#include + +/***************************************************************/ +/* C O N S T A N T S */ +/***************************************************************/ + +#define OP_PER_TRANS 200 +#define NO_OF_SUBSCRIBERS 500000 +#define NO_OF_GROUPS 100 +#define NO_OF_SERVERS 20 + +#define SUBSCRIBER_NUMBER_LENGTH 12 +#define SUBSCRIBER_NUMBER_SUFFIX_LENGTH 2 + +#define SUBSCRIBER_NAME_LENGTH 32 +#define CHANGED_BY_LENGTH 32 +#define CHANGED_TIME_LENGTH 32 +#define SESSION_DETAILS_LENGTH 2000 +#define SERVER_NAME_LENGTH 32 +#define GROUP_NAME_LENGTH 32 + +/*************************************************************** +* D A T A S T R U C T U R E S * +***************************************************************/ + +#define PADDING 4 + +typedef char SubscriberNumber[SUBSCRIBER_NUMBER_LENGTH]; +typedef char SubscriberSuffix[SUBSCRIBER_NUMBER_SUFFIX_LENGTH + 2]; +typedef char SubscriberName[SUBSCRIBER_NAME_LENGTH]; +typedef char ServerName[SERVER_NAME_LENGTH]; +typedef char GroupName[GROUP_NAME_LENGTH]; +typedef char ChangedBy[CHANGED_BY_LENGTH]; +typedef char ChangedTime[CHANGED_TIME_LENGTH]; +typedef char SessionDetails[SESSION_DETAILS_LENGTH]; +typedef Uint32 ServerId; +typedef Uint32 ServerBit; +typedef Uint32 GroupId; +typedef Uint32 Location; +typedef Uint32 Permission; + +typedef Uint32 Counter; +typedef Uint32 ActiveSessions; +typedef unsigned int BranchExecuted; +typedef unsigned int DoRollback; + +/*************************************************************** +* P U B L I C F U N C T I O N S * +***************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __cplusplus +} +#endif + +/*************************************************************** +* E X T E R N A L D A T A * +***************************************************************/ + + + +#endif /* TESTDEFINITIONS_H */ + diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/lib/.empty b/ndb/test/ndbapi/old_dirs/lmc-bench/lib/.empty new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/script/Makefile b/ndb/test/ndbapi/old_dirs/lmc-bench/script/Makefile new file mode 100644 index 00000000000..240b5957573 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/script/Makefile @@ -0,0 +1,5 @@ +include .defs.mk + +SOURCES.sh := async-lmc-bench.sh async-lmc-bench-l.sh async-lmc-bench-p10.sh async-lmc-bench-l-p10.sh + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/script/async-lmc-bench-l-p10.sh b/ndb/test/ndbapi/old_dirs/lmc-bench/script/async-lmc-bench-l-p10.sh new file mode 100755 index 00000000000..1ce3969f9fb --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/script/async-lmc-bench-l-p10.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +DbCreate -l +ret=$? +if [ $ret -ne 0 ] +then + echo "DbCreate failed" + exit $ret +fi + +DbAsyncGenerator -time 300 -p 10 $* +ret=$? +exit $ret + diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/script/async-lmc-bench-l.sh b/ndb/test/ndbapi/old_dirs/lmc-bench/script/async-lmc-bench-l.sh new file mode 100755 index 00000000000..a5de71395c4 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/script/async-lmc-bench-l.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +DbCreate -l +ret=$? +if [ $ret -ne 0 ] +then + echo "DbCreate failed" + exit $ret +fi + +DbAsyncGenerator -time 300 $* +ret=$? +exit $ret + diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/script/async-lmc-bench-p10.sh b/ndb/test/ndbapi/old_dirs/lmc-bench/script/async-lmc-bench-p10.sh new file mode 100755 index 00000000000..92c853cdd86 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/script/async-lmc-bench-p10.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +DbCreate +ret=$? +if [ $ret -ne 0 ] +then + echo "DbCreate failed" + exit $ret +fi + +DbAsyncGenerator -time 300 -p 10 $* +ret=$? +exit $ret + diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/script/async-lmc-bench.sh b/ndb/test/ndbapi/old_dirs/lmc-bench/script/async-lmc-bench.sh new file mode 100755 index 00000000000..da8e9d9bf42 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/script/async-lmc-bench.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +DbCreate +ret=$? +if [ $ret -ne 0 ] +then + echo "DbCreate failed" + exit $ret +fi + +DbAsyncGenerator -time 300 $* +ret=$? +exit $ret + diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/src/Makefile b/ndb/test/ndbapi/old_dirs/lmc-bench/src/Makefile new file mode 100644 index 00000000000..ae7fac9c49b --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/src/Makefile @@ -0,0 +1,8 @@ +include .defs.mk + +DIRS = \ + user \ + populator \ + +include $(NDB_TOP)/Epilogue.mk + diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/src/README b/ndb/test/ndbapi/old_dirs/lmc-bench/src/README new file mode 100644 index 00000000000..e81c8ba0051 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/src/README @@ -0,0 +1,8 @@ + +Note that you have to use gnumake to build + +On ndbs05: +use 'gmake' instead of 'make' + +On hfXXX: +do 'module add make' diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/Makefile b/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/Makefile new file mode 100644 index 00000000000..143d9ba655e --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/Makefile @@ -0,0 +1,17 @@ +include .defs.mk + +TYPE := ndbapitest + +SOURCES = mainGenerator.c dbGenerator.c + +CCFLAGS_LOC := -I../include -I../../include + +OBJECTS = \ + mainGenerator.o\ + dbGenerator.o + +BIN_TARGET := DbGenerator +BIN_TARGET_ARCHIVES := lmc_User + +include $(NDB_TOP)/Epilogue.mk + diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/dbGenerator.c b/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/dbGenerator.c new file mode 100644 index 00000000000..7484c7647f5 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/dbGenerator.c @@ -0,0 +1,543 @@ +/* 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 */ + +/*************************************************************** +* I N C L U D E D F I L E S * +***************************************************************/ + +#include +#include "dbGenerator.h" + +/*************************************************************** +* L O C A L C O N S T A N T S * +***************************************************************/ + +/*************************************************************** +* L O C A L D A T A S T R U C T U R E S * +***************************************************************/ + +/*************************************************************** +* L O C A L F U N C T I O N S * +***************************************************************/ + +static void getRandomSubscriberNumber(SubscriberNumber number); +static void getRandomServerId(ServerId *serverId); +static void getRandomChangedBy(ChangedBy changedBy); +static void getRandomChangedTime(ChangedTime changedTime); + +static void clearTransaction(TransactionDefinition *trans); +static void initGeneratorStatistics(GeneratorStatistics *gen); + +static void doOneTransaction(UserHandle *uh, GeneratorStatistics *gen); +static void doTransaction_T1(UserHandle *uh, GeneratorStatistics *gen); +static void doTransaction_T2(UserHandle *uh, GeneratorStatistics *gen); +static void doTransaction_T3(UserHandle *uh, GeneratorStatistics *gen); +static void doTransaction_T4(UserHandle *uh, GeneratorStatistics *gen); +static void doTransaction_T5(UserHandle *uh, GeneratorStatistics *gen); + +/*************************************************************** +* L O C A L D A T A * +***************************************************************/ + +static SequenceValues transactionDefinition[] = { + {25, 1}, + {25, 2}, + {20, 3}, + {15, 4}, + {15, 5}, + {0, 0} +}; + +static SequenceValues rollbackDefinition[] = { + {98, 0}, + {2 , 1}, + {0, 0} +}; + +static int maxsize = 0; + +/*************************************************************** +* P U B L I C D A T A * +***************************************************************/ + +/*************************************************************** +**************************************************************** +* L O C A L F U N C T I O N S C O D E S E C T I O N * +**************************************************************** +***************************************************************/ + +static void getRandomSubscriberNumber(SubscriberNumber number) +{ + uint32 tmp; + char sbuf[SUBSCRIBER_NUMBER_LENGTH + 1]; + tmp = myRandom48(NO_OF_SUBSCRIBERS); + sprintf(sbuf, "%.*d", SUBSCRIBER_NUMBER_LENGTH, tmp); + memcpy(number, sbuf, SUBSCRIBER_NUMBER_LENGTH); +} + +static void getRandomServerId(ServerId *serverId) +{ + *serverId = myRandom48(NO_OF_SERVERS); +} + +static void getRandomChangedBy(ChangedBy changedBy) +{ + memset(changedBy, myRandom48(26)+'A', CHANGED_BY_LENGTH); + changedBy[CHANGED_BY_LENGTH] = 0; +} + +static void getRandomChangedTime(ChangedTime changedTime) +{ + memset(changedTime, myRandom48(26)+'A', CHANGED_TIME_LENGTH); + changedTime[CHANGED_TIME_LENGTH] = 0; +} + +static void clearTransaction(TransactionDefinition *trans) +{ + trans->benchTime = 0.0; + trans->count = 0; + trans->branchExecuted = 0; + trans->rollbackExecuted = 0; +} + +static int listFull(SessionList *list) +{ + return(list->numberInList == SESSION_LIST_LENGTH); +} + +static int listEmpty(SessionList *list) +{ + return(list->numberInList == 0); +} + +static void insertSession(SessionList *list, + SubscriberNumber number, + ServerId serverId) +{ + SessionElement *e; + if( listFull(list) ) return; + + e = &list->list[list->writeIndex]; + + strcpy(e->subscriberNumber, number); + e->serverId = serverId; + + list->writeIndex = (list->writeIndex + 1) % SESSION_LIST_LENGTH; + list->numberInList++; + +if( list->numberInList > maxsize ) +maxsize = list->numberInList; +} + +static SessionElement *getNextSession(SessionList *list) +{ + if( listEmpty(list) ) return(0); + + return(&list->list[list->readIndex]); +} + +static void deleteSession(SessionList *list) +{ + if( listEmpty(list) ) return; + + list->readIndex = (list->readIndex + 1) % SESSION_LIST_LENGTH; + list->numberInList--; +} + +static void initGeneratorStatistics(GeneratorStatistics *gen) +{ + int i; + + if( initSequence(&gen->transactionSequence, + transactionDefinition) != 0 ) { + printf("could not set the transaction types\n"); + exit(0); + } + + if( initSequence(&gen->rollbackSequenceT4, + rollbackDefinition) != 0 ) { + printf("could not set the rollback sequence\n"); + exit(0); + } + + if( initSequence(&gen->rollbackSequenceT5, + rollbackDefinition) != 0 ) { + printf("could not set the rollback sequence\n"); + exit(0); + } + + for(i = 0; i < NUM_TRANSACTION_TYPES; i++ ) + clearTransaction(&gen->transactions[i]); + + gen->totalTransactions = 0; + + gen->activeSessions.numberInList = 0; + gen->activeSessions.readIndex = 0; + gen->activeSessions.writeIndex = 0; +} + + +static void doOneTransaction(UserHandle *uh, GeneratorStatistics *gen) +{ + unsigned int transactionType; + + transactionType = getNextRandom(&gen->transactionSequence); + + switch(transactionType) { + case 1: + doTransaction_T1(uh, gen); + break; + case 2: + doTransaction_T2(uh, gen); + break; + case 3: + doTransaction_T3(uh, gen); + break; + case 4: + doTransaction_T4(uh, gen); + break; + case 5: + doTransaction_T5(uh, gen); + break; + default: + printf("Unknown transaction type: %d\n", transactionType); + } + + gen->totalTransactions++; +} + +static void doTransaction_T1(UserHandle *uh, GeneratorStatistics *gen) +{ + SubscriberNumber number; + Location new_location; + ChangedBy changed_by; + ChangedTime changed_time; + + double start_time; + double end_time; + double transaction_time; + + unsigned int tid = 0; + + /*----------------*/ + /* Init arguments */ + /*----------------*/ + getRandomSubscriberNumber(number); + getRandomChangedBy(changed_by); + getRandomChangedTime(changed_time); + new_location = changed_by[0]; + + /*-----------------*/ + /* Run transaction */ + /*-----------------*/ + start_time = userGetTimeSync(); + userTransaction_T1(uh, + number, + new_location, + changed_by, + changed_time); + end_time = userGetTimeSync(); + + /*-------------------*/ + /* Update Statistics */ + /*-------------------*/ + transaction_time = end_time - start_time; + gen->transactions[tid].benchTime += transaction_time; + gen->transactions[tid].count++; +} + +static void doTransaction_T2(UserHandle *uh, GeneratorStatistics *gen) +{ + SubscriberNumber number; + Location new_location; + ChangedBy changed_by; + ChangedTime changed_time; + SubscriberName subscriberName; + + double start_time; + double end_time; + double transaction_time; + + unsigned int tid = 1; + + /*----------------*/ + /* Init arguments */ + /*----------------*/ + getRandomSubscriberNumber(number); + + /*-----------------*/ + /* Run transaction */ + /*-----------------*/ + start_time = userGetTimeSync(); + userTransaction_T2(uh, + number, + &new_location, + changed_by, + changed_time, + subscriberName); + end_time = userGetTimeSync(); + + /*-------------------*/ + /* Update Statistics */ + /*-------------------*/ + transaction_time = end_time - start_time; + gen->transactions[tid].benchTime += transaction_time; + gen->transactions[tid].count++; +} + +static void doTransaction_T3(UserHandle *uh, GeneratorStatistics *gen) +{ + SubscriberNumber number; + ServerId serverId; + ServerBit serverBit; + SessionDetails sessionDetails; + unsigned int branchExecuted; + SessionElement *se; + + double start_time; + double end_time; + double transaction_time; + + unsigned int tid = 2; + + /*----------------*/ + /* Init arguments */ + /*----------------*/ + se = getNextSession(&gen->activeSessions); + if( se ) { + strcpy(number, se->subscriberNumber); + serverId = se->serverId; + } + else { + getRandomSubscriberNumber(number); + getRandomServerId(&serverId); + } + + serverBit = 1 << serverId; + + /*-----------------*/ + /* Run transaction */ + /*-----------------*/ + start_time = userGetTimeSync(); + userTransaction_T3(uh, + number, + serverId, + serverBit, + sessionDetails, + &branchExecuted); + end_time = userGetTimeSync(); + + /*-------------------*/ + /* Update Statistics */ + /*-------------------*/ + transaction_time = end_time - start_time; + gen->transactions[tid].benchTime += transaction_time; + gen->transactions[tid].count++; + + if(branchExecuted) + gen->transactions[tid].branchExecuted++; +} + +static void doTransaction_T4(UserHandle *uh, GeneratorStatistics *gen) +{ + SubscriberNumber number; + ServerId serverId; + ServerBit serverBit; + SessionDetails sessionDetails; + unsigned int branchExecuted; + unsigned int rollback; + + double start_time; + double end_time; + double transaction_time; + + unsigned int tid = 3; + + /*----------------*/ + /* Init arguments */ + /*----------------*/ + getRandomSubscriberNumber(number); + getRandomServerId(&serverId); + + serverBit = 1 << serverId; + rollback = getNextRandom(&gen->rollbackSequenceT4); + + memset(sessionDetails, myRandom48(26)+'A', SESSION_DETAILS_LENGTH); + sessionDetails[SESSION_DETAILS_LENGTH] = 0; + + /*-----------------*/ + /* Run transaction */ + /*-----------------*/ + start_time = userGetTimeSync(); + userTransaction_T4(uh, + number, + serverId, + serverBit, + sessionDetails, + rollback, + &branchExecuted); + end_time = userGetTimeSync(); + + /*-------------------*/ + /* Update Statistics */ + /*-------------------*/ + transaction_time = end_time - start_time; + gen->transactions[tid].benchTime += transaction_time; + gen->transactions[tid].count++; + + if(branchExecuted) + gen->transactions[tid].branchExecuted++; + if(rollback) + gen->transactions[tid].rollbackExecuted++; + + if( branchExecuted && !rollback ) { + insertSession(&gen->activeSessions, number, serverId); + } +} + +static void doTransaction_T5(UserHandle *uh, GeneratorStatistics *gen) +{ + SubscriberNumber number; + ServerId serverId; + ServerBit serverBit; + unsigned int branchExecuted; + unsigned int rollback; + SessionElement *se; + + double start_time; + double end_time; + double transaction_time; + + unsigned int tid = 4; + + /*----------------*/ + /* Init arguments */ + /*----------------*/ + se = getNextSession(&gen->activeSessions); + if( se ) { + strcpy(number, se->subscriberNumber); + serverId = se->serverId; + } + else { + getRandomSubscriberNumber(number); + getRandomServerId(&serverId); + } + + serverBit = 1 << serverId; + rollback = getNextRandom(&gen->rollbackSequenceT5); + + /*-----------------*/ + /* Run transaction */ + /*-----------------*/ + start_time = userGetTimeSync(); + userTransaction_T5(uh, + number, + serverId, + serverBit, + rollback, + &branchExecuted); + end_time = userGetTimeSync(); + + /*-------------------*/ + /* Update Statistics */ + /*-------------------*/ + transaction_time = end_time - start_time; + gen->transactions[tid].benchTime += transaction_time; + gen->transactions[tid].count++; + + if(branchExecuted) + gen->transactions[tid].branchExecuted++; + if(rollback) + gen->transactions[tid].rollbackExecuted++; + + if( se && !rollback) { + deleteSession(&gen->activeSessions); + } +} + +/*************************************************************** +**************************************************************** +* P U B L I C F U N C T I O N S C O D E S E C T I O N * +**************************************************************** +***************************************************************/ + + +void dbGenerator(UserHandle *uh, ThreadData *data) +{ + GeneratorStatistics rg_warmUp; + GeneratorStatistics rg_coolDown; + GeneratorStatistics *st; + double periodStop; + double benchTimeStart; + double benchTimeEnd; + int i; + + myRandom48Init(data->randomSeed); + + initGeneratorStatistics(&rg_warmUp); + initGeneratorStatistics(&data->generator); + initGeneratorStatistics(&rg_coolDown); + + /*----------------*/ + /* warm up period */ + /*----------------*/ + periodStop = userGetTimeSync() + (double)data->warmUpSeconds; + while(userGetTimeSync() < periodStop){ + doOneTransaction(uh, &rg_warmUp); + } + + /*-------------------------*/ + /* normal benchmark period */ + /*-------------------------*/ + benchTimeStart = userGetTimeSync(); + + if( data->numTransactions > 0 ) { + for(i = 0; i < data->numTransactions; i++) + doOneTransaction(uh, &data->generator); + } + else { + periodStop = benchTimeStart + (double)data->testSeconds; + while(userGetTimeSync() < periodStop) + doOneTransaction(uh, &data->generator); + } + + benchTimeEnd = userGetTimeSync(); + + /*------------------*/ + /* cool down period */ + /*------------------*/ + periodStop = benchTimeEnd + data->coolDownSeconds; + while(userGetTimeSync() < periodStop){ + doOneTransaction(uh, &rg_coolDown); + } + + /*---------------------------------------------------------*/ + /* add the times for all transaction for inner loop timing */ + /*---------------------------------------------------------*/ + st = &data->generator; + st->innerLoopTime = 0.0; + for(i = 0 ; i < NUM_TRANSACTION_TYPES; i++) { + st->innerLoopTime += st->transactions[i].benchTime; + st->transactions[i].tps = getTps(st->transactions[i].count, + st->transactions[i].benchTime); + } + + st->outerLoopTime = benchTimeEnd - benchTimeStart; + st->outerTps = getTps(st->totalTransactions, st->outerLoopTime); + st->innerTps = getTps(st->totalTransactions, st->innerLoopTime); + + /* printf("maxsize = %d\n",maxsize); */ +} diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/dbGenerator.h b/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/dbGenerator.h new file mode 100644 index 00000000000..824688b6cf9 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/dbGenerator.h @@ -0,0 +1,61 @@ +/* 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 */ + +#ifndef DBGENERATOR_H +#define DBGENERATOR_H + +/*************************************************************** +* I N C L U D E D F I L E S * +***************************************************************/ + +#include "testData.h" +#include "userInterface.h" + +/*************************************************************** +* M A C R O S * +***************************************************************/ + +/***************************************************************/ +/* C O N S T A N T S */ +/***************************************************************/ + +/*************************************************************** +* D A T A S T R U C T U R E S * +***************************************************************/ + +/*************************************************************** +* P U B L I C F U N C T I O N S * +***************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +extern void dbGenerator(UserHandle *uh, ThreadData *data); + + +#ifdef __cplusplus +} +#endif + +/*************************************************************** +* E X T E R N A L D A T A * +***************************************************************/ + + + +#endif /* DBGENERATOR_H */ + diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/mainGenerator.c b/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/mainGenerator.c new file mode 100644 index 00000000000..4a31db0b4e9 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/src/generator/mainGenerator.c @@ -0,0 +1,323 @@ +/* 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 */ + +#include + +#include +#include +#include +#include + +#include "userInterface.h" +#include "dbGenerator.h" + + +static int numProcesses; +static int numTransactions; +static int numSeconds; +static int numWarmSeconds; +static char *testDbName; + +static ThreadData data[100]; + +typedef struct { + pthread_t threadId; + int waitSeconds; + int toExit; +}CheckpointData; + +static void usage(char *prog) +{ + char *progname; + + /*--------------------------------------------*/ + /* Get the name of the program (without path) */ + /*--------------------------------------------*/ + progname = strrchr(prog, '/'); + + if (progname == 0) + progname = prog; + else + ++progname; + + fprintf(stderr, + "Usage: %s [-db ] [-proc ] [-transactions ] [-time ]\n" + " -db Specifies the database name\n" + " default = '%s'\n" + " -proc Specifies that is the number of\n" + " concurrent processes. The default is 1.\n" + " -transactions Specifies that transactions will be\n" + " performed. The default is to do a specific time interval\n" + " -time Specifies that the test will run for sec.\n" + " The default is 10 sec\n" + " -warm Specifies the warm-up/cooldown period of sec.\n" + " The default is 10 sec\n", + progname, DEFAULTDB); + exit(1); +} + +static void parse_args(int argc,char **argv) +{ + int i; + + testDbName = DEFAULTDB; + numProcesses = 1; + numTransactions = 0; + numSeconds = 10; + numWarmSeconds = 10; + + i = 1; + while (i < argc){ + if (strcmp("-db",argv[i]) == 0) { + if (i + 1 >= argc) { + usage(argv[0]); + exit(1); + } + testDbName = argv[i + 1]; + i += 2; + } + else if (strcmp("-proc",argv[i]) == 0) { + if (i + 1 >= argc) { + usage(argv[0]); + exit(1); + } + if (sscanf(argv[i+1], "%d", &numProcesses) == -1 || + numProcesses <= 0 || numProcesses > 99) { + fprintf(stderr, "-proc flag requires a positive integer argument [1..99]\n"); + usage(argv[0]); + exit(1); + } + i += 2; + } + else if (strcmp("-transactions",argv[i]) == 0) { + if (i + 1 >= argc) { + usage(argv[0]); + exit(1); + } + if (sscanf(argv[i+1], "%d", &numTransactions) == -1 || + numTransactions < 0) { + fprintf(stderr, "-transactions flag requires a positive integer argument\n"); + usage(argv[0]); + exit(1); + } + i += 2; + } + else if (strcmp("-time",argv[i]) == 0) { + if (i + 1 >= argc) { + usage(argv[0]); + exit(1); + } + if (sscanf(argv[i+1], "%d", &numSeconds) == -1 || + numSeconds < 0) { + fprintf(stderr, "-time flag requires a positive integer argument\n"); + usage(argv[0]); + exit(1); + } + i += 2; + } + else if (strcmp("-warm",argv[i]) == 0) { + if (i + 1 >= argc) { + usage(argv[0]); + exit(1); + } + if (sscanf(argv[i+1], "%d", &numWarmSeconds) == -1 || + numWarmSeconds < 0) { + fprintf(stderr, "-warm flag requires a positive integer argument\n"); + usage(argv[0]); + exit(1); + } + i += 2; + } + else + usage(argv[0]); + } +} + +static void print_transaction(const char *header, + unsigned long totalCount, + TransactionDefinition *trans, + unsigned int printBranch, + unsigned int printRollback) +{ + double f; + + printf(" %s: %d (%.2f%%) Time: %.4f sec TPS = %.0f\n", + header, + trans->count, + (double)trans->count / (double)totalCount * 100.0, + trans->benchTime, + trans->tps); + + if( printBranch ){ + if( trans->count == 0 ) + f = 0.0; + else + f = (double)trans->branchExecuted / (double)trans->count * 100.0; + printf(" Branches Executed: %d (%.2f%%)\n", trans->branchExecuted, f); + } + + if( printRollback ){ + if( trans->count == 0 ) + f = 0.0; + else + f = (double)trans->rollbackExecuted / (double)trans->count * 100.0; + printf(" Rollback Executed: %d (%.2f%%)\n", trans->rollbackExecuted, f); + } +} + +void print_stats_sync(const char *title, + unsigned int length, + unsigned int transactionFlag, + GeneratorStatistics *gen, + int numProc) +{ + int i; + char buf[10]; + char name[100]; + + name[0] = 0; + NdbHost_GetHostName(name); + + printf("\n------ %s ------\n",title); + printf("Length : %d %s\n", + length, + transactionFlag ? "Transactions" : "sec"); + printf("Processor : %s\n", name); + printf("Number of Proc: %d\n",numProc); + printf("\n"); + + if( gen->totalTransactions == 0 ) { + printf(" No Transactions for this test\n"); + } + else { + for(i = 0; i < 5; i++) { + sprintf(buf, "T%d",i+1); + print_transaction(buf, + gen->totalTransactions, + &gen->transactions[i], + i >= 2, + i >= 3 ); + } + + printf("\n"); + printf(" Overall Statistics:\n"); + printf(" Transactions: %d\n", gen->totalTransactions); + printf(" Inner : %.0f TPS\n",gen->innerTps); + printf(" Outer : %.0f TPS\n",gen->outerTps); + printf("\n"); + } +} + +static void *threadRoutine(void *arg) +{ + UserHandle *uh; + ThreadData *data = (ThreadData *)arg; + + uh = userDbConnect(0, testDbName); + NdbSleep_MilliSleep(data->threadId); + dbGenerator(uh,data); + userDbDisconnect(uh); + + pthread_exit(0); + return(0); +} + +NDB_COMMAND(DbGenerator, "DbGenerator", "DbGenerator", "DbGenerator", 16384) +{ + int i; + int j; + GeneratorStatistics stats; + GeneratorStatistics *p; + CheckpointData cd; + + parse_args(argc,argv); + + printf("\nStarting Test with %d process(es) for %d %s\n", + numProcesses, + numTransactions ? numTransactions : numSeconds, + numTransactions ? "Transactions" : "sec"); + printf(" WarmUp/coolDown = %d sec\n", numWarmSeconds); + + /* + cd.waitSeconds = 300; + cd.toExit = 0; + pthread_create(&cd.threadId, 0, checkpointRoutine, &cd); + */ + + for(i = 0; i < numProcesses; i++) { + data[i].warmUpSeconds = numWarmSeconds; + data[i].testSeconds = numSeconds; + data[i].coolDownSeconds = numWarmSeconds; + data[i].numTransactions = numTransactions; + data[i].randomSeed = time(0)+i; + j = pthread_create(&data[i].threadId, 0, threadRoutine, &data[i]); + if(j != 0){ + perror("Failed to create thread"); + } + } + + /*--------------------------------*/ + /* Wait for all processes to exit */ + /*--------------------------------*/ + for(i = 0; i < numProcesses; i++) + pthread_join(data[i].threadId, 0); + + printf("All threads have finished\n"); + + cd.toExit = 1; + + /*-------------------------------------------*/ + /* Clear all structures for total statistics */ + /*-------------------------------------------*/ + stats.totalTransactions = 0; + stats.outerTps = 0.0; + stats.innerTps = 0.0; + + for(i = 0; i < NUM_TRANSACTION_TYPES; i++ ) { + stats.transactions[i].benchTime = 0.0; + stats.transactions[i].count = 0; + stats.transactions[i].tps = 0.0; + stats.transactions[i].branchExecuted = 0; + stats.transactions[i].rollbackExecuted = 0; + } + + /*--------------------------------*/ + /* Add the values for all Threads */ + /*--------------------------------*/ + for(i = 0; i < numProcesses; i++) { + p = &data[i].generator; + + stats.totalTransactions += p->totalTransactions; + stats.outerTps += p->outerTps; + stats.innerTps += p->innerTps; + + for(j = 0; j < NUM_TRANSACTION_TYPES; j++ ) { + stats.transactions[j].benchTime += p->transactions[j].benchTime; + stats.transactions[j].count += p->transactions[j].count; + stats.transactions[j].tps += p->transactions[j].tps; + stats.transactions[j].branchExecuted += p->transactions[j].branchExecuted; + stats.transactions[j].rollbackExecuted += p->transactions[j].rollbackExecuted; + } + } + + print_stats_sync("Test Results", + numTransactions ? numTransactions : numSeconds, + numTransactions ? 1 : 0, + &stats, + numProcesses); + + return(0); +} diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/src/include/testData.h b/ndb/test/ndbapi/old_dirs/lmc-bench/src/include/testData.h new file mode 100644 index 00000000000..863c230502b --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/src/include/testData.h @@ -0,0 +1,103 @@ +/* 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 */ + +#ifndef TESTDATA_H +#define TESTDATA_H + +/*************************************************************** +* I N C L U D E D F I L E S * +***************************************************************/ + +#include "testDefinitions.h" +#include + +/*************************************************************** +* M A C R O S * +***************************************************************/ + +/***************************************************************/ +/* C O N S T A N T S */ +/***************************************************************/ + +#define NUM_TRANSACTION_TYPES 5 +#define SESSION_LIST_LENGTH 1000 + +/*************************************************************** +* D A T A S T R U C T U R E S * +***************************************************************/ + +typedef struct { + SubscriberNumber subscriberNumber; + ServerId serverId; +} SessionElement; + +typedef struct { + SessionElement list[SESSION_LIST_LENGTH]; + unsigned int readIndex; + unsigned int writeIndex; + unsigned int numberInList; +} SessionList; + +typedef struct { + double benchTime; + unsigned int count; + double tps; + unsigned int branchExecuted; + unsigned int rollbackExecuted; +}TransactionDefinition; + +typedef struct { + RandomSequence transactionSequence; + RandomSequence rollbackSequenceT4; + RandomSequence rollbackSequenceT5; + + TransactionDefinition transactions[NUM_TRANSACTION_TYPES]; + + unsigned int totalTransactions; + + double innerLoopTime; + double innerTps; + + double outerLoopTime; + double outerTps; + + SessionList activeSessions; +} GeneratorStatistics; + +typedef struct { + unsigned long threadId; + unsigned long randomSeed; + + unsigned int warmUpSeconds; + unsigned int testSeconds; + unsigned int coolDownSeconds; + unsigned int numTransactions; + + GeneratorStatistics generator; +}ThreadData; + +/*************************************************************** +* P U B L I C F U N C T I O N S * +***************************************************************/ + +/*************************************************************** +* E X T E R N A L D A T A * +***************************************************************/ + + + +#endif /* TESTDATA_H */ + diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/src/include/userInterface.h b/ndb/test/ndbapi/old_dirs/lmc-bench/src/include/userInterface.h new file mode 100644 index 00000000000..b70ded87756 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/src/include/userInterface.h @@ -0,0 +1,128 @@ +/* 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 */ + +#ifndef DBINTERFACE_H +#define DBINTERFACE_H + +/***************************************************************/ +/* I N C L U D E D F I L E S */ +/***************************************************************/ + +#include "testDefinitions.h" + +/*************************************************************** +* M A C R O S * +***************************************************************/ + +/***************************************************************/ +/* C O N S T A N T S */ +/***************************************************************/ + +/*-----------------------*/ +/* Default Database Name */ +/*-----------------------*/ +#define DEFAULTDB "TestDbClient" + +/*************************************************************** +* D A T A S T R U C T U R E S * +***************************************************************/ + +typedef struct { + struct Ndb * pNDB; + struct NdbConnection * pCurrTrans; +} UserHandle; + +/*************************************************************** +* P U B L I C F U N C T I O N S * +***************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +extern double userGetTimeSync(void); + +extern void userCheckpoint(UserHandle *uh); + +extern UserHandle *userDbConnect(uint32 createDb, char *dbName); +extern void userDbDisconnect(UserHandle *uh); + +extern int userDbInsertServer(UserHandle *uh, + ServerId serverId, + SubscriberSuffix suffix, + ServerName name); + +extern int userDbInsertSubscriber(UserHandle *uh, + SubscriberNumber number, + uint32 groupId, + SubscriberName name); + +extern int userDbInsertGroup(UserHandle *uh, + GroupId groupId, + GroupName name, + Permission allowRead, + Permission allowInsert, + Permission allowDelete); + +extern int userDbCommit(UserHandle *uh); +extern int userDbRollback(UserHandle *uh); + +extern void userTransaction_T1(UserHandle *uh, + SubscriberNumber number, + Location new_location, + ChangedBy changed_by, + ChangedTime changed_time); + +extern void userTransaction_T2(UserHandle *uh, + SubscriberNumber number, + Location *new_location, + ChangedBy changed_by, + ChangedTime changed_time, + SubscriberName subscriberName); + +extern void userTransaction_T3(UserHandle *uh, + SubscriberNumber number, + ServerId server_id, + ServerBit server_bit, + SessionDetails session_details, + unsigned int *branch_executed); + +extern void userTransaction_T4(UserHandle *uh, + SubscriberNumber number, + ServerId server_id, + ServerBit server_bit, + SessionDetails session_details, + unsigned int do_rollback, + unsigned int *branch_executed); + +extern void userTransaction_T5(UserHandle *uh, + SubscriberNumber number, + ServerId server_id, + ServerBit server_bit, + unsigned int do_rollback, + unsigned int *branch_executed); + + +#ifdef __cplusplus +} +#endif + +/*************************************************************** +* E X T E R N A L D A T A * +***************************************************************/ + +#endif /* DBINTERFACE_H */ + diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/src/makevars.linux b/ndb/test/ndbapi/old_dirs/lmc-bench/src/makevars.linux new file mode 100644 index 00000000000..a933669cfe7 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/src/makevars.linux @@ -0,0 +1,6 @@ +PROJECT_TOP = /home/lmcritr/ecurlmc/users/lmcritr/dbBenchmark + +CFLAGS = -Wall -Wstrict-prototypes -O2 -I/opt/TimesTen4.1/32/include/ -I../include +LDFLAGS = -L/opt/TimesTen4.1/32/lib -Wl,-rpath,/opt/TimesTen4.1/32/lib +LIBS = -ltten -ldl +LIBSCS = -lttclient -ldl diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/src/makevars.sparc b/ndb/test/ndbapi/old_dirs/lmc-bench/src/makevars.sparc new file mode 100644 index 00000000000..57ab8bf982f --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/src/makevars.sparc @@ -0,0 +1,15 @@ + +include $(UAS_TOP)/Defs.mk + +LINK.CC = CC +CC := /opt/as/forte6/SUNWspro/bin/cc +export CC + +NDB_LIB = -L$(UAS_TOP)/API -lNDB_API \ + -L$(UAS_OSPACE_LOC)/lib -lospace \ + -lrt + +CFLAGS = -xO3 -I../include -mt +LDFLAGS = $(NDB_LIB) -lpthread +LIBS = +LIBSCS = diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/src/populator/Makefile b/ndb/test/ndbapi/old_dirs/lmc-bench/src/populator/Makefile new file mode 100644 index 00000000000..2107c948843 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/src/populator/Makefile @@ -0,0 +1,15 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := DbCreate +BIN_TARGET_ARCHIVES := lmc_User + +CCFLAGS_LOC:= -I../include -I../../include + +SOURCES := \ + mainPopulate.c\ + dbPopulate.c + +include $(NDB_TOP)/Epilogue.mk + diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/src/populator/dbPopulate.c b/ndb/test/ndbapi/old_dirs/lmc-bench/src/populator/dbPopulate.c new file mode 100644 index 00000000000..42fbb52f3b2 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/src/populator/dbPopulate.c @@ -0,0 +1,244 @@ +/* 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 */ + +/*************************************************************** +* I N C L U D E D F I L E S * +***************************************************************/ + +#include + +#include "userInterface.h" + +#include "dbPopulate.h" +#include +#include + +/*************************************************************** +* L O C A L C O N S T A N T S * +***************************************************************/ + +/*************************************************************** +* L O C A L D A T A S T R U C T U R E S * +***************************************************************/ + +/*************************************************************** +* L O C A L F U N C T I O N S * +***************************************************************/ + +static void getRandomSubscriberData(int subscriberNo, + SubscriberNumber number, + SubscriberName name); + +static void populate(char *title, + int count, + void (*func)(UserHandle*,int), + UserHandle *uh); + +static void populateServers(UserHandle *uh, int count); +static void populateSubscribers(UserHandle *uh, int count); +static void populateGroups(UserHandle *uh, int count); + +/*************************************************************** +* L O C A L D A T A * +***************************************************************/ + +static SequenceValues permissionsDefinition[] = { + {90, 1}, + {10, 0}, + {0, 0} +}; + +/*************************************************************** +* P U B L I C D A T A * +***************************************************************/ + + +/*************************************************************** +**************************************************************** +* L O C A L F U N C T I O N S C O D E S E C T I O N * +**************************************************************** +***************************************************************/ + +static void getRandomSubscriberData(int subscriberNo, + SubscriberNumber number, + SubscriberName name) +{ + char sbuf[SUBSCRIBER_NUMBER_LENGTH + 1]; + sprintf(sbuf, "%.*d", SUBSCRIBER_NUMBER_LENGTH, subscriberNo); + memcpy(number, sbuf, SUBSCRIBER_NUMBER_LENGTH); + + memset(name, myRandom48(26)+'A', SUBSCRIBER_NAME_LENGTH); +} + +static void populate(char *title, + int count, + void (*func)(UserHandle*, int), + UserHandle *uh) +{ + ndbout_c("Populating %d '%s' ... ",count, title); + /* fflush(stdout); */ + func(uh,count); + ndbout_c("done"); +} + +static void populateServers(UserHandle *uh, int count) +{ + int i, j; + int len; + char tmp[80]; + int suffix_length = 1; + ServerName serverName; + SubscriberSuffix suffix; + + int commitCount = 0; + + for(i = 0; i < SUBSCRIBER_NUMBER_SUFFIX_LENGTH; i++) + suffix_length *= 10; + + for(i = 0; i < count; i++) { + sprintf(tmp, "-Server %d-", i); + + len = strlen(tmp); + for(j = 0; j < SERVER_NAME_LENGTH; j++){ + serverName[j] = tmp[j % len]; + } + /* serverName[j] = 0; not null-terminated */ + + for(j = 0; j < suffix_length; j++){ + char sbuf[SUBSCRIBER_NUMBER_SUFFIX_LENGTH + 1]; + sprintf(sbuf, "%.*d", SUBSCRIBER_NUMBER_SUFFIX_LENGTH, j); + memcpy(suffix, sbuf, SUBSCRIBER_NUMBER_SUFFIX_LENGTH); + userDbInsertServer(uh, i, suffix, serverName); + commitCount ++; + if((commitCount % OP_PER_TRANS) == 0) + userDbCommit(uh); + } + } + if((commitCount % OP_PER_TRANS) != 0) + userDbCommit(uh); +} + +static void populateSubscribers(UserHandle *uh, int count) +{ + SubscriberNumber number; + SubscriberName name; + int i, j, k; + int res; + + SequenceValues values[NO_OF_GROUPS+1]; + RandomSequence seq; + + for(i = 0; i < NO_OF_GROUPS; i++) { + values[i].length = 1; + values[i].value = i; + } + + values[i].length = 0; + values[i].value = 0; + + if( initSequence(&seq, values) != 0 ) { + ndbout_c("could not set the sequence of random groups"); + exit(0); + } + +#define RETRIES 25 + + for(i = 0; i < count; i+= OP_PER_TRANS) { + for(j = 0; j + +#include "userInterface.h" +#include "dbPopulate.h" +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +int useTableLogging; +int useIndexTables; +#ifdef __cplusplus +} +#endif + + +static +void usage(const char *prog) +{ + + ndbout_c( + "Usage: %s [-l]\n" + " -l Use logging and checkpointing on tables\n", + " -i Use index tables\n", + prog); + + exit(1); +} + +NDB_COMMAND(DbCreate, "DbCreate", "DbCreate", "DbCreate", 16384) +{ + int i; + UserHandle *uh; + + useTableLogging = useIndexTables = 0; + + for(i = 1; i + +#include "userInterface.h" +#include "userHandle.h" + +/*************************************************************** +* L O C A L C O N S T A N T S * +***************************************************************/ + +/*************************************************************** +* L O C A L D A T A S T R U C T U R E S * +***************************************************************/ + +/*************************************************************** +* L O C A L F U N C T I O N S * +***************************************************************/ + + +/*************************************************************** +* L O C A L D A T A * +***************************************************************/ + +/*----------------*/ +/* Transaction T1 */ +/*----------------*/ +static char *update_subscriber_stmnt = "update subscriber set \ +location = ?,changedBy = ?, changedTime = ? where subscriberNumber = ?"; + +/*----------------*/ +/* Transaction T2 */ +/*----------------*/ +static char *read_subscriber_stmnt = "select subscriberName,location,\ +changedBy,changedTime from subscriber where subscriberNumber = ? for update"; + +/*----------------*/ +/* Transaction T3 */ +/*----------------*/ +static char *read_subscriber_session_stmnt = "select activeSessions,groupId,\ +changedBy,changedTime from subscriber where subscriberNumber = ? for update"; + +static char *read_group_allowRead_stmnt = "select allowRead from userGroup \ +where groupId = ?"; +static char *read_group_allowInsert_stmnt = "select allowInsert from userGroup \ +where groupId = ?"; +static char *read_group_allowDelete_stmnt = "select allowDelete from userGroup \ +where groupId = ?"; + +static char *read_session_details_stmnt = "select sessionData from userSession \ +where subscriberNumber = ? and serverId = ? for update"; + +static char *update_noOfRead_stmnt = "update server \ +set noOfRead = noOfRead + 1 where serverId = ? and subscriberSuffix = ?"; +static char *update_noOfInsert_stmnt = "update server \ +set noOfInsert = noOfInsert + 1 where serverId = ? and subscriberSuffix = ?"; +static char *update_noOfDelete_stmnt = "update server \ +set noOfDelete = noOfDelete + 1 where serverId = ? and subscriberSuffix = ?"; + +static char *insert_session_stmnt = "insert into userSession values (?,?,?)"; + +static char *delete_session_stmnt = "delete from userSession \ +where subscriberNumber = ? and serverId = ?"; + +static char *update_subscriber_session_stmnt = "update subscriber set \ +activeSessions = ? where subscriberNumber = ?"; + +/*************************************************************** +* P U B L I C D A T A * +***************************************************************/ + + +/*************************************************************** +**************************************************************** +* L O C A L F U N C T I O N S C O D E S E C T I O N * +**************************************************************** +***************************************************************/ + +extern void handle_error(SQLHDBC hdbc, + SQLHENV henv, + SQLHSTMT hstmt, + SQLRETURN rc, + char *filename, + int lineno); + +/*************************************************************** +**************************************************************** +* P U B L I C F U N C T I O N S C O D E S E C T I O N * +**************************************************************** +***************************************************************/ + +int localDbPrepare(UserHandle *uh) +{ + SQLRETURN rc; + + if(!uh) return(-1); + + /*-----------------------------*/ + /* Update Subscriber Statement */ + /*-----------------------------*/ + rc = SQLAllocStmt(uh->hdbc, &uh->updateSubscriber.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to allocate insert group statement\n"); + return(-1); + } + + rc = SQLPrepare(uh->updateSubscriber.stmt,(SQLCHAR *) update_subscriber_stmnt, SQL_NTS); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { +/* +handle_error(uh->hdbc, uh->henv, uh->updateSubscriber.stmt, rc, __FILE__, __LINE__); +*/ + printf("Unable to prepare update subscriber statement\n"); + return(-1); + } + + rc = SQLBindParameter(uh->updateSubscriber.stmt, + 1,SQL_PARAM_INPUT,SQL_C_DEFAULT,SQL_INTEGER, + 0,0, + &uh->updateSubscriber.values.location,0,NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare update subscriber statement param 1\n"); + return(-1); + } + + rc = SQLBindParameter(uh->updateSubscriber.stmt, + 2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, + CHANGED_BY_LENGTH+1,0, + uh->updateSubscriber.values.changedBy,0,NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare update subscriber statement param 2\n"); + return(-1); + } + + rc = SQLBindParameter(uh->updateSubscriber.stmt, + 3,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, + CHANGED_TIME_LENGTH+1,0, + uh->updateSubscriber.values.changedTime,0,NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare update subscriber statement param 3\n"); + return(-1); + } + + rc = SQLBindParameter(uh->updateSubscriber.stmt, + 4,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, + SUBSCRIBER_NUMBER_LENGTH+1,0, + uh->updateSubscriber.values.number,0,NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare update subscriber statement param 3\n"); + return(-1); + } + + /*---------------------------*/ + /* Read Subscriber Statement */ + /*---------------------------*/ + rc = SQLAllocStmt(uh->hdbc, &uh->readSubscriber.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to allocate read subscriber statement\n"); + return(-1); + } + + rc = SQLPrepare(uh->readSubscriber.stmt,(SQLCHAR *) read_subscriber_stmnt, SQL_NTS); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare read subscriber statement\n"); + return(-1); + } + + rc = SQLBindParameter(uh->readSubscriber.stmt, + 1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, + SUBSCRIBER_NUMBER_LENGTH+1,0, + uh->readSubscriber.values.number,0,NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare read subscriber statement param 1\n"); + return(-1); + } + + rc = SQLBindCol(uh->readSubscriber.stmt, 1, + SQL_C_CHAR, + uh->readSubscriber.values.name, SUBSCRIBER_NAME_LENGTH+1, + NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to bind column 1 to read subscriber statement\n"); + return(-1); + } + + rc = SQLBindCol(uh->readSubscriber.stmt, 2, + SQL_C_DEFAULT, + &uh->readSubscriber.values.location, 1, + NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to bind column 2 to read subscriber statement\n"); + return(-1); + } + + rc = SQLBindCol(uh->readSubscriber.stmt, 3, + SQL_C_CHAR, + uh->readSubscriber.values.changedBy, CHANGED_BY_LENGTH+1, + NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to bind column 3 to read subscriber statement\n"); + return(-1); + } + + rc = SQLBindCol(uh->readSubscriber.stmt, 4, + SQL_C_CHAR, + uh->readSubscriber.values.changedTime, CHANGED_TIME_LENGTH+1, + NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to bind column 4 to read subscriber statement\n"); + return(-1); + } + + /*------------------------------------*/ + /* Read Subscriber Sessions Statement */ + /*------------------------------------*/ + rc = SQLAllocStmt(uh->hdbc, &uh->readSubscriberSession.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to allocate read subscriber session statement\n"); + return(-1); + } + + rc = SQLPrepare(uh->readSubscriberSession.stmt,(SQLCHAR *) read_subscriber_session_stmnt, SQL_NTS); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare read subscriber sessions statement\n"); + return(-1); + } + + rc = SQLBindParameter(uh->readSubscriberSession.stmt, + 1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, + SUBSCRIBER_NUMBER_LENGTH+1,0, + uh->readSubscriberSession.values.number,0,NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare read subscriber statement param 1\n"); + return(-1); + } + + rc = SQLBindCol(uh->readSubscriberSession.stmt, 1, + SQL_C_DEFAULT, + &uh->readSubscriberSession.values.activeSessions, 0, + NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to bind column 1 to read subscriber sessions statement\n"); + return(-1); + } + + rc = SQLBindCol(uh->readSubscriberSession.stmt, 2, + SQL_C_DEFAULT, + &uh->readSubscriberSession.values.groupId, 0, + NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to bind column 2 to read subscriber sessions statement\n"); + return(-1); + } + + rc = SQLBindCol(uh->readSubscriberSession.stmt, 3, + SQL_C_CHAR, + uh->readSubscriberSession.values.changedBy, CHANGED_BY_LENGTH+1, + NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to bind column 3 to read subscriber sessions statement\n"); + return(-1); + } + + rc = SQLBindCol(uh->readSubscriberSession.stmt, 4, + SQL_C_CHAR, + uh->readSubscriberSession.values.changedTime, CHANGED_TIME_LENGTH+1, + NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to bind column 4 to read subscriber sessions statement\n"); + return(-1); + } + + /*--------------------------------*/ + /* Read Group AllowRead Statement */ + /*--------------------------------*/ + rc = SQLAllocStmt(uh->hdbc, &uh->readGroupAllowRead.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to allocate read subscriber session statement\n"); + return(-1); + } + + rc = SQLPrepare(uh->readGroupAllowRead.stmt,(SQLCHAR *) read_group_allowRead_stmnt, SQL_NTS); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare read group allow read statement\n"); + return(-1); + } + + rc = SQLBindParameter(uh->readGroupAllowRead.stmt, + 1,SQL_PARAM_INPUT,SQL_C_DEFAULT,SQL_INTEGER, + 0,0, + &uh->readGroupAllowRead.values.groupId,0,NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare read allow read statement param 1\n"); + return(-1); + } + + rc = SQLBindCol(uh->readGroupAllowRead.stmt, 1, + SQL_C_DEFAULT, + &uh->readGroupAllowRead.values.allowRead, 0, + NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to bind column 1 to read group allow read statement\n"); + return(-1); + } + + /*----------------------------------*/ + /* Read Group AllowInsert Statement */ + /*----------------------------------*/ + rc = SQLAllocStmt(uh->hdbc, &uh->readGroupAllowInsert.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to allocate read subscriber session statement\n"); + return(-1); + } + + rc = SQLPrepare(uh->readGroupAllowInsert.stmt,(SQLCHAR *) read_group_allowInsert_stmnt, SQL_NTS); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare read group allow read statement\n"); + return(-1); + } + + rc = SQLBindParameter(uh->readGroupAllowInsert.stmt, + 1,SQL_PARAM_INPUT,SQL_C_DEFAULT,SQL_INTEGER, + 0,0, + &uh->readGroupAllowInsert.values.groupId,0,NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare read allow read statement param 1\n"); + return(-1); + } + + rc = SQLBindCol(uh->readGroupAllowInsert.stmt, 1, + SQL_C_DEFAULT, + &uh->readGroupAllowInsert.values.allowInsert, 0, + NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to bind column 1 to read group allow read statement\n"); + return(-1); + } + + /*----------------------------------*/ + /* Read Group AllowDelete Statement */ + /*----------------------------------*/ + rc = SQLAllocStmt(uh->hdbc, &uh->readGroupAllowDelete.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to allocate read subscriber session statement\n"); + return(-1); + } + + rc = SQLPrepare(uh->readGroupAllowDelete.stmt,(SQLCHAR *) read_group_allowDelete_stmnt, SQL_NTS); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare read group allow read statement\n"); + return(-1); + } + + rc = SQLBindParameter(uh->readGroupAllowDelete.stmt, + 1,SQL_PARAM_INPUT,SQL_C_DEFAULT,SQL_INTEGER, + 0,0, + &uh->readGroupAllowDelete.values.groupId,0,NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare read allow read statement param 1\n"); + return(-1); + } + + rc = SQLBindCol(uh->readGroupAllowDelete.stmt, 1, + SQL_C_DEFAULT, + &uh->readGroupAllowDelete.values.allowDelete, 0, + NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to bind column 1 to read group allow read statement\n"); + return(-1); + } + + /*----------------------*/ + /* read session details */ + /*----------------------*/ + rc = SQLAllocStmt(uh->hdbc, &uh->readSessionDetails.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to allocate read session details statement\n"); + return(-1); + } + + rc = SQLPrepare(uh->readSessionDetails.stmt,(SQLCHAR *) read_session_details_stmnt, SQL_NTS); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare read session details statement\n"); + return(-1); + } + + rc = SQLBindParameter(uh->readSessionDetails.stmt, + 1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, + SUBSCRIBER_NUMBER_LENGTH+1,0, + uh->readSessionDetails.values.number,0,NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare read sessions param 1\n"); + return(-1); + } + + rc = SQLBindParameter(uh->readSessionDetails.stmt, + 2,SQL_PARAM_INPUT,SQL_C_DEFAULT,SQL_INTEGER, + 0,0, + &uh->readSessionDetails.values.serverId,0,NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare read sessions param 2\n"); + return(-1); + } + + rc = SQLBindCol(uh->readSessionDetails.stmt, 1, + SQL_C_CHAR, + uh->readSessionDetails.values.details, SESSION_DETAILS_LENGTH+1, + NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to bind column 1 to read group allow read statement\n"); + return(-1); + } + + /*-------------------*/ + /* Update no of Read */ + /*-------------------*/ + rc = SQLAllocStmt(uh->hdbc, &uh->updateServerNoOfRead.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to allocate update noOfRead statement\n"); + return(-1); + } + + rc = SQLPrepare(uh->updateServerNoOfRead.stmt,(SQLCHAR *) update_noOfRead_stmnt, SQL_NTS); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare update noOfRead statement\n"); + return(-1); + } + + rc = SQLBindParameter(uh->updateServerNoOfRead.stmt, + 1,SQL_PARAM_INPUT,SQL_C_DEFAULT,SQL_INTEGER, + 0,0, + &uh->updateServerNoOfRead.values.serverId,0,NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare read noOfRead param 1\n"); + return(-1); + } + + rc = SQLBindParameter(uh->updateServerNoOfRead.stmt, + 2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, + SUBSCRIBER_NUMBER_SUFFIX_LENGTH+1,0, + uh->updateServerNoOfRead.values.suffix,0,NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare read noOfRead param 2\n"); + return(-1); + } + + /*----------------*/ + /* Insert Session */ + /*----------------*/ + rc = SQLAllocStmt(uh->hdbc, &uh->insertSession.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to allocate update noOfRead statement\n"); + return(-1); + } + + rc = SQLPrepare(uh->insertSession.stmt,(SQLCHAR *) insert_session_stmnt, SQL_NTS); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare insert session statement\n"); + return(-1); + } + + rc = SQLBindParameter(uh->insertSession.stmt, + 1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, + SUBSCRIBER_NUMBER_LENGTH+1,0, + uh->insertSession.values.number,0,NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare read sessions param 1\n"); + return(-1); + } + + rc = SQLBindParameter(uh->insertSession.stmt, + 2,SQL_PARAM_INPUT,SQL_C_DEFAULT,SQL_INTEGER, + 0,0, + &uh->insertSession.values.serverId,0,NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare read noOfRead param 2\n"); + return(-1); + } + + rc = SQLBindParameter(uh->insertSession.stmt, + 3,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, + SESSION_DETAILS_LENGTH+1,0, + uh->insertSession.values.details,0,NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare read sessions param 1\n"); + return(-1); + } + + /*----------------------------*/ + /* Update subscriber sessions */ + /*----------------------------*/ + rc = SQLAllocStmt(uh->hdbc, &uh->updateSubscriberSession.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to allocate update noOfRead statement\n"); + return(-1); + } + + rc = SQLPrepare(uh->updateSubscriberSession.stmt,(SQLCHAR *) update_subscriber_session_stmnt, SQL_NTS); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare update subscriber session statement\n"); + return(-1); + } + + rc = SQLBindParameter(uh->updateSubscriberSession.stmt, + 1,SQL_PARAM_INPUT,SQL_C_DEFAULT,SQL_INTEGER, + 0,0, + &uh->updateSubscriberSession.values.activeSessions,0,NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare read noOfRead param 2\n"); + return(-1); + } + + rc = SQLBindParameter(uh->updateSubscriberSession.stmt, + 2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, + SUBSCRIBER_NUMBER_LENGTH+1,0, + uh->updateSubscriberSession.values.number,0,NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare read sessions param 1\n"); + return(-1); + } + + /*---------------------*/ + /* Update no of Insert */ + /*---------------------*/ + rc = SQLAllocStmt(uh->hdbc, &uh->updateServerNoOfInsert.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to allocate update noOfRead statement\n"); + return(-1); + } + + rc = SQLPrepare(uh->updateServerNoOfInsert.stmt,(SQLCHAR *) update_noOfInsert_stmnt, SQL_NTS); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare update noOfRead statement\n"); + return(-1); + } + + rc = SQLBindParameter(uh->updateServerNoOfInsert.stmt, + 1,SQL_PARAM_INPUT,SQL_C_DEFAULT,SQL_INTEGER, + 0,0, + &uh->updateServerNoOfInsert.values.serverId,0,NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare read noOfRead param 1\n"); + return(-1); + } + + rc = SQLBindParameter(uh->updateServerNoOfInsert.stmt, + 2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, + SUBSCRIBER_NUMBER_SUFFIX_LENGTH+1,0, + uh->updateServerNoOfInsert.values.suffix,0,NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare read noOfRead param 2\n"); + return(-1); + } + + /*----------------*/ + /* Delete Session */ + /*----------------*/ + rc = SQLAllocStmt(uh->hdbc, &uh->deleteSession.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to allocate update noOfRead statement\n"); + return(-1); + } + + rc = SQLPrepare(uh->deleteSession.stmt,(SQLCHAR *) delete_session_stmnt, SQL_NTS); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare insert session statement\n"); + return(-1); + } + + rc = SQLBindParameter(uh->deleteSession.stmt, + 1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, + SUBSCRIBER_NUMBER_LENGTH+1,0, + uh->deleteSession.values.number,0,NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare read sessions param 1\n"); + return(-1); + } + + rc = SQLBindParameter(uh->deleteSession.stmt, + 2,SQL_PARAM_INPUT,SQL_C_DEFAULT,SQL_INTEGER, + 0,0, + &uh->deleteSession.values.serverId,0,NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare read noOfRead param 2\n"); + return(-1); + } + + /*---------------------*/ + /* Update no of Delete */ + /*---------------------*/ + rc = SQLAllocStmt(uh->hdbc, &uh->updateServerNoOfDelete.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to allocate update noOfRead statement\n"); + return(-1); + } + + rc = SQLPrepare(uh->updateServerNoOfDelete.stmt,(SQLCHAR *) update_noOfDelete_stmnt, SQL_NTS); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare update noOfRead statement\n"); + return(-1); + } + + rc = SQLBindParameter(uh->updateServerNoOfDelete.stmt, + 1,SQL_PARAM_INPUT,SQL_C_DEFAULT,SQL_INTEGER, + 0,0, + &uh->updateServerNoOfDelete.values.serverId,0,NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare read noOfRead param 1\n"); + return(-1); + } + + rc = SQLBindParameter(uh->updateServerNoOfDelete.stmt, + 2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR, + SUBSCRIBER_NUMBER_SUFFIX_LENGTH+1,0, + uh->updateServerNoOfInsert.values.suffix,0,NULL); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to prepare read noOfRead param 2\n"); + return(-1); + } + + /*-------------------------------*/ + /* Commit all prepare statements */ + /*-------------------------------*/ + rc = SQLTransact(uh->henv, uh->hdbc, SQL_COMMIT); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to commit all prepare insert statement\n"); + return(-1); + } + + return(0); +} diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/macros.h b/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/macros.h new file mode 100644 index 00000000000..363f247b93f --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/macros.h @@ -0,0 +1,51 @@ +/* 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 */ + +#ifndef MACROS_H +#define MACROS_H + +#include +#include + +#define ERROR(x) {ndbout_c((x)); } +#define ERROR1(x,y) {ndbout_c((x), (y)); } +#define ERROR2(x,y,z) {ndbout_c((x), (y), (z)); } +#define ERROR3(x,y,z,u) {ndbout_c((x), (y), (z), (u)); } +#define ERROR4(x,y,z,u,w) {ndbout_c((x), (y), (z), (u), (w)); } + +#define INIT_RANDOM(x) srand48((x)) +#define UI_RANDOM(x) ((unsigned int)(lrand48()%(x))) + +#define ASSERT(cond, message) \ + { if(!(cond)) { ERROR(message); exit(-1); }} + +#ifdef DEBUG_ON +#define DEBUG(x) {ndbout_c((x)); } +#define DEBUG1(x,y) {ndbout_c((x), (y)); } +#define DEBUG2(x,y,z) {ndbout_c((x), (y), (z)); } +#define DEBUG3(x,y,z,u) {ndbout_c((x), (y), (z), (u)); } +#define DEBUG4(x,y,z,u,w) {ndbout_c((x), (y), (z), (u), (w)); } +#define DEBUG5(x,y,z,u,w, v) {ndbout_c((x), (y), (z), (u), (w), (v)); } +#else +#define DEBUG(x) +#define DEBUG1(x,y) +#define DEBUG2(x,y,z) +#define DEBUG3(x,y,z,u) +#define DEBUG4(x,y,z,u,w) +#define DEBUG5(x,y,z,u,w, v) +#endif + +#endif diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/ndb_error.hpp b/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/ndb_error.hpp new file mode 100644 index 00000000000..b3aaeac822e --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/ndb_error.hpp @@ -0,0 +1,31 @@ +/* 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 */ + +#ifndef NDB_ERROR_H +#define NDB_ERROR_H + +#include + +#define error_handler(x,y, z) { \ + ndbout << x << " " << y << endl; \ + exit(-1); } + +#define CHECK_NULL(x,y, z) if(x == 0) \ + error_handler(y,(z->getNdbError()), 0) +#define CHECK_MINUS_ONE(x, y, z) if(x == -1) \ + error_handler(y,(z->getNdbError()), 0) + +#endif diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/old/Makefile b/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/old/Makefile new file mode 100644 index 00000000000..9b1247d44af --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/old/Makefile @@ -0,0 +1,10 @@ +include ../makevars.$(ARCH) + +LIBRARY = ../../lib/libUser.so + +OBJECTS = \ + $(LIBRARY)(localDbPrepare.o)\ + $(LIBRARY)(userInterface.o)\ + $(LIBRARY)(userTransaction.o) + +$(LIBRARY): $(OBJECTS) diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/old/userHandle.h b/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/old/userHandle.h new file mode 100644 index 00000000000..1de468d4dad --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/old/userHandle.h @@ -0,0 +1,190 @@ +/* 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 */ + +#ifndef USERHANDLE_H +#define USERHANDLE_H + +/***************************************************************/ +/* I N C L U D E D F I L E S */ +/***************************************************************/ + +#include "sql.h" +#include "sqlext.h" +#include "sqltypes.h" + +#include "testDefinitions.h" + +/*************************************************************** +* M A C R O S * +***************************************************************/ + +/***************************************************************/ +/* C O N S T A N T S */ +/***************************************************************/ + +/*************************************************************** +* D A T A S T R U C T U R E S * +***************************************************************/ + +struct userHandle{ + SQLHENV henv; + SQLHDBC hdbc; + SQLHSTMT stmt; + + /*----------------*/ + /* Transaction T1 */ + /*----------------*/ + struct { + SQLHSTMT stmt; + struct { + SubscriberNumber number; + Location location; + ChangedBy changedBy; + ChangedTime changedTime; + }values; + }updateSubscriber; + + /*----------------*/ + /* Transaction T2 */ + /*----------------*/ + struct { + SQLHSTMT stmt; + struct { + SubscriberNumber number; + SubscriberName name; + Location location; + ChangedBy changedBy; + ChangedTime changedTime; + }values; + }readSubscriber; + + /*----------------*/ + /* Transaction T3 */ + /*----------------*/ + struct { + SQLHSTMT stmt; + struct { + GroupId groupId; + Permission allowRead; + }values; + }readGroupAllowRead; + + struct { + SQLHSTMT stmt; + struct { + SubscriberNumber number; + ServerId serverId; + SessionDetails details; + }values; + }readSessionDetails; + + struct { + SQLHSTMT stmt; + struct { + ServerId serverId; + SubscriberSuffix suffix; + }values; + }updateServerNoOfRead; + + /*----------------*/ + /* Transaction T4 */ + /*----------------*/ + struct { + SQLHSTMT stmt; + struct { + GroupId groupId; + Permission allowInsert; + }values; + }readGroupAllowInsert; + + struct { + SQLHSTMT stmt; + struct { + SubscriberNumber number; + ServerId serverId; + SessionDetails details; + }values; + }insertSession; + + struct { + SQLHSTMT stmt; + struct { + ServerId serverId; + SubscriberSuffix suffix; + }values; + }updateServerNoOfInsert; + + /*----------------*/ + /* Transaction T5 */ + /*----------------*/ + struct { + SQLHSTMT stmt; + struct { + GroupId groupId; + Permission allowDelete; + }values; + }readGroupAllowDelete; + + struct { + SQLHSTMT stmt; + struct { + SubscriberNumber number; + ServerId serverId; + }values; + }deleteSession; + + struct { + SQLHSTMT stmt; + struct { + ServerId serverId; + SubscriberSuffix suffix; + }values; + }updateServerNoOfDelete; + + /*--------------------------*/ + /* Transaction T3 + T4 + T5 */ + /*--------------------------*/ + struct { + SQLHSTMT stmt; + struct { + SubscriberNumber number; + uint32 activeSessions; + GroupId groupId; + ChangedBy changedBy; + ChangedTime changedTime; + }values; + }readSubscriberSession; + + struct { + SQLHSTMT stmt; + struct { + SubscriberNumber number; + uint32 activeSessions; + }values; + }updateSubscriberSession; +}; + +/*************************************************************** +* P U B L I C F U N C T I O N S * +***************************************************************/ + +/*************************************************************** +* E X T E R N A L D A T A * +***************************************************************/ + + +#endif /* USERHANDLE_H */ + diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/old/userInterface.c b/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/old/userInterface.c new file mode 100644 index 00000000000..bacf1861dde --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/old/userInterface.c @@ -0,0 +1,453 @@ +/* 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 */ + +/*************************************************************** +* I N C L U D E D F I L E S * +***************************************************************/ + +#include + +#include "userInterface.h" +#include "userHandle.h" + +/*************************************************************** +* L O C A L C O N S T A N T S * +***************************************************************/ + +/*************************************************************** +* L O C A L D A T A S T R U C T U R E S * +***************************************************************/ + +/*************************************************************** +* L O C A L F U N C T I O N S * +***************************************************************/ + +extern int localDbPrepare(UserHandle *uh); + +static int dbCreate(UserHandle *uh); + +/*************************************************************** +* L O C A L D A T A * +***************************************************************/ + +static char *create_subscriber_table = +"CREATE TABLE subscriber(\ +subscriberNumber CHAR(12) NOT NULL primary key,\ +subscriberName CHAR(32) NOT NULL,\ +groupId INT NOT NULL,\ +location INT NOT NULL,\ +activeSessions INT NOT NULL,\ +changedBy CHAR(32) NOT NULL,\ +changedTime CHAR(32) NOT NULL)"; + +static char *create_group_table = +"CREATE TABLE userGroup(\ +groupId INT NOT NULL primary key,\ +groupName CHAR(32) NOT NULL,\ +allowRead INT NOT NULL,\ +allowInsert INT NOT NULL,\ +allowDelete INT NOT NULL)"; + +static char *create_server_table = "CREATE TABLE server(\ +serverId INT NOT NULL,\ +subscriberSuffix CHAR(2) NOT NULL,\ +serverName CHAR(32) NOT NULL,\ +noOfRead INT NOT NULL,\ +noOfInsert INT NOT NULL,\ +noOfDelete INT NOT NULL,\ +PRIMARY KEY(serverId,subscriberSuffix))"; + +static char *create_session_table = +"CREATE TABLE userSession(\ +subscriberNumber CHAR(12) NOT NULL,\ +serverId INT NOT NULL,\ +sessionData CHAR(2000) NOT NULL,\ +PRIMARY KEY(subscriberNumber,serverId))"; + +/*************************************************************** +* P U B L I C D A T A * +***************************************************************/ + + +/*************************************************************** +**************************************************************** +* L O C A L F U N C T I O N S C O D E S E C T I O N * +**************************************************************** +***************************************************************/ + +/*************************************************************** +**************************************************************** +* P U B L I C F U N C T I O N S C O D E S E C T I O N * +**************************************************************** +***************************************************************/ + +/*-----------------------------------*/ +/* Time related Functions */ +/* */ +/* Returns a double value in seconds */ +/*-----------------------------------*/ +double userGetTime(void) +{ + static int initialized = 0; + static struct timeval initTime; + double timeValue; + + if( !initialized ) { + initialized = 1; + gettimeofday(&initTime, 0); + timeValue = 0.0; + } + else { + struct timeval tv; + double s; + double us; + + gettimeofday(&tv, 0); + s = (double)tv.tv_sec - (double)initTime.tv_sec; + us = (double)tv.tv_usec - (double)initTime.tv_usec; + + timeValue = s + (us / 1000000.0); + } + + return(timeValue); +} + + +void handle_error(SQLHDBC hdbc, + SQLHENV henv, + SQLHSTMT hstmt, + SQLRETURN rc, + char *filename, + int lineno) +{ +#define MSG_LNG 512 + + int isError = 0; + SQLRETURN ret = SQL_SUCCESS; + SQLCHAR szSqlState[MSG_LNG]; /* SQL state string */ + SQLCHAR szErrorMsg[MSG_LNG]; /* Error msg text buffer pointer */ + SQLINTEGER pfNativeError; /* Native error code */ + SQLSMALLINT pcbErrorMsg; /* Error msg text Available bytes */ + + if ( rc == SQL_SUCCESS || rc == SQL_NO_DATA_FOUND ) + return; + else if ( rc == SQL_INVALID_HANDLE ) { + printf("ERROR in %s, line %d: invalid handle\n", + filename, lineno); + isError = 1; + } + else if ( rc == SQL_SUCCESS_WITH_INFO ) { + printf("WARNING in %s, line %d\n", + filename, lineno); + isError = 0; + } + else if ( rc == SQL_ERROR ) { + printf("ERROR in %s, line %d\n", + filename, lineno); + isError = 1; + } + + fflush(stdout); + + while ( ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO ) { + ret = SQLError(henv, hdbc, hstmt, szSqlState, &pfNativeError, szErrorMsg, + MSG_LNG, &pcbErrorMsg); + + switch (ret) { + case SQL_SUCCESS: + case SQL_SUCCESS_WITH_INFO: + printf("%s\n*** ODBC Error/Warning = %s, " + "Additional Error/Warning = %d\n", + szErrorMsg, szSqlState, pfNativeError); + + if(ret == SQL_SUCCESS_WITH_INFO) + printf("(Note: error message was truncated.\n"); + break; + + case SQL_INVALID_HANDLE: + printf("Call to SQLError failed with return code of " + "SQL_INVALID_HANDLE.\n"); + break; + + case SQL_ERROR: + printf("Call to SQLError failed with return code of SQL_ERROR.\n"); + break; + + case SQL_NO_DATA_FOUND: + break; + + default: + printf("Call to SQLError failed with return code of %d.\n", ret); + } + } + + if ( isError ) + exit(1); +} + +static int dbCreate(UserHandle *uh) +{ + SQLRETURN rc; + SQLHSTMT creatstmt; + + if(!uh) return(-1); + + rc = SQLAllocStmt(uh->hdbc, &creatstmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to allocate create statement\n"); + return(-1); + } + + rc = SQLExecDirect(creatstmt,(SQLCHAR *)create_subscriber_table, SQL_NTS); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to create subscriber table\n"); + return(-1); + } + + rc = SQLExecDirect(creatstmt,(SQLCHAR *)create_group_table, SQL_NTS); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to create group table\n"); + return(-1); + } + + rc = SQLExecDirect(creatstmt,(SQLCHAR *)create_server_table, SQL_NTS); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to create server table\n"); + return(-1); + } + + rc = SQLExecDirect(creatstmt,(SQLCHAR *)create_session_table, SQL_NTS); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to create session table\n"); + return(-1); + } + + rc = SQLTransact(uh->henv, uh->hdbc, SQL_COMMIT); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to commit all create table\n"); + return(-1); + } + + rc = SQLFreeStmt(creatstmt, SQL_DROP); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to free create statement\n"); + return(-1); + } + + return(0); +} + +UserHandle *userDbConnect(uint32 createDb, char *dbName) +{ + char connStrIn[512]; /* ODBC Connection String */ + char connStrOut[2048]; + SQLRETURN rc; + UserHandle *uh; + + /*--------------------------*/ + /* Build the Connect string */ + /*--------------------------*/ + sprintf(connStrIn, + "AutoCreate=%d;OverWrite=%d;DSN=%s", + createDb ? 1 : 0, + createDb ? 1 : 0, + dbName); + + uh = calloc(1, sizeof(UserHandle)); + if( !uh ) { + printf("Unable to allocate memory for Handle\n"); + return(0); + } + + /*---------------------------------*/ + /* Allocate the Environment Handle */ + /*---------------------------------*/ + rc = SQLAllocEnv(&uh->henv); + + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to allocate Environment Handle\n"); + return(0); + } + + /*--------------------------------*/ + /* Allocate the DB Connect Handle */ + /*--------------------------------*/ + rc = SQLAllocConnect(uh->henv, &uh->hdbc); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to allocate a connection handle\n"); + return(0); + } + + /*-------------------------*/ + /* Connect to the Database */ + /*-------------------------*/ + rc = SQLDriverConnect(uh->hdbc, NULL, + (SQLCHAR *)connStrIn, SQL_NTS, + (SQLCHAR *)connStrOut, sizeof (connStrOut), + NULL, SQL_DRIVER_NOPROMPT); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { +handle_error(uh->hdbc, uh->henv, NULL, rc, __FILE__, __LINE__); + printf("Unable to connect to database server\n"); + return(0); + } + + rc = SQLSetConnectOption(uh->hdbc, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to set connection option\n"); + return(0); + } + + rc = SQLAllocStmt(uh->hdbc, &uh->stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to allocate immediate statement\n"); + return(0); + } + + if( createDb ) + dbCreate(uh); + + if( localDbPrepare(uh) < 0 ) + return(0); + + return(uh); +} + +void userDbDisconnect(UserHandle *uh) +{ + SQLRETURN rc; + + if(!uh) return; + + rc = SQLDisconnect(uh->hdbc); + + SQLFreeConnect(uh->hdbc); + SQLFreeEnv(uh->henv); + free(uh); +} + +int userDbInsertServer(UserHandle *uh, + ServerId serverId, + SubscriberSuffix suffix, + ServerName name) +{ + SQLRETURN rc; + char buf[1000]; + + if(!uh) return(-1); + + sprintf(buf, "insert into server values (%d,'%.*s','%s',0,0,0)", + serverId, + SUBSCRIBER_NUMBER_SUFFIX_LENGTH, suffix, + name); + + rc = SQLExecDirect(uh->stmt, (unsigned char *)buf, SQL_NTS); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to execute insert server\n"); + return(-1); + } + + return( userDbCommit(uh) ); +} + +int userDbInsertSubscriber(UserHandle *uh, + SubscriberNumber number, + uint32 groupId, + SubscriberName name) +{ + SQLRETURN rc; + char buf[1000]; + + if(!uh) return(-1); + + sprintf(buf, "insert into subscriber values ('%s','%s',%d,0,0,'','')", + number, + name, + groupId); + + rc = SQLExecDirect(uh->stmt, (unsigned char*)buf, SQL_NTS); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to execute insert subscriber\n"); + return(-1); + } + + return( userDbCommit(uh) ); +} + +int userDbInsertGroup(UserHandle *uh, + GroupId groupId, + GroupName name, + Permission allowRead, + Permission allowInsert, + Permission allowDelete) +{ + SQLRETURN rc; + char buf[1000]; + + if(!uh) return(-1); + + sprintf(buf, "insert into usergroup values (%d,'%s',%d,%d,%d)", + groupId, + name, + allowRead, + allowInsert, + allowDelete); + + rc = SQLExecDirect(uh->stmt, (unsigned char*)buf, SQL_NTS); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to execute insert group\n"); + return(-1); + } + + return( userDbCommit(uh) ); +} + +int userDbCommit(UserHandle *uh) +{ + SQLRETURN rc; + if(!uh) return(-1); + + rc = SQLTransact(uh->henv, uh->hdbc, SQL_COMMIT); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { +handle_error(uh->hdbc, uh->henv, 0, rc, __FILE__, __LINE__); + printf("Unable to commit Transaction\n"); + return(-1); + } + + return(0); +} + +int userDbRollback(UserHandle *uh) +{ + SQLRETURN rc; + if(!uh) return(-1); + + rc = SQLTransact(uh->henv, uh->hdbc, SQL_ROLLBACK); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("Unable to rollback Transaction\n"); + return(-1); + } + + return(0); +} + +void userCheckpoint(UserHandle *uh) +{ + SQLRETURN rc; + if(!uh) return; + + rc = SQLExecDirect(uh->stmt, (SQLCHAR *)"call ttCheckpointFuzzy", SQL_NTS); + userDbCommit(uh); +} diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/old/userTransaction.c b/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/old/userTransaction.c new file mode 100644 index 00000000000..a2f4787bb0c --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/old/userTransaction.c @@ -0,0 +1,473 @@ +/* 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 */ + +/*************************************************************** +* I N C L U D E D F I L E S * +***************************************************************/ + +#include +#include + +#include "sql.h" +#include "sqlext.h" + + +#include "userInterface.h" +#include "userHandle.h" + +/*************************************************************** +* L O C A L C O N S T A N T S * +***************************************************************/ + +/*************************************************************** +* L O C A L D A T A S T R U C T U R E S * +***************************************************************/ + +/*************************************************************** +* L O C A L F U N C T I O N S * +***************************************************************/ + +static int readSubscriberSessions(UserHandle *uh, + SubscriberNumber number, + char *transactionType); + +/*************************************************************** +* L O C A L D A T A * +***************************************************************/ + +extern void handle_error(SQLHDBC hdbc, + SQLHENV henv, + SQLHSTMT hstmt, + SQLRETURN rc, + char *filename, + int lineno); + +/*************************************************************** +* P U B L I C D A T A * +***************************************************************/ + + +/*************************************************************** +**************************************************************** +* L O C A L F U N C T I O N S C O D E S E C T I O N * +**************************************************************** +***************************************************************/ + +static int readSubscriberSessions(UserHandle *uh, + SubscriberNumber number, + char *transactionType) +{ + SQLRETURN rc; + + /*-----------------------------------------------------*/ + /* SELECT activeSessions,groupId,changedBy,changedTime */ + /* FROM SUBSCRIBER */ + /* WHERE subscriberNumber=x; */ + /*-----------------------------------------------------*/ + strcpy(uh->readSubscriberSession.values.number,number); + + rc = SQLExecute(uh->readSubscriberSession.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("%s %s\n", + transactionType, + "Unable to execute read subscriber session"); + return(-1); + } + + rc = SQLFetch(uh->readSubscriberSession.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("%s %s\n", + transactionType, + "Unable to fetch read subscriber session"); + return(-1); + } + + return(0); +} + +/*************************************************************** +**************************************************************** +* P U B L I C F U N C T I O N S C O D E S E C T I O N * +**************************************************************** +***************************************************************/ + +void userTransaction_T1(UserHandle *uh, + SubscriberNumber number, + Location new_location, + ChangedBy changed_by, + ChangedTime changed_time) +{ + SQLRETURN rc; + + if(!uh) return; + + /*---------------------------------------------*/ + /* Update the subscriber information */ + /* */ + /* UPDATE SUBSCRIBER */ + /* SET location=x, changedBy=x, changedTime=x */ + /* WHERE subscriberNumber=x; */ + /*---------------------------------------------*/ + strcpy(uh->updateSubscriber.values.number, number); + uh->updateSubscriber.values.location = new_location; + strcpy(uh->updateSubscriber.values.changedBy, changed_by); + strcpy(uh->updateSubscriber.values.changedTime, changed_time); + + rc = SQLExecute(uh->updateSubscriber.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T1 Unable to execute update subscriber\n"); + return; + } + + userDbCommit(uh); +} + +void userTransaction_T2(UserHandle *uh, + SubscriberNumber number, + Location *new_location, + ChangedBy changed_by, + ChangedTime changed_time, + SubscriberName subscriberName) +{ + SQLRETURN rc; + + if(!uh) return; + + /*------------------------------------------------------*/ + /* Read the information from the subscriber table */ + /* */ + /* SELECT location,subscriberName,changedBy,changedTime */ + /* FROM SUBSCRIBER */ + /* WHERE subscriberNumber=x; */ + /*------------------------------------------------------*/ + strcpy(uh->readSubscriber.values.number,number); + + rc = SQLExecute(uh->readSubscriber.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T2 Unable to execute read subscriber\n"); + return; + } + + rc = SQLFetch(uh->readSubscriber.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T2 Unable to fetch read subscriber\n"); + return; + } + + userDbCommit(uh); + + strcpy(subscriberName, uh->readSubscriber.values.name); + *new_location = uh->readSubscriber.values.location; + strcpy(changed_by, uh->readSubscriber.values.changedBy); + strcpy(changed_time, uh->readSubscriber.values.changedTime); +} + +void userTransaction_T3(UserHandle *uh, + SubscriberNumber number, + ServerId server_id, + ServerBit server_bit, + SessionDetails session_details, + unsigned int *branch_executed) +{ + SQLRETURN rc; + + if(!uh) return; + + *branch_executed = 0; + + /*--------------------------------------*/ + /* Read active sessions from subscriber */ + /*--------------------------------------*/ + if( readSubscriberSessions(uh, number, "T3") < 0 ) + return; + + /*-----------------------------------------------*/ + /* Read the 'read' Permissions for the userGroup */ + /* */ + /* SELECT allowRead */ + /* FROM USERGROUP */ + /* WHERE groupId=x */ + /*-----------------------------------------------*/ + uh->readGroupAllowRead.values.groupId = uh->readSubscriberSession.values.groupId; + + rc = SQLExecute(uh->readGroupAllowRead.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T3 Unable to execute read group allow read\n"); + return; + } + + rc = SQLFetch(uh->readGroupAllowRead.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T3 Unable to fetch read group allow read\n"); + return; + } + + if( uh->readGroupAllowRead.values.allowRead & server_bit && + uh->readSubscriberSession.values.activeSessions & server_bit ) { + + /*----------------------------------------------------*/ + /* Read the sessionDetails from the userSession table */ + /* */ + /* SELECT sessionData */ + /* FROM userSession */ + /* WHERE subscriberNumber=x, serverId=x */ + /*----------------------------------------------------*/ + strcpy(uh->readSessionDetails.values.number,number); + uh->readSessionDetails.values.serverId = server_id; + + rc = SQLExecute(uh->readSessionDetails.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T3 Unable to execute read session details\n"); + return; + } + + rc = SQLFetch(uh->readSessionDetails.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T3 Unable to fetch read session details\n"); + return; + } + + strcpy(session_details, uh->readSessionDetails.values.details); + + /*----------------------------------------*/ + /* Increment noOfRead field in the server */ + /* */ + /* UPDATE server */ + /* SET noOfRead=noOfRead+1 */ + /* WHERE serverId=x,subscriberSuffix=x */ + /*----------------------------------------*/ + uh->updateServerNoOfRead.values.serverId = server_id; + strcpy(uh->updateServerNoOfRead.values.suffix, + &number[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH]); + + rc = SQLExecute(uh->updateServerNoOfRead.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T3 Unable to execute read no of read\n"); + return; + } + + *branch_executed = 1; + } + + userDbCommit(uh); +} + +void userTransaction_T4(UserHandle *uh, + SubscriberNumber number, + ServerId server_id, + ServerBit server_bit, + SessionDetails session_details, + unsigned int do_rollback, + unsigned int *branch_executed) +{ + SQLRETURN rc; + + if(!uh) return; + + *branch_executed = 0; + + /*--------------------------------------*/ + /* Read active sessions from subscriber */ + /*--------------------------------------*/ + if( readSubscriberSessions(uh, number, "T4") < 0 ) + return; + + /*-------------------------------------------------*/ + /* Read the 'insert' Permissions for the userGroup */ + /* */ + /* SELECT allowInsert */ + /* FROM USERGROUP */ + /* WHERE groupId=x */ + /*-------------------------------------------------*/ + uh->readGroupAllowInsert.values.groupId = uh->readSubscriberSession.values.groupId; + + rc = SQLExecute(uh->readGroupAllowInsert.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T4 Unable to execute read group allow insert\n"); + return; + } + + rc = SQLFetch(uh->readGroupAllowInsert.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T4 Unable to fetch read group allow insert\n"); + return; + } + + if( uh->readGroupAllowInsert.values.allowInsert & server_bit && + !(uh->readSubscriberSession.values.activeSessions & server_bit) ) { + + /*---------------------------------------------*/ + /* Insert the session to the userSession table */ + /* */ + /* INSERT INTO userSession */ + /* VALUES (x,x,x) */ + /*---------------------------------------------*/ + strcpy(uh->insertSession.values.number, number); + uh->insertSession.values.serverId = server_id; + strcpy(uh->insertSession.values.details, session_details); + + rc = SQLExecute(uh->insertSession.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { +handle_error(uh->hdbc, uh->henv, uh->insertSession.stmt, rc, __FILE__, __LINE__); + printf("T4 Unable to execute insert session \n"); + return; + } + + /*----------------------------------------*/ + /* Update subscriber activeSessions field */ + /* */ + /* UPDATE subscriber */ + /* SET activeSessions=x */ + /* WHERE subscriberNumber=x */ + /*----------------------------------------*/ + strcpy(uh->updateSubscriberSession.values.number, number); + uh->updateSubscriberSession.values.activeSessions = + uh->readSubscriberSession.values.activeSessions | server_bit; + + rc = SQLExecute(uh->updateSubscriberSession.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T4 Unable to execute update session \n"); + return; + } + + /*------------------------------------------*/ + /* Increment noOfInsert field in the server */ + /* */ + /* UPDATE server */ + /* SET noOfInsert=noOfInsert+1 */ + /* WHERE serverId=x,subscriberSuffix=x */ + /*------------------------------------------*/ + uh->updateServerNoOfInsert.values.serverId = server_id; + strcpy(uh->updateServerNoOfInsert.values.suffix, + &number[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH]); + + rc = SQLExecute(uh->updateServerNoOfInsert.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T4 Unable to execute update no of read\n"); + return; + } + + *branch_executed = 1; + } + + if(do_rollback) + userDbRollback(uh); + else + userDbCommit(uh); +} + +void userTransaction_T5(UserHandle *uh, + SubscriberNumber number, + ServerId server_id, + ServerBit server_bit, + unsigned int do_rollback, + unsigned int *branch_executed) +{ + SQLRETURN rc; + + if(!uh) return; + + *branch_executed = 0; + + /*--------------------------------------*/ + /* Read active sessions from subscriber */ + /*--------------------------------------*/ + if( readSubscriberSessions(uh, number, "T5") < 0 ) + return; + + /*-------------------------------------------------*/ + /* Read the 'delete' Permissions for the userGroup */ + /* */ + /* SELECT allowDelete */ + /* FROM USERGROUP */ + /* WHERE groupId=x */ + /*-------------------------------------------------*/ + uh->readGroupAllowDelete.values.groupId = uh->readSubscriberSession.values.groupId; + + rc = SQLExecute(uh->readGroupAllowDelete.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T5 Unable to execute read group allow delete\n"); + return; + } + + rc = SQLFetch(uh->readGroupAllowDelete.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T5 Unable to fetch read group allow delete\n"); + return; + } + + if( uh->readGroupAllowDelete.values.allowDelete & server_bit && + uh->readSubscriberSession.values.activeSessions & server_bit ) { + + /*-----------------------------------------------*/ + /* Delete the session from the userSession table */ + /* */ + /* DELETE FROM userSession */ + /* WHERE subscriberNumber=x,serverId=x */ + /*-----------------------------------------------*/ + strcpy(uh->deleteSession.values.number,number); + uh->deleteSession.values.serverId = server_id; + + rc = SQLExecute(uh->deleteSession.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T5 Unable to execute delete session\n"); + return; + } + + /*----------------------------------------*/ + /* Update subscriber activeSessions field */ + /* */ + /* UPDATE subscriber */ + /* SET activeSessions=x */ + /* WHERE subscriberNumber=x */ + /*----------------------------------------*/ + strcpy(uh->updateSubscriberSession.values.number, number); + uh->updateSubscriberSession.values.activeSessions = + uh->readSubscriberSession.values.activeSessions & ~server_bit; + + rc = SQLExecute(uh->updateSubscriberSession.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T5 Unable to execute update subscriber session \n"); + return; + } + + /*------------------------------------------*/ + /* Increment noOfDelete field in the server */ + /* */ + /* UPDATE server */ + /* SET noOfDelete=noOfDelete+1 */ + /* WHERE serverId=x,subscriberSuffix=x */ + /*------------------------------------------*/ + uh->updateServerNoOfDelete.values.serverId = server_id; + strcpy(uh->updateServerNoOfDelete.values.suffix, + &number[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH]); + + rc = SQLExecute(uh->updateServerNoOfDelete.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T5 Unable to execute update no of delete\n"); + return; + } + + *branch_executed = 1; + } + + if(do_rollback) + userDbRollback(uh); + else + userDbCommit(uh); +} + + diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/userHandle.h b/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/userHandle.h new file mode 100644 index 00000000000..6da76fc2bff --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/userHandle.h @@ -0,0 +1,51 @@ +/* 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 */ + +#ifndef USERHANDLE_H +#define USERHANDLE_H + +/***************************************************************/ +/* I N C L U D E D F I L E S */ +/***************************************************************/ + +#include +#include "testDefinitions.h" + +/*************************************************************** +* M A C R O S * +***************************************************************/ + +/***************************************************************/ +/* C O N S T A N T S */ +/***************************************************************/ + +/*************************************************************** +* D A T A S T R U C T U R E S * +***************************************************************/ + +typedef Ndb userHandle; + +/*************************************************************** +* P U B L I C F U N C T I O N S * +***************************************************************/ + +/*************************************************************** +* E X T E R N A L D A T A * +***************************************************************/ + + +#endif /* USERHANDLE_H */ + diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/userInterface.cpp b/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/userInterface.cpp new file mode 100644 index 00000000000..67c4e037215 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/userInterface.cpp @@ -0,0 +1,740 @@ +/* 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 */ + +/*************************************************************** +* I N C L U D E D F I L E S * +***************************************************************/ + +#include +#ifndef NDB_WIN32 +#include +#endif + +#include "ndb_error.hpp" +#include "userHandle.h" +#include "userInterface.h" +#include +#include +#include +#include +#include "ndb_schema.hpp" +#include + +/*************************************************************** +* L O C A L C O N S T A N T S * +***************************************************************/ + +/*************************************************************** +* L O C A L D A T A S T R U C T U R E S * +***************************************************************/ + +/*************************************************************** +* L O C A L F U N C T I O N S * +***************************************************************/ + +extern int localDbPrepare(UserHandle *uh); + +static int dbCreate(UserHandle *uh); + +/*************************************************************** +* L O C A L D A T A * +***************************************************************/ + +/*************************************************************** +* P U B L I C D A T A * +***************************************************************/ + + +/*************************************************************** +**************************************************************** +* L O C A L F U N C T I O N S C O D E S E C T I O N * +**************************************************************** +***************************************************************/ + +/*************************************************************** +**************************************************************** +* P U B L I C F U N C T I O N S C O D E S E C T I O N * +**************************************************************** +***************************************************************/ + +/*-----------------------------------*/ +/* Time related Functions */ +/* */ +/* Returns a double value in seconds */ +/*-----------------------------------*/ +double userGetTimeSync(void) +{ + static int initialized = 0; + static NDB_TICKS initSecs = 0; + static Uint32 initMicros = 0; + double timeValue = 0; + + if ( !initialized ) { + initialized = 1; + NdbTick_CurrentMicrosecond(&initSecs, &initMicros); + timeValue = 0.0; + } else { + NDB_TICKS secs = 0; + Uint32 micros = 0; + + NdbTick_CurrentMicrosecond(&secs, µs); + + double s = (double)secs - (double)initSecs; + double us = (double)secs - (double)initMicros; + + timeValue = s + (us / 1000000.0); + } + + return timeValue; +} + +// 0 - OK +// 1 - Retry transaction +// 2 - Permanent +int +userDbCommit(UserHandle *uh){ + if(uh->pCurrTrans != 0){ + int check = uh->pCurrTrans->execute( Commit ); + NdbError err = uh->pCurrTrans->getNdbError(); + uh->pNDB->closeTransaction(uh->pCurrTrans); + uh->pCurrTrans = 0; + + if(err.status != NdbError::Success) + ndbout << err << endl; + + if(err.status == NdbError::TemporaryError && + err.classification == NdbError::OverloadError){ + NdbSleep_SecSleep(3); + } + + return err.status; + } + return 2; +} + +/** + * TRUE - Normal table + * FALSE - Table w.o. checkpoing and logging + */ + +#ifdef __cplusplus +extern "C" { +#endif +extern int useTableLogging; +extern int useIndexTables; +#ifdef __cplusplus +} +#endif + + +int +create_table_server(Ndb * pNDB){ + + int check; + + NdbSchemaCon * MySchemaTransaction = pNDB->startSchemaTransaction(); + if( MySchemaTransaction == NULL ) + error_handler("startSchemaTransaction", pNDB->getNdbError(), 0); + + NdbSchemaOp * MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); + if( MySchemaOp == NULL ) + error_handler("getNdbSchemaOp", MySchemaTransaction->getNdbError(), 0); + + // Create table + check = MySchemaOp->createTable( SERVER_TABLE, + 8, // Table size + TupleKey, // Key Type + 1 // Nr of Pages + ,DistributionGroup, + 6, + 78, + 80, + 1, + useTableLogging + ); + if( check == -1 ) + error_handler("createTable", MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute + ( SERVER_SUBSCRIBER_SUFFIX, + TupleKey, + sizeof(char) << 3, + SUBSCRIBER_NUMBER_SUFFIX_LENGTH, + String, + MMBased, + NotNullAttribute, + NormalStorageAttribute, + 0, + 1, + 16); + if( check == -1 ) + error_handler("createAttribute (subscriber suffix)", + MySchemaTransaction->getNdbError(), 0); + + // Create first column, primary key + check = MySchemaOp->createAttribute( SERVER_ID, + TupleKey, + sizeof(ServerId) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (serverid)", + MySchemaTransaction->getNdbError(), 0); + + + check = MySchemaOp->createAttribute( SERVER_NAME, + NoKey, + sizeof(char) << 3, + SERVER_NAME_LENGTH, + String, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (server name)", + MySchemaTransaction->getNdbError(), 0); + + + check = MySchemaOp->createAttribute( SERVER_READS, + NoKey, + sizeof(Counter) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (server reads)", + MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute( SERVER_INSERTS, + NoKey, + sizeof(Counter) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (server inserts)", + MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute( SERVER_DELETES, + NoKey, + sizeof(Counter) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (server deletes)", + MySchemaTransaction->getNdbError(), 0); + + if( MySchemaTransaction->execute() == -1 ) { + error_handler("schemaTransaction->execute()", + MySchemaTransaction->getNdbError(), 0); + } + pNDB->closeSchemaTransaction(MySchemaTransaction); + return 0; +} + +int +create_table_group(Ndb * pNDB){ + int check; + + NdbSchemaCon * MySchemaTransaction = pNDB->startSchemaTransaction(); + if( MySchemaTransaction == NULL ) + error_handler("startSchemaTransaction", pNDB->getNdbError(), 0); + + NdbSchemaOp * MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); + if( MySchemaOp == NULL ) + error_handler("getNdbSchemaOp", MySchemaTransaction->getNdbError(), 0); + + // Create table + check = MySchemaOp->createTable( GROUP_TABLE, + 8, // Table size + TupleKey, // Key Type + 1 // Nr of Pages + ,All, + 6, + 78, + 80, + 1, + useTableLogging + ); + + if( check == -1 ) + error_handler("createTable", MySchemaTransaction->getNdbError(), 0); + + // Create first column, primary key + check = MySchemaOp->createAttribute( GROUP_ID, + TupleKey, + sizeof(GroupId) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (group id)", + MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute( GROUP_NAME, + NoKey, + sizeof(char) << 3, + GROUP_NAME_LENGTH, + String, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (group name)", + MySchemaTransaction->getNdbError(), 0); + + + check = MySchemaOp->createAttribute( GROUP_ALLOW_READ, + NoKey, + sizeof(Permission) << 3, + 1, + String, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (group read)", + MySchemaTransaction->getNdbError(), 0); + + + check = MySchemaOp->createAttribute( GROUP_ALLOW_INSERT, + NoKey, + sizeof(Permission) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (group insert)", + MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute( GROUP_ALLOW_DELETE, + NoKey, + sizeof(Permission) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (group delete)", + MySchemaTransaction->getNdbError(), 0); + + if( MySchemaTransaction->execute() == -1 ) { + error_handler("schemaTransaction->execute()", + MySchemaTransaction->getNdbError(), 0); + } + pNDB->closeSchemaTransaction(MySchemaTransaction); + return 0; +} + +int +create_table_subscriber(Ndb * pNDB){ + int check; + NdbSchemaCon * MySchemaTransaction = pNDB->startSchemaTransaction(); + if( MySchemaTransaction == NULL ) + error_handler("startSchemaTransaction", pNDB->getNdbError(), 0); + + NdbSchemaOp * MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); + if( MySchemaOp == NULL ) + error_handler("getNdbSchemaOp", MySchemaTransaction->getNdbError(), 0); + + // Create table + check = MySchemaOp->createTable( SUBSCRIBER_TABLE, + 8, // Table size + TupleKey, // Key Type + 1 // Nr of Pages + ,DistributionGroup, + 6, + 78, + 80, + 1, + useTableLogging + ); + if( check == -1 ) + error_handler("createTable", MySchemaTransaction->getNdbError(), 0); + + // Create first column, primary key + check = MySchemaOp->createAttribute + ( SUBSCRIBER_NUMBER, + TupleKey, + sizeof(char) << 3, + SUBSCRIBER_NUMBER_LENGTH, + String, + MMBased, + NotNullAttribute, + (useIndexTables ? IndexStorageAttribute : NormalStorageAttribute), + 0, + 1, + 16); + if( check == -1 ) + error_handler("createAttribute (subscriber number)", + MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute( SUBSCRIBER_NAME, + NoKey, + sizeof(char) << 3, + SUBSCRIBER_NAME_LENGTH, + String, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (subscriber name)", + MySchemaTransaction->getNdbError(), 0); + + + check = MySchemaOp->createAttribute( SUBSCRIBER_GROUP, + NoKey, + sizeof(GroupId) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (subscriber_group)", + MySchemaTransaction->getNdbError(), 0); + + + check = MySchemaOp->createAttribute( SUBSCRIBER_LOCATION, + NoKey, + sizeof(Location) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (server reads)", + MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute( SUBSCRIBER_SESSIONS, + NoKey, + sizeof(ActiveSessions) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (subscriber_sessions)", + MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute( SUBSCRIBER_CHANGED_BY, + NoKey, + sizeof(char) << 3, + CHANGED_BY_LENGTH, + String, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (subscriber_changed_by)", + MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute( SUBSCRIBER_CHANGED_TIME, + NoKey, + sizeof(char) << 3, + CHANGED_TIME_LENGTH, + String, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (subscriber_changed_time)", + MySchemaTransaction->getNdbError(), 0); + + if( MySchemaTransaction->execute() == -1 ) { + error_handler("schemaTransaction->execute()", + MySchemaTransaction->getNdbError(), 0); + } + pNDB->closeSchemaTransaction(MySchemaTransaction); + return 0; +} + +int +create_table_session(Ndb * pNDB){ + int check; + NdbSchemaCon * MySchemaTransaction = pNDB->startSchemaTransaction(); + if( MySchemaTransaction == NULL ) + error_handler("startSchemaTransaction", pNDB->getNdbError(), 0); + + NdbSchemaOp * MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); + if( MySchemaOp == NULL ) + error_handler("getNdbSchemaOp", + MySchemaTransaction->getNdbError(), 0); + + // Create table + check = MySchemaOp->createTable( SESSION_TABLE, + 8, // Table size + TupleKey, // Key Type + 1 // Nr of Pages + ,DistributionGroup, + 6, + 78, + 80, + 1, + useTableLogging + ); + if( check == -1 ) + error_handler("createTable", MySchemaTransaction->getNdbError(), 0); + + check = MySchemaOp->createAttribute( SESSION_SUBSCRIBER, + TupleKey, + sizeof(char) << 3, + SUBSCRIBER_NUMBER_LENGTH, + String, + MMBased, + NotNullAttribute, + NormalStorageAttribute, + 0, + 1, + 16); + if( check == -1 ) + error_handler("createAttribute (session_subscriber)", + MySchemaTransaction->getNdbError(), 0); + + // Create first column, primary key + check = MySchemaOp->createAttribute( SESSION_SERVER, + TupleKey, + sizeof(ServerId) << 3, + 1, + UnSigned, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (session_server)", + MySchemaTransaction->getNdbError(), 0); + + + check = MySchemaOp->createAttribute( SESSION_DATA, + NoKey, + sizeof(char) << 3, + SESSION_DETAILS_LENGTH, + String, + MMBased, + NotNullAttribute ); + if( check == -1 ) + error_handler("createAttribute (session_data)", + MySchemaTransaction->getNdbError(), 0); + + if( MySchemaTransaction->execute() == -1 ) { + error_handler("schemaTransaction->execute()", + MySchemaTransaction->getNdbError(), 0); + } + pNDB->closeSchemaTransaction(MySchemaTransaction); + return 0; +} + +void +create_table(const char * name, int (* function)(Ndb * pNDB), Ndb* pNDB){ + printf("creating table %s...", name); + if(pNDB->getDictionary()->getTable(name) != 0){ + printf(" it already exists\n"); + return; + } else { + printf("\n"); + } + function(pNDB); + printf("creating table %s... done\n", name); +} + +static int dbCreate(Ndb * pNDB) +{ + create_table(SUBSCRIBER_TABLE, create_table_subscriber, pNDB); + create_table(GROUP_TABLE , create_table_group, pNDB); + create_table(SESSION_TABLE , create_table_session, pNDB); + create_table(SERVER_TABLE , create_table_server, pNDB); + return 0; +} + +#ifndef NDB_WIN32 +#include +#endif + +static NdbMutex* startupMutex = NdbMutex_Create(); + +UserHandle* +userDbConnect(uint32 createDb, char *dbName) +{ + NdbMutex_Lock(startupMutex); + + Ndb * pNDB = new Ndb(""); + + //printf("Initializing...\n"); + pNDB->init(); + + //printf("Waiting..."); + while(pNDB->waitUntilReady() != 0){ + //printf("..."); + } + // printf("done\n"); + + if( createDb ) + dbCreate(pNDB); + + + UserHandle * uh = new UserHandle; + uh->pNDB = pNDB; + uh->pCurrTrans = 0; + + NdbMutex_Unlock(startupMutex); + + return uh; +} + +void userDbDisconnect(UserHandle *uh) +{ + delete uh; +} + +int userDbInsertServer(UserHandle *uh, + ServerId serverId, + SubscriberSuffix suffix, + ServerName name) +{ + int check; + + uint32 noOfRead = 0; + uint32 noOfInsert = 0; + uint32 noOfDelete = 0; + + NdbConnection * MyTransaction = 0; + if(uh->pCurrTrans != 0){ + MyTransaction = uh->pCurrTrans; + } else { + uh->pCurrTrans = MyTransaction = uh->pNDB->startTransaction(); + } + if (MyTransaction == NULL) + error_handler("startTranscation", uh->pNDB->getNdbError(), 0); + + NdbOperation *MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE); + CHECK_NULL(MyOperation, "getNdbOperation", MyTransaction); + + check = MyOperation->insertTuple(); + CHECK_MINUS_ONE(check, "insert tuple", MyTransaction); + + check = MyOperation->equal(SERVER_ID, (char*)&serverId); + CHECK_MINUS_ONE(check, "setValue id", MyTransaction); + + check = MyOperation->setValue(SERVER_SUBSCRIBER_SUFFIX, suffix); + CHECK_MINUS_ONE(check, "setValue suffix", MyTransaction); + + check = MyOperation->setValue(SERVER_NAME, name); + CHECK_MINUS_ONE(check, "setValue name", MyTransaction); + + check = MyOperation->setValue(SERVER_READS, (char*)&noOfRead); + CHECK_MINUS_ONE(check, "setValue reads", MyTransaction); + + check = MyOperation->setValue(SERVER_INSERTS, (char*)&noOfInsert); + CHECK_MINUS_ONE(check, "setValue inserts", MyTransaction); + + check = MyOperation->setValue(SERVER_DELETES, (char*)&noOfDelete); + CHECK_MINUS_ONE(check, "setValue deletes", MyTransaction); + + return 0; +} + +int userDbInsertSubscriber(UserHandle *uh, + SubscriberNumber number, + uint32 groupId, + SubscriberName name) +{ + int check; + uint32 activeSessions = 0; + Location l = 0; + ChangedBy changedBy; snprintf(changedBy, sizeof(changedBy), "ChangedBy"); + ChangedTime changedTime; snprintf(changedTime, sizeof(changedTime), "ChangedTime"); + + NdbConnection * MyTransaction = 0; + if(uh->pCurrTrans != 0){ + MyTransaction = uh->pCurrTrans; + } else { + uh->pCurrTrans = MyTransaction = uh->pNDB->startTransaction(); + } + if (MyTransaction == NULL) + error_handler("startTranscation", uh->pNDB->getNdbError(), 0); + + NdbOperation *MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE); + CHECK_NULL(MyOperation, "getNdbOperation", MyTransaction); + + check = MyOperation->insertTuple(); + CHECK_MINUS_ONE(check, "insertTuple", MyTransaction); + + check = MyOperation->equal(SUBSCRIBER_NUMBER, number); + CHECK_MINUS_ONE(check, "equal", MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_NAME, name); + CHECK_MINUS_ONE(check, "setValue name", MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_GROUP, (char*)&groupId); + CHECK_MINUS_ONE(check, "setValue group", MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_LOCATION, (char*)&l); + CHECK_MINUS_ONE(check, "setValue location", MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_SESSIONS, (char*)&activeSessions); + CHECK_MINUS_ONE(check, "setValue sessions", MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_CHANGED_BY, changedBy); + CHECK_MINUS_ONE(check, "setValue changedBy", MyTransaction); + + check = MyOperation->setValue(SUBSCRIBER_CHANGED_TIME, changedTime); + CHECK_MINUS_ONE(check, "setValue changedTime", MyTransaction); + + return 0; +} + +int userDbInsertGroup(UserHandle *uh, + GroupId groupId, + GroupName name, + Permission allowRead, + Permission allowInsert, + Permission allowDelete) +{ + int check; + + NdbConnection * MyTransaction = 0; + if(uh->pCurrTrans != 0){ + MyTransaction = uh->pCurrTrans; + } else { + uh->pCurrTrans = MyTransaction = uh->pNDB->startTransaction(); + } + if (MyTransaction == NULL) + error_handler("startTranscation", uh->pNDB->getNdbError(), 0); + + NdbOperation *MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE); + CHECK_NULL(MyOperation, "getNdbOperation", MyTransaction); + + check = MyOperation->insertTuple(); + CHECK_MINUS_ONE(check, "insertTuple", MyTransaction); + + check = MyOperation->equal(GROUP_ID, (char*)&groupId); + CHECK_MINUS_ONE(check, "equal", MyTransaction); + + check = MyOperation->setValue(GROUP_NAME, name); + CHECK_MINUS_ONE(check, "setValue name", MyTransaction); + + check = MyOperation->setValue(GROUP_ALLOW_READ, (char*)&allowRead); + CHECK_MINUS_ONE(check, "setValue allowRead", MyTransaction); + + check = MyOperation->setValue(GROUP_ALLOW_INSERT, (char*)&allowInsert); + CHECK_MINUS_ONE(check, "setValue allowInsert", MyTransaction); + + check = MyOperation->setValue(GROUP_ALLOW_DELETE, (char*)&allowDelete); + CHECK_MINUS_ONE(check, "setValue allowDelete", MyTransaction); + + return 0; +} + diff --git a/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/userTransaction.c b/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/userTransaction.c new file mode 100644 index 00000000000..a2f4787bb0c --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/lmc-bench/src/user/userTransaction.c @@ -0,0 +1,473 @@ +/* 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 */ + +/*************************************************************** +* I N C L U D E D F I L E S * +***************************************************************/ + +#include +#include + +#include "sql.h" +#include "sqlext.h" + + +#include "userInterface.h" +#include "userHandle.h" + +/*************************************************************** +* L O C A L C O N S T A N T S * +***************************************************************/ + +/*************************************************************** +* L O C A L D A T A S T R U C T U R E S * +***************************************************************/ + +/*************************************************************** +* L O C A L F U N C T I O N S * +***************************************************************/ + +static int readSubscriberSessions(UserHandle *uh, + SubscriberNumber number, + char *transactionType); + +/*************************************************************** +* L O C A L D A T A * +***************************************************************/ + +extern void handle_error(SQLHDBC hdbc, + SQLHENV henv, + SQLHSTMT hstmt, + SQLRETURN rc, + char *filename, + int lineno); + +/*************************************************************** +* P U B L I C D A T A * +***************************************************************/ + + +/*************************************************************** +**************************************************************** +* L O C A L F U N C T I O N S C O D E S E C T I O N * +**************************************************************** +***************************************************************/ + +static int readSubscriberSessions(UserHandle *uh, + SubscriberNumber number, + char *transactionType) +{ + SQLRETURN rc; + + /*-----------------------------------------------------*/ + /* SELECT activeSessions,groupId,changedBy,changedTime */ + /* FROM SUBSCRIBER */ + /* WHERE subscriberNumber=x; */ + /*-----------------------------------------------------*/ + strcpy(uh->readSubscriberSession.values.number,number); + + rc = SQLExecute(uh->readSubscriberSession.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("%s %s\n", + transactionType, + "Unable to execute read subscriber session"); + return(-1); + } + + rc = SQLFetch(uh->readSubscriberSession.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("%s %s\n", + transactionType, + "Unable to fetch read subscriber session"); + return(-1); + } + + return(0); +} + +/*************************************************************** +**************************************************************** +* P U B L I C F U N C T I O N S C O D E S E C T I O N * +**************************************************************** +***************************************************************/ + +void userTransaction_T1(UserHandle *uh, + SubscriberNumber number, + Location new_location, + ChangedBy changed_by, + ChangedTime changed_time) +{ + SQLRETURN rc; + + if(!uh) return; + + /*---------------------------------------------*/ + /* Update the subscriber information */ + /* */ + /* UPDATE SUBSCRIBER */ + /* SET location=x, changedBy=x, changedTime=x */ + /* WHERE subscriberNumber=x; */ + /*---------------------------------------------*/ + strcpy(uh->updateSubscriber.values.number, number); + uh->updateSubscriber.values.location = new_location; + strcpy(uh->updateSubscriber.values.changedBy, changed_by); + strcpy(uh->updateSubscriber.values.changedTime, changed_time); + + rc = SQLExecute(uh->updateSubscriber.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T1 Unable to execute update subscriber\n"); + return; + } + + userDbCommit(uh); +} + +void userTransaction_T2(UserHandle *uh, + SubscriberNumber number, + Location *new_location, + ChangedBy changed_by, + ChangedTime changed_time, + SubscriberName subscriberName) +{ + SQLRETURN rc; + + if(!uh) return; + + /*------------------------------------------------------*/ + /* Read the information from the subscriber table */ + /* */ + /* SELECT location,subscriberName,changedBy,changedTime */ + /* FROM SUBSCRIBER */ + /* WHERE subscriberNumber=x; */ + /*------------------------------------------------------*/ + strcpy(uh->readSubscriber.values.number,number); + + rc = SQLExecute(uh->readSubscriber.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T2 Unable to execute read subscriber\n"); + return; + } + + rc = SQLFetch(uh->readSubscriber.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T2 Unable to fetch read subscriber\n"); + return; + } + + userDbCommit(uh); + + strcpy(subscriberName, uh->readSubscriber.values.name); + *new_location = uh->readSubscriber.values.location; + strcpy(changed_by, uh->readSubscriber.values.changedBy); + strcpy(changed_time, uh->readSubscriber.values.changedTime); +} + +void userTransaction_T3(UserHandle *uh, + SubscriberNumber number, + ServerId server_id, + ServerBit server_bit, + SessionDetails session_details, + unsigned int *branch_executed) +{ + SQLRETURN rc; + + if(!uh) return; + + *branch_executed = 0; + + /*--------------------------------------*/ + /* Read active sessions from subscriber */ + /*--------------------------------------*/ + if( readSubscriberSessions(uh, number, "T3") < 0 ) + return; + + /*-----------------------------------------------*/ + /* Read the 'read' Permissions for the userGroup */ + /* */ + /* SELECT allowRead */ + /* FROM USERGROUP */ + /* WHERE groupId=x */ + /*-----------------------------------------------*/ + uh->readGroupAllowRead.values.groupId = uh->readSubscriberSession.values.groupId; + + rc = SQLExecute(uh->readGroupAllowRead.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T3 Unable to execute read group allow read\n"); + return; + } + + rc = SQLFetch(uh->readGroupAllowRead.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T3 Unable to fetch read group allow read\n"); + return; + } + + if( uh->readGroupAllowRead.values.allowRead & server_bit && + uh->readSubscriberSession.values.activeSessions & server_bit ) { + + /*----------------------------------------------------*/ + /* Read the sessionDetails from the userSession table */ + /* */ + /* SELECT sessionData */ + /* FROM userSession */ + /* WHERE subscriberNumber=x, serverId=x */ + /*----------------------------------------------------*/ + strcpy(uh->readSessionDetails.values.number,number); + uh->readSessionDetails.values.serverId = server_id; + + rc = SQLExecute(uh->readSessionDetails.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T3 Unable to execute read session details\n"); + return; + } + + rc = SQLFetch(uh->readSessionDetails.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T3 Unable to fetch read session details\n"); + return; + } + + strcpy(session_details, uh->readSessionDetails.values.details); + + /*----------------------------------------*/ + /* Increment noOfRead field in the server */ + /* */ + /* UPDATE server */ + /* SET noOfRead=noOfRead+1 */ + /* WHERE serverId=x,subscriberSuffix=x */ + /*----------------------------------------*/ + uh->updateServerNoOfRead.values.serverId = server_id; + strcpy(uh->updateServerNoOfRead.values.suffix, + &number[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH]); + + rc = SQLExecute(uh->updateServerNoOfRead.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T3 Unable to execute read no of read\n"); + return; + } + + *branch_executed = 1; + } + + userDbCommit(uh); +} + +void userTransaction_T4(UserHandle *uh, + SubscriberNumber number, + ServerId server_id, + ServerBit server_bit, + SessionDetails session_details, + unsigned int do_rollback, + unsigned int *branch_executed) +{ + SQLRETURN rc; + + if(!uh) return; + + *branch_executed = 0; + + /*--------------------------------------*/ + /* Read active sessions from subscriber */ + /*--------------------------------------*/ + if( readSubscriberSessions(uh, number, "T4") < 0 ) + return; + + /*-------------------------------------------------*/ + /* Read the 'insert' Permissions for the userGroup */ + /* */ + /* SELECT allowInsert */ + /* FROM USERGROUP */ + /* WHERE groupId=x */ + /*-------------------------------------------------*/ + uh->readGroupAllowInsert.values.groupId = uh->readSubscriberSession.values.groupId; + + rc = SQLExecute(uh->readGroupAllowInsert.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T4 Unable to execute read group allow insert\n"); + return; + } + + rc = SQLFetch(uh->readGroupAllowInsert.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T4 Unable to fetch read group allow insert\n"); + return; + } + + if( uh->readGroupAllowInsert.values.allowInsert & server_bit && + !(uh->readSubscriberSession.values.activeSessions & server_bit) ) { + + /*---------------------------------------------*/ + /* Insert the session to the userSession table */ + /* */ + /* INSERT INTO userSession */ + /* VALUES (x,x,x) */ + /*---------------------------------------------*/ + strcpy(uh->insertSession.values.number, number); + uh->insertSession.values.serverId = server_id; + strcpy(uh->insertSession.values.details, session_details); + + rc = SQLExecute(uh->insertSession.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { +handle_error(uh->hdbc, uh->henv, uh->insertSession.stmt, rc, __FILE__, __LINE__); + printf("T4 Unable to execute insert session \n"); + return; + } + + /*----------------------------------------*/ + /* Update subscriber activeSessions field */ + /* */ + /* UPDATE subscriber */ + /* SET activeSessions=x */ + /* WHERE subscriberNumber=x */ + /*----------------------------------------*/ + strcpy(uh->updateSubscriberSession.values.number, number); + uh->updateSubscriberSession.values.activeSessions = + uh->readSubscriberSession.values.activeSessions | server_bit; + + rc = SQLExecute(uh->updateSubscriberSession.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T4 Unable to execute update session \n"); + return; + } + + /*------------------------------------------*/ + /* Increment noOfInsert field in the server */ + /* */ + /* UPDATE server */ + /* SET noOfInsert=noOfInsert+1 */ + /* WHERE serverId=x,subscriberSuffix=x */ + /*------------------------------------------*/ + uh->updateServerNoOfInsert.values.serverId = server_id; + strcpy(uh->updateServerNoOfInsert.values.suffix, + &number[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH]); + + rc = SQLExecute(uh->updateServerNoOfInsert.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T4 Unable to execute update no of read\n"); + return; + } + + *branch_executed = 1; + } + + if(do_rollback) + userDbRollback(uh); + else + userDbCommit(uh); +} + +void userTransaction_T5(UserHandle *uh, + SubscriberNumber number, + ServerId server_id, + ServerBit server_bit, + unsigned int do_rollback, + unsigned int *branch_executed) +{ + SQLRETURN rc; + + if(!uh) return; + + *branch_executed = 0; + + /*--------------------------------------*/ + /* Read active sessions from subscriber */ + /*--------------------------------------*/ + if( readSubscriberSessions(uh, number, "T5") < 0 ) + return; + + /*-------------------------------------------------*/ + /* Read the 'delete' Permissions for the userGroup */ + /* */ + /* SELECT allowDelete */ + /* FROM USERGROUP */ + /* WHERE groupId=x */ + /*-------------------------------------------------*/ + uh->readGroupAllowDelete.values.groupId = uh->readSubscriberSession.values.groupId; + + rc = SQLExecute(uh->readGroupAllowDelete.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T5 Unable to execute read group allow delete\n"); + return; + } + + rc = SQLFetch(uh->readGroupAllowDelete.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T5 Unable to fetch read group allow delete\n"); + return; + } + + if( uh->readGroupAllowDelete.values.allowDelete & server_bit && + uh->readSubscriberSession.values.activeSessions & server_bit ) { + + /*-----------------------------------------------*/ + /* Delete the session from the userSession table */ + /* */ + /* DELETE FROM userSession */ + /* WHERE subscriberNumber=x,serverId=x */ + /*-----------------------------------------------*/ + strcpy(uh->deleteSession.values.number,number); + uh->deleteSession.values.serverId = server_id; + + rc = SQLExecute(uh->deleteSession.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T5 Unable to execute delete session\n"); + return; + } + + /*----------------------------------------*/ + /* Update subscriber activeSessions field */ + /* */ + /* UPDATE subscriber */ + /* SET activeSessions=x */ + /* WHERE subscriberNumber=x */ + /*----------------------------------------*/ + strcpy(uh->updateSubscriberSession.values.number, number); + uh->updateSubscriberSession.values.activeSessions = + uh->readSubscriberSession.values.activeSessions & ~server_bit; + + rc = SQLExecute(uh->updateSubscriberSession.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T5 Unable to execute update subscriber session \n"); + return; + } + + /*------------------------------------------*/ + /* Increment noOfDelete field in the server */ + /* */ + /* UPDATE server */ + /* SET noOfDelete=noOfDelete+1 */ + /* WHERE serverId=x,subscriberSuffix=x */ + /*------------------------------------------*/ + uh->updateServerNoOfDelete.values.serverId = server_id; + strcpy(uh->updateServerNoOfDelete.values.suffix, + &number[SUBSCRIBER_NUMBER_LENGTH-SUBSCRIBER_NUMBER_SUFFIX_LENGTH]); + + rc = SQLExecute(uh->updateServerNoOfDelete.stmt); + if( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) { + printf("T5 Unable to execute update no of delete\n"); + return; + } + + *branch_executed = 1; + } + + if(do_rollback) + userDbRollback(uh); + else + userDbCommit(uh); +} + + diff --git a/ndb/test/ndbapi/old_dirs/restarter/Makefile b/ndb/test/ndbapi/old_dirs/restarter/Makefile new file mode 100644 index 00000000000..041fbfd82ba --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/restarter/Makefile @@ -0,0 +1,11 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := restarter + +# Source files of non-templated classes (.C files) +SOURCES = restarter.cpp + +include $(NDB_TOP)/Epilogue.mk + diff --git a/ndb/test/ndbapi/old_dirs/restarter2/Makefile b/ndb/test/ndbapi/old_dirs/restarter2/Makefile new file mode 100644 index 00000000000..ba33a2e21dc --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/restarter2/Makefile @@ -0,0 +1,11 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := restarter2 + +# Source files of non-templated classes (.C files) +SOURCES = restarter2.cpp + +include $(NDB_TOP)/Epilogue.mk + diff --git a/ndb/test/ndbapi/old_dirs/restarts/Makefile b/ndb/test/ndbapi/old_dirs/restarts/Makefile new file mode 100644 index 00000000000..9f14b81fae5 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/restarts/Makefile @@ -0,0 +1,11 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := restarts + +# Source files of non-templated classes (.C files) +SOURCES = restarts.cpp + +include $(NDB_TOP)/Epilogue.mk + diff --git a/ndb/test/ndbapi/old_dirs/ronja/Makefile b/ndb/test/ndbapi/old_dirs/ronja/Makefile new file mode 100644 index 00000000000..a11a27c5fd7 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/ronja/Makefile @@ -0,0 +1,6 @@ +include .defs.mk + +DIRS = initronja \ + benchronja + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/ronja/benchronja/Makefile b/ndb/test/ndbapi/old_dirs/ronja/benchronja/Makefile new file mode 100644 index 00000000000..f0521c3ba77 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/ronja/benchronja/Makefile @@ -0,0 +1,10 @@ +include .defs.mk + +TYPE := ndbapitest + + +BIN_TARGET := benchronja + +SOURCES := benchronja.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/ronja/initronja/Makefile b/ndb/test/ndbapi/old_dirs/ronja/initronja/Makefile new file mode 100644 index 00000000000..dd66dd813d1 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/ronja/initronja/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := initronja + +SOURCES := initronja.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/telco/Makefile b/ndb/test/ndbapi/old_dirs/telco/Makefile new file mode 100644 index 00000000000..8f82c714119 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/telco/Makefile @@ -0,0 +1,10 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := telco + +# Source files of non-templated classes (.C files) +SOURCES = msa.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/telco/readme b/ndb/test/ndbapi/old_dirs/telco/readme new file mode 100644 index 00000000000..627b4256eef --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/telco/readme @@ -0,0 +1,9 @@ + +adoInsertRecs.cpp - the original evaluation program + +InsertRecs.cpp - replaced ado with ndb api, still windows only + +msa.cpp - removed windows and exceptions, portable + + + diff --git a/ndb/test/ndbapi/old_dirs/testBackup/Makefile b/ndb/test/ndbapi/old_dirs/testBackup/Makefile new file mode 100644 index 00000000000..ce0e404803c --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/testBackup/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE = ndbapitest + +BIN_TARGET = testBackup +BIN_TARGET_LIBS += bank +SOURCES = testBackup.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/testBasic/Makefile b/ndb/test/ndbapi/old_dirs/testBasic/Makefile new file mode 100644 index 00000000000..755b19939cb --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/testBasic/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := testBasic + +SOURCES := testBasic.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/testBlobs/Makefile b/ndb/test/ndbapi/old_dirs/testBlobs/Makefile new file mode 100644 index 00000000000..cc5bb629c17 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/testBlobs/Makefile @@ -0,0 +1,11 @@ +include .defs.mk + +TYPE = ndbapitest + +BIN_TARGET = testBlobs + +SOURCES = testBlobs.cpp + +include $(NDB_TOP)/Epilogue.mk + +CCFLAGS_LOC += -I$(NDB_TOP)/include/kernel diff --git a/ndb/test/ndbapi/old_dirs/testDataBuffers/Makefile b/ndb/test/ndbapi/old_dirs/testDataBuffers/Makefile new file mode 100644 index 00000000000..181fbc829d4 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/testDataBuffers/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE = ndbapitest + +BIN_TARGET = testDataBuffers + +SOURCES = testDataBuffers.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/testDict/Makefile b/ndb/test/ndbapi/old_dirs/testDict/Makefile new file mode 100644 index 00000000000..75d493c3424 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/testDict/Makefile @@ -0,0 +1,11 @@ +include .defs.mk + +TYPE = ndbapitest + +BIN_TARGET = testDict + +SOURCES = testDict.cpp + +CFLAGS_testDict.cpp := -I$(call fixpath,$(NDB_TOP)/include/kernel) + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/testGrep/Makefile b/ndb/test/ndbapi/old_dirs/testGrep/Makefile new file mode 100644 index 00000000000..34fdd7113d0 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/testGrep/Makefile @@ -0,0 +1,10 @@ +include .defs.mk + +TYPE = ndbapitest +DIRS = verify +BIN_TARGET = testGrep +BIN_TARGET_LIBS += bank +SOURCES = testGrep.cpp + +include $(NDB_TOP)/Epilogue.mk + diff --git a/ndb/test/ndbapi/old_dirs/testGrep/verify/Makefile b/ndb/test/ndbapi/old_dirs/testGrep/verify/Makefile new file mode 100644 index 00000000000..4e6182de6b2 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/testGrep/verify/Makefile @@ -0,0 +1,11 @@ +include .defs.mk + +TYPE = ndbapitest + +BIN_TARGET = testGrepVerify +BIN_TARGET_LIBS += bank +SOURCES = testGrepVerify.cpp + +CFLAGS_testGrepVerify.cpp += -I$(call fixpath,$(NDB_TOP)/include/kernel) -I$(call fixpath,$(NDB_TOP)/include/mgmcommon) + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/testIndex/Makefile b/ndb/test/ndbapi/old_dirs/testIndex/Makefile new file mode 100644 index 00000000000..e5cd4542c9c --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/testIndex/Makefile @@ -0,0 +1,11 @@ +include .defs.mk + +TYPE = ndbapitest + +BIN_TARGET = testIndex + +SOURCES = testIndex.cpp + +CFLAGS_testIndex.cpp := -I$(call fixpath,$(NDB_TOP)/include/kernel) + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/testInterpreter/Makefile b/ndb/test/ndbapi/old_dirs/testInterpreter/Makefile new file mode 100644 index 00000000000..e84287a1b16 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/testInterpreter/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE = ndbapitest + +BIN_TARGET = testInterpreter + +SOURCES = testInterpreter.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/testMgm/Makefile b/ndb/test/ndbapi/old_dirs/testMgm/Makefile new file mode 100644 index 00000000000..be50d3dae7e --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/testMgm/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE = ndbapitest + +BIN_TARGET = testMgm + +SOURCES = testMgm.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/testNdbApi/Makefile b/ndb/test/ndbapi/old_dirs/testNdbApi/Makefile new file mode 100644 index 00000000000..3bb3cba427e --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/testNdbApi/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE = ndbapitest + +BIN_TARGET = testNdbApi + +SOURCES = testNdbApi.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/testNodeRestart/Makefile b/ndb/test/ndbapi/old_dirs/testNodeRestart/Makefile new file mode 100644 index 00000000000..8c13ab3beb4 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/testNodeRestart/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE = ndbapitest + +BIN_TARGET = testNodeRestart + +SOURCES = testNodeRestart.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/testOIBasic/Makefile b/ndb/test/ndbapi/old_dirs/testOIBasic/Makefile new file mode 100644 index 00000000000..1bbbcf1d17e --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/testOIBasic/Makefile @@ -0,0 +1,13 @@ +include .defs.mk + +TYPE = ndbapitest + +BIN_TARGET = testOIBasic + +SOURCES = testOIBasic.cpp + +ifeq ($(NDB_COMPILER),GCC) +CCFLAGS_WARNINGS += -Wno-unused -Wformat +endif + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/testOIBasic/times.txt b/ndb/test/ndbapi/old_dirs/testOIBasic/times.txt new file mode 100644 index 00000000000..641e9ddb4bf --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/testOIBasic/times.txt @@ -0,0 +1,8 @@ +one db-node +testOIBasic -case t -table 1 -index 1 -fragtype small -threads 10 -rows 5000 -subloop 1 +------------------------------------------------------------ +040331 +build index - 5769 ms per 50000 ( 115 ms per 1000 ) +update - 5962 ms per 50000 ( 119 ms per 1000 ) +update indexed - 14851 ms per 50000 ( 297 ms per 1000 ) +overhead - 149 pct diff --git a/ndb/test/ndbapi/old_dirs/testOperations/Makefile b/ndb/test/ndbapi/old_dirs/testOperations/Makefile new file mode 100644 index 00000000000..25546ade639 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/testOperations/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := testOperations + +SOURCES := testOperations.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/testOrderedIndex/Makefile b/ndb/test/ndbapi/old_dirs/testOrderedIndex/Makefile new file mode 100644 index 00000000000..d8899a37895 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/testOrderedIndex/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE = ndbapitest + +BIN_TARGET = testOrderedIndex + +SOURCES = testOrderedIndex.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/testRestartGci/Makefile b/ndb/test/ndbapi/old_dirs/testRestartGci/Makefile new file mode 100644 index 00000000000..24f449b747d --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/testRestartGci/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := testRestartGci + +SOURCES := testRestartGci.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/testScan/Makefile b/ndb/test/ndbapi/old_dirs/testScan/Makefile new file mode 100644 index 00000000000..fe48f5bc926 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/testScan/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE = ndbapitest + +BIN_TARGET = testScan + +SOURCES = testScan.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/testScanInterpreter/Makefile b/ndb/test/ndbapi/old_dirs/testScanInterpreter/Makefile new file mode 100644 index 00000000000..c7d96494148 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/testScanInterpreter/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE = ndbapitest + +BIN_TARGET = testScanInterpreter + +SOURCES = testScanInterpreter.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/testSystemRestart/Makefile b/ndb/test/ndbapi/old_dirs/testSystemRestart/Makefile new file mode 100644 index 00000000000..7a306eb313d --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/testSystemRestart/Makefile @@ -0,0 +1,11 @@ +include .defs.mk + +TYPE = ndbapitest + +BIN_TARGET = testSystemRestart + +SOURCES = testSystemRestart.cpp + +CFLAGS_testSystemRestart.cpp := -I$(call fixpath,$(NDB_TOP)/include/kernel) + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/testTimeout/Makefile b/ndb/test/ndbapi/old_dirs/testTimeout/Makefile new file mode 100644 index 00000000000..01a9df9887f --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/testTimeout/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE = ndbapitest + +BIN_TARGET = testTimeout + +SOURCES = testTimeout.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/testTransactions/Makefile b/ndb/test/ndbapi/old_dirs/testTransactions/Makefile new file mode 100644 index 00000000000..0279a526923 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/testTransactions/Makefile @@ -0,0 +1,10 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := testTransactions + +SOURCES := testTransactions.cpp +CFLAGS_testTransactions.cpp := -I$(call fixpath,$(NDB_TOP)/include/kernel) + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/test_event/Makefile b/ndb/test/ndbapi/old_dirs/test_event/Makefile new file mode 100644 index 00000000000..6299fa47845 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/test_event/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := test_event + +SOURCES := test_event.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/vw_test/Makefile b/ndb/test/ndbapi/old_dirs/vw_test/Makefile new file mode 100644 index 00000000000..144873dcc69 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/vw_test/Makefile @@ -0,0 +1,11 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := vw_test +BIN_TARGET_LIBS := orafunctr decode cirk inifunc +BIN_TARGET_LIBS_DIRS := /home/ndb/junk/vw/ndb/lib + +SOURCES := cdrserver.C + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/vw_test/bcd.h b/ndb/test/ndbapi/old_dirs/vw_test/bcd.h new file mode 100644 index 00000000000..d0aaffbd8b7 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/vw_test/bcd.h @@ -0,0 +1,26 @@ +/* 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 */ + +#include + +struct bcdtab { + char tab[3]; +}; + +int dec2hex(int dec,int last); +int bcd_code (char *bcd_in,char *bcd_out); +int bcd_decode (int bcd_len,char *bcd_in,char *bcd_out); +int bcd_decode2 (int bcd_len,char *bcd_in,char *bcd_out); diff --git a/ndb/test/ndbapi/old_dirs/vw_test/script/client_start b/ndb/test/ndbapi/old_dirs/vw_test/script/client_start new file mode 100644 index 00000000000..2965be6fbb5 --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/vw_test/script/client_start @@ -0,0 +1,10 @@ +# Argument to the client program is: +# 1. ip-adress to the server +# 2. location to the raw cdr-file +# 3. nanoseconds (0-1000) between writing the buffer to the port +# 4. how many writes to the buffer before the sleep command should accur +# Argument 3 and 4 controlls the flow of the raw cdr-file to the cdrserver + +cd $VCDRPATH/bin +# ./client stat181.xxx.com /ext06/data/indata_fraud1/port2file.data.-2089540139 1000 0 & +./client xxx.xxx.xxx.xxx.xxx /export2/home/ndb/vw/data/port2file_data_-2089540139 0 100000 & diff --git a/ndb/test/ndbapi/old_dirs/vw_test/utv.h b/ndb/test/ndbapi/old_dirs/vw_test/utv.h new file mode 100644 index 00000000000..6f378e5595b --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/vw_test/utv.h @@ -0,0 +1,161 @@ +/* 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 */ + +#include +#include +#include + +#define TESTLEV + +#define ASubscriberNumber_SIZE 16 +#define BSubscriberNumber_SIZE 29 +#define TRUE 1 +#define FALSE 0 +#define WRITE_LIMIT 100000 +#define EVER ;; +#define CONNINFO "/" +#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) + +#define BIT_1 0x1 +#define BIT_2 0x2 +#define BIT_3 0x4 +#define BIT_4 0x8 +#define BIT_5 0x10 +#define BIT_6 0x20 +#define BIT_7 0x40 +#define BIT_8 0x80 + +/*------------------------------------------------------*/ +/* record defines structure over an alarm thresholds */ +/* CallAttemptState Beskriver status på samtal */ +/* 0 - Subscriber is calling */ +/* 1 - Called part answer call */ +/* 2 - Release of call */ +/* 3-255 reserved for furter use */ +/* USED_FILEDS Indicates active fields within call */ +/* bit 1 - START_TIME */ +/* 2 - TimeForStartOfCharge */ +/* 3 - TimeForStopOfCharge */ +/* 4 - ReroutingIndicator */ +/* 5 - RINParameter */ +/* 6 - ACategory */ +/* 7 - EndOfSelectionInformation */ +/* 8 - UserToUserIndicatior */ +/* 9 - UserToUserInformation */ +/* 10 - CauseCode */ +/* 11 - ASubscriberNumber */ +/* 12 - BSubscriberNumber */ +/* 13 - RedirectingNumber */ +/* 14 - OriginalCalledNumber */ +/* 15 - LocationCode */ +/* 16 - OriginatingPointCode */ +/* 17 - DestinationPointCode */ +/* 18 - CircuitIdentificationCode */ +/* 19 - NetworkIndicator */ +/*------------------------------------------------------*/ + +struct cdr_record +{ + unsigned int USED_FIELDS; + unsigned long ClientId; + unsigned int CallIdentificationNumber; + unsigned int START_TIME; + unsigned int OurSTART_TIME; + unsigned int TimeForStartOfCharge; + unsigned int TimeForStopOfCharge; + time_t OurTimeForStartOfCharge; + time_t OurTimeForStopOfCharge; + unsigned short DestinationPointCode; + unsigned short CircuitIdentificationCode; + unsigned short OriginatingPointCode; + unsigned short ReroutingIndicator; + unsigned short RINParameter; + char NetworkIndicator; + char CallAttemptState; + char ACategory; + char EndOfSelectionInformation; + char UserToUserInformation; + char UserToUserIndicatior; + char CauseCode; + char ASubscriberNumber[ASubscriberNumber_SIZE]; + char ASubscriberNumberLength; + char TonASubscriberNumber; + char BSubscriberNumber[BSubscriberNumber_SIZE]; + char BSubscriberNumberLength; + char TonBSubscriberNumber; + char RedirectingNumber[16]; + char TonRedirectingNumber; + char OriginalCalledNumber[16]; + char TonOriginalCalledNumber; + char LocationCode[16]; + char TonLocationCode; +}; + +/*------------------------------------------------------*/ +/* Define switches for each tag */ +/*------------------------------------------------------*/ + +#define B_START_TIME 0x1 +#define B_TimeForStartOfCharge 0x2 +#define B_TimeForStopOfCharge 0x4 +#define B_ReroutingIndicator 0x8 +#define B_RINParameter 0x10 +#define B_ACategory 0x20 +#define B_EndOfSelectionInformation 0x40 +#define B_UserToUserIndicatior 0x80 +#define B_UserToUserInformation 0x100 +#define B_CauseCode 0x200 +#define B_ASubscriberNumber 0x400 +#define B_BSubscriberNumber 0x800 +#define B_RedirectingNumber 0x1000 +#define B_OriginalCalledNumber 0x2000 +#define B_LocationCode 0x4000 +#define B_OriginatingPointCode 0x8000 +#define B_DestinationPointCode 0x10000 +#define B_CircuitIdentificationCode 0x20000 + +#define B_NetworkIndicator 0x40000 +#define B_TonASubscriberNumber 0x80000 +#define B_TonBSubscriberNumber 0x100000 +#define B_TonRedirectingNumber 0x200000 +#define B_TonOriginalCalledNumber 0x4000000 +#define B_TonLocationCode 0x8000000 + +#define K_START_TIME 0xFF01 +#define K_TimeForStartOfCharge 0xFF02 +#define K_TimeForStopOfCharge 0xFF03 +#define K_ReroutingIndicator 0x13 +#define K_RINParameter 0xFC +#define K_ACategory 0x09 +#define K_EndOfSelectionInformation 0x11 +#define K_UserToUserIndicatior 0x2A +#define K_UserToUserInformation 0x20 +#define K_CauseCode 0x12 +#define K_ASubscriberNumber 0x0A +#define K_BSubscriberNumber 0x04 +#define K_RedirectingNumber 0x0B +#define K_OriginalCalledNumber 0x28 +#define K_LocationCode 0x3F +#define K_OriginatingPointCode 0xFD +#define K_DestinationPointCode 0xFE +#define K_CircuitIdentificationCode 0xFF + +#define K_NetworkIndicator 0xF0 +#define K_TonASubscriberNumber 0xF1 +#define K_TonBSubscriberNumber 0xF2 +#define K_TonRedirectingNumber 0xF3 +#define K_TonOriginalCalledNumber 0xF4 +#define K_TonLocationCode 0xF5 diff --git a/ndb/test/ndbapi/old_dirs/vw_test/vcdrfunc.h b/ndb/test/ndbapi/old_dirs/vw_test/vcdrfunc.h new file mode 100644 index 00000000000..3c5444d733b --- /dev/null +++ b/ndb/test/ndbapi/old_dirs/vw_test/vcdrfunc.h @@ -0,0 +1,55 @@ +/* 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 */ + +/********************************************************/ +/* Common functions */ +/* unix_ps checks if a process is running with a */ +/* name and pid rc 0=not running */ +/* 1=Running */ +/* logname create a log filename */ +/* Parm */ +/* 1 lvl1 name */ +/* 2 lvl2 name */ +/* 3 lvl3 name */ +/* m2log Skriv log rader som moder */ +/* Parm */ +/* 1 pointer to filehandler */ +/* 2 Log text max 600 tecken */ +/* c2log Skriv log rader som barn */ +/* Parm */ +/* 1 pointer to filehandler */ +/* 2 Log text max 600 tecken */ +/* n2log Skriv log rader utan relation */ +/* Parm */ +/* 1 pointer to filehandler */ +/* 2 Log text max 600 tecken */ +/********************************************************/ + +int n2log(FILE *fi,char *text); +int m2log(FILE *fi,char *text); +int c2log(FILE *fi,char *text); +int checkchangelog(FILE* fp,char *filename); +void logname(char *filename, char *lvl1, char *lvl2, char *lvl3); +void logname_unique_day(char *filename, char *lvl1, char *lvl2, char *lvl3); +int unix_ps(char *proc_name,char *pid); +/* +int unix_ps2(char *proc_name,char *pid); +*/ +int unix_ps3(char *proc_name); +int replacetoken(const char* instring,char token,char replace); +int CompAsciiNum(char *, char *); +int CompareIt(char *,char *); +int CompCdrNum(const void *,const void *,void *); diff --git a/ndb/test/ndbapi/restarter.cpp b/ndb/test/ndbapi/restarter.cpp new file mode 100644 index 00000000000..9a522f5dcac --- /dev/null +++ b/ndb/test/ndbapi/restarter.cpp @@ -0,0 +1,129 @@ +/* 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 */ + + +#include "mgmapi.h" +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +int main(int argc, const char** argv){ + + const char* _hostName = NULL; + int _loops = 10; + int _wait = 15; + int _help = 0; + int _error_insert = 0; + int _initial = 0; + int _master = 0; + int _maxwait = 120; + int _multiple = 0; + + struct getargs args[] = { + { "seconds", 's', arg_integer, &_wait, + "Seconds to wait between each restart(0=random)", "secs" }, + { "max seconds", 'm', arg_integer, &_maxwait, + "Max seconds to wait between each restart. Default is 120 seconds", + "msecs" }, + { "loops", 'l', arg_integer, &_loops, + "Number of loops(0=forever)", "loops"}, + { "initial", 'i', arg_flag, &_initial, "Initial node restart"}, + { "error-insert", 'e', arg_flag, &_error_insert, "Use error insert"}, + { "master", 'm', arg_flag, &_master, + "Restart the master"}, + { "multiple", 'x', arg_flag, &_multiple, + "Multiple random node restarts. OBS! Even and odd node Ids must be separated into each node group"}, + { "usage", '?', arg_flag, &_help, "Print help", "" } + + }; + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + char desc[] = + "hostname:port\n"\ + "This program will connect to the mgmsrv of a NDB cluster.\n"\ + "It will then wait for all nodes to be started, then restart node(s)\n"\ + "and wait for all to restart inbetween. It will do this \n"\ + "loop number of times\n"; + + if(getarg(args, num_args, argc, argv, &optind) || _help) { + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + _hostName = argv[optind]; + + + NdbRestarts restarts(_hostName); + NdbRestarter restarter(_hostName); + + const char* restartName = ""; + if (_multiple){ + if (_master){ + restartName = "TwoMasterNodeFailure"; + } + else { + // Restart 50 percent of nodes + restartName = "FiftyPercentFail"; + } + } + else if (_master){ + restartName = "RestartMasterNodeError"; + }else { + if (_error_insert) + restartName = "RestartRandomNodeError"; + else if (_initial) + restartName = "RestartRandomNodeInitial"; + else + restartName = "RestartRandomNode"; + } + + ndbout << "Performing " << restartName << endl; + + int result = NDBT_OK; + int l = 0; + while (_loops == 0 || l<_loops){ + + g_info << "Waiting for cluster to start" << endl; + while (restarter.waitClusterStarted(1) != 0){ + //g_warning << "Ndb failed to start in 2 minutes" << endl; + } + + int seconds = _wait; + if(seconds==0) { + // Create random value, default 120 secs + seconds = (rand() % _maxwait) + 1; + } + g_info << "Waiting for " << seconds << "(" << _maxwait + << ") secs " << endl; + NdbSleep_SecSleep(seconds); + + g_info << l << ": Restarting node(s) " << endl; + + if (restarts.executeRestart(restartName) != 0){ + result = NDBT_FAILED; + break; + } + + l++; + } + return NDBT_ProgramExit(NDBT_OK); +} diff --git a/ndb/test/ndbapi/restarter/Makefile b/ndb/test/ndbapi/restarter/Makefile deleted file mode 100644 index 041fbfd82ba..00000000000 --- a/ndb/test/ndbapi/restarter/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := restarter - -# Source files of non-templated classes (.C files) -SOURCES = restarter.cpp - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/test/ndbapi/restarter/restarter.cpp b/ndb/test/ndbapi/restarter/restarter.cpp deleted file mode 100644 index 9a522f5dcac..00000000000 --- a/ndb/test/ndbapi/restarter/restarter.cpp +++ /dev/null @@ -1,129 +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 */ - - -#include "mgmapi.h" -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -int main(int argc, const char** argv){ - - const char* _hostName = NULL; - int _loops = 10; - int _wait = 15; - int _help = 0; - int _error_insert = 0; - int _initial = 0; - int _master = 0; - int _maxwait = 120; - int _multiple = 0; - - struct getargs args[] = { - { "seconds", 's', arg_integer, &_wait, - "Seconds to wait between each restart(0=random)", "secs" }, - { "max seconds", 'm', arg_integer, &_maxwait, - "Max seconds to wait between each restart. Default is 120 seconds", - "msecs" }, - { "loops", 'l', arg_integer, &_loops, - "Number of loops(0=forever)", "loops"}, - { "initial", 'i', arg_flag, &_initial, "Initial node restart"}, - { "error-insert", 'e', arg_flag, &_error_insert, "Use error insert"}, - { "master", 'm', arg_flag, &_master, - "Restart the master"}, - { "multiple", 'x', arg_flag, &_multiple, - "Multiple random node restarts. OBS! Even and odd node Ids must be separated into each node group"}, - { "usage", '?', arg_flag, &_help, "Print help", "" } - - }; - int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; - char desc[] = - "hostname:port\n"\ - "This program will connect to the mgmsrv of a NDB cluster.\n"\ - "It will then wait for all nodes to be started, then restart node(s)\n"\ - "and wait for all to restart inbetween. It will do this \n"\ - "loop number of times\n"; - - if(getarg(args, num_args, argc, argv, &optind) || _help) { - arg_printusage(args, num_args, argv[0], desc); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - _hostName = argv[optind]; - - - NdbRestarts restarts(_hostName); - NdbRestarter restarter(_hostName); - - const char* restartName = ""; - if (_multiple){ - if (_master){ - restartName = "TwoMasterNodeFailure"; - } - else { - // Restart 50 percent of nodes - restartName = "FiftyPercentFail"; - } - } - else if (_master){ - restartName = "RestartMasterNodeError"; - }else { - if (_error_insert) - restartName = "RestartRandomNodeError"; - else if (_initial) - restartName = "RestartRandomNodeInitial"; - else - restartName = "RestartRandomNode"; - } - - ndbout << "Performing " << restartName << endl; - - int result = NDBT_OK; - int l = 0; - while (_loops == 0 || l<_loops){ - - g_info << "Waiting for cluster to start" << endl; - while (restarter.waitClusterStarted(1) != 0){ - //g_warning << "Ndb failed to start in 2 minutes" << endl; - } - - int seconds = _wait; - if(seconds==0) { - // Create random value, default 120 secs - seconds = (rand() % _maxwait) + 1; - } - g_info << "Waiting for " << seconds << "(" << _maxwait - << ") secs " << endl; - NdbSleep_SecSleep(seconds); - - g_info << l << ": Restarting node(s) " << endl; - - if (restarts.executeRestart(restartName) != 0){ - result = NDBT_FAILED; - break; - } - - l++; - } - return NDBT_ProgramExit(NDBT_OK); -} diff --git a/ndb/test/ndbapi/restarter2.cpp b/ndb/test/ndbapi/restarter2.cpp new file mode 100644 index 00000000000..f2bcf6f8e7b --- /dev/null +++ b/ndb/test/ndbapi/restarter2.cpp @@ -0,0 +1,116 @@ +/* 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 */ + + +#include +#include +#include +#include +#include +#include + +#include +#include + +int main(int argc, const char** argv){ + + const char* _hostName = NULL; + int _loops = 10; + int _wait = 15; + int _help = 0; +#if 0 + int _crash = 0; + int _abort = 0; +#endif + + struct getargs args[] = { + { "seconds", 's', arg_integer, &_wait, "Seconds to wait between each restart(0=random)", "secs" }, + { "loops", 'l', arg_integer, &_loops, "Number of loops", "loops 0=forever"}, +#if 0 + // Not yet! + { "abort", 'a', arg_flag, &_abort, "Restart abort"}, + { "crash", 'c', arg_flag, &_crash, "Crash instead of restart"}, +#endif + { "usage", '?', arg_flag, &_help, "Print help", "" } + + }; + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + char desc[] = + "hostname:port\n"\ + "This program will connect to the mgmsrv of a NDB cluster.\n"\ + "It will wait for all nodes to be started, then restart all nodes\n"\ + "into nostart state. Then after a random delay it will tell all nodes\n"\ + "to start. It will do this loop number of times\n"; + + if(getarg(args, num_args, argc, argv, &optind) || _help) { + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + _hostName = argv[optind]; + + NdbRestarter restarter(_hostName); +#if 0 + if(_abort && _crash){ + g_err << "You can't specify both abort and crash" << endl; + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + if(_abort){ + restarter.setRestartType(NdbRestarter::AbortRestart); + } + if(_crash){ + restarter.setRestartType(NdbRestarter::Crash); + } +#endif + + int l = 0; + while (_loops == 0 || l<_loops){ + g_info << "Waiting for cluster to start" << endl; + while(restarter.waitClusterStarted(120) != 0){ + g_warning << "Ndb failed to start in 2 minutes" << endl; + } + + int seconds = _wait; + if(seconds==0) + seconds = (rand() % 120) + 1; // Create random value max 120 secs + g_info << "Waiting for "< -#include -#include -#include -#include -#include - -#include -#include - -int main(int argc, const char** argv){ - - const char* _hostName = NULL; - int _loops = 10; - int _wait = 15; - int _help = 0; -#if 0 - int _crash = 0; - int _abort = 0; -#endif - - struct getargs args[] = { - { "seconds", 's', arg_integer, &_wait, "Seconds to wait between each restart(0=random)", "secs" }, - { "loops", 'l', arg_integer, &_loops, "Number of loops", "loops 0=forever"}, -#if 0 - // Not yet! - { "abort", 'a', arg_flag, &_abort, "Restart abort"}, - { "crash", 'c', arg_flag, &_crash, "Crash instead of restart"}, -#endif - { "usage", '?', arg_flag, &_help, "Print help", "" } - - }; - int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; - char desc[] = - "hostname:port\n"\ - "This program will connect to the mgmsrv of a NDB cluster.\n"\ - "It will wait for all nodes to be started, then restart all nodes\n"\ - "into nostart state. Then after a random delay it will tell all nodes\n"\ - "to start. It will do this loop number of times\n"; - - if(getarg(args, num_args, argc, argv, &optind) || _help) { - arg_printusage(args, num_args, argv[0], desc); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - _hostName = argv[optind]; - - NdbRestarter restarter(_hostName); -#if 0 - if(_abort && _crash){ - g_err << "You can't specify both abort and crash" << endl; - arg_printusage(args, num_args, argv[0], desc); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - if(_abort){ - restarter.setRestartType(NdbRestarter::AbortRestart); - } - if(_crash){ - restarter.setRestartType(NdbRestarter::Crash); - } -#endif - - int l = 0; - while (_loops == 0 || l<_loops){ - g_info << "Waiting for cluster to start" << endl; - while(restarter.waitClusterStarted(120) != 0){ - g_warning << "Ndb failed to start in 2 minutes" << endl; - } - - int seconds = _wait; - if(seconds==0) - seconds = (rand() % 120) + 1; // Create random value max 120 secs - g_info << "Waiting for "< +#include +#include +#include +#include +#include + +#include +#include + +int main(int argc, const char** argv){ + + const char* _restartName = NULL; + int _loops = 1; + int _wait = -1; + int _maxwait = 120; + int _help = 0; + int _list = 0; + int _random = 0; + int _timeout = 0; + int _all = 0; + + struct getargs args[] = { + { "seconds", 's', arg_integer, &_wait, + "Seconds to wait between each restart(0=random)", "secs" }, + { "max seconds", 'm', arg_integer, &_maxwait, + "Max seconds to wait between each restart. Default is 120 seconds", "msecs" }, + { "loops", 'l', arg_integer, &_loops, "Number of loops(0=forever)", "loops"}, + { "timeout", 't', arg_integer, &_timeout, "Timeout waiting for nodes to start", "seconds"}, + { "random", 'r', arg_flag, &_random, "Select restart case randomly", + ""}, + { "all", 'a', arg_flag, &_all, "Run all restarts", + ""}, + { "list-restarts", '\0', arg_flag, &_list, "List available restarts", ""}, + { "usage", '?', arg_flag, &_help, "Print help", "" } + + }; + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + char desc[] = + "testname\n" \ + "This program will perform node restart, \n"\ + "multiple node restart or system-restart.\n"\ + "Use --list-restarts to see whats available\n"; + + if(getarg(args, num_args, argc, argv, &optind) || _help) { + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + + if (_list){ + NdbRestarts restarts; + restarts.listRestarts(); + return NDBT_ProgramExit(NDBT_OK); + } + + if ((argv[optind] == NULL) && (_random == 0)){ + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + _restartName = argv[optind]; + + NdbRestarts restarts; + + int res = NDBT_OK; + int l = 0; + while (_loops == 0 || l < _loops){ + + if (_all) { + // Execute all restarts, set loops to numRestarts + // so that ecvery restart is executed once + _loops = restarts.getNumRestarts(); + res = restarts.executeRestart(l, _timeout); + } else if (_random) { + int num = rand() % restarts.getNumRestarts(); + res = restarts.executeRestart(num, _timeout); + } else { + res = restarts.executeRestart(_restartName, _timeout); + } + if (res != NDBT_OK) + break; + + if (_wait >= 0){ + int seconds = _wait; + if(seconds==0) { + // Create random value, default 120 secs + seconds = (rand() % _maxwait) + 1; + } + g_info << "Waiting for " << seconds << "(" << _maxwait + << ") secs " << endl; + NdbSleep_SecSleep(seconds); + } + + l++; + } + return NDBT_ProgramExit(res); +} diff --git a/ndb/test/ndbapi/restarts/Makefile b/ndb/test/ndbapi/restarts/Makefile deleted file mode 100644 index 9f14b81fae5..00000000000 --- a/ndb/test/ndbapi/restarts/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := restarts - -# Source files of non-templated classes (.C files) -SOURCES = restarts.cpp - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/test/ndbapi/restarts/restarts.cpp b/ndb/test/ndbapi/restarts/restarts.cpp deleted file mode 100644 index 0ec2883d53c..00000000000 --- a/ndb/test/ndbapi/restarts/restarts.cpp +++ /dev/null @@ -1,115 +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 */ - - -#include "mgmapi.h" -#include -#include -#include -#include -#include -#include - -#include -#include - -int main(int argc, const char** argv){ - - const char* _restartName = NULL; - int _loops = 1; - int _wait = -1; - int _maxwait = 120; - int _help = 0; - int _list = 0; - int _random = 0; - int _timeout = 0; - int _all = 0; - - struct getargs args[] = { - { "seconds", 's', arg_integer, &_wait, - "Seconds to wait between each restart(0=random)", "secs" }, - { "max seconds", 'm', arg_integer, &_maxwait, - "Max seconds to wait between each restart. Default is 120 seconds", "msecs" }, - { "loops", 'l', arg_integer, &_loops, "Number of loops(0=forever)", "loops"}, - { "timeout", 't', arg_integer, &_timeout, "Timeout waiting for nodes to start", "seconds"}, - { "random", 'r', arg_flag, &_random, "Select restart case randomly", - ""}, - { "all", 'a', arg_flag, &_all, "Run all restarts", - ""}, - { "list-restarts", '\0', arg_flag, &_list, "List available restarts", ""}, - { "usage", '?', arg_flag, &_help, "Print help", "" } - - }; - int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; - char desc[] = - "testname\n" \ - "This program will perform node restart, \n"\ - "multiple node restart or system-restart.\n"\ - "Use --list-restarts to see whats available\n"; - - if(getarg(args, num_args, argc, argv, &optind) || _help) { - arg_printusage(args, num_args, argv[0], desc); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - - if (_list){ - NdbRestarts restarts; - restarts.listRestarts(); - return NDBT_ProgramExit(NDBT_OK); - } - - if ((argv[optind] == NULL) && (_random == 0)){ - arg_printusage(args, num_args, argv[0], desc); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - _restartName = argv[optind]; - - NdbRestarts restarts; - - int res = NDBT_OK; - int l = 0; - while (_loops == 0 || l < _loops){ - - if (_all) { - // Execute all restarts, set loops to numRestarts - // so that ecvery restart is executed once - _loops = restarts.getNumRestarts(); - res = restarts.executeRestart(l, _timeout); - } else if (_random) { - int num = rand() % restarts.getNumRestarts(); - res = restarts.executeRestart(num, _timeout); - } else { - res = restarts.executeRestart(_restartName, _timeout); - } - if (res != NDBT_OK) - break; - - if (_wait >= 0){ - int seconds = _wait; - if(seconds==0) { - // Create random value, default 120 secs - seconds = (rand() % _maxwait) + 1; - } - g_info << "Waiting for " << seconds << "(" << _maxwait - << ") secs " << endl; - NdbSleep_SecSleep(seconds); - } - - l++; - } - return NDBT_ProgramExit(res); -} diff --git a/ndb/test/ndbapi/ronja/Makefile b/ndb/test/ndbapi/ronja/Makefile deleted file mode 100644 index a11a27c5fd7..00000000000 --- a/ndb/test/ndbapi/ronja/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -include .defs.mk - -DIRS = initronja \ - benchronja - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/ronja/benchronja/Makefile b/ndb/test/ndbapi/ronja/benchronja/Makefile deleted file mode 100644 index f0521c3ba77..00000000000 --- a/ndb/test/ndbapi/ronja/benchronja/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - - -BIN_TARGET := benchronja - -SOURCES := benchronja.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/ronja/benchronja/benchronja.cpp b/ndb/test/ndbapi/ronja/benchronja/benchronja.cpp deleted file mode 100644 index ce0aee35e8f..00000000000 --- a/ndb/test/ndbapi/ronja/benchronja/benchronja.cpp +++ /dev/null @@ -1,1202 +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 */ - - -/* *************************************************** - NODEREC - Perform benchmark of insert, update and delete transactions - - Arguments: - -t Number of threads to start, default 1 - -o Number of loops per thread, default 100000 - - - * *************************************************** */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MAX_TIMERS 4 -#define MAXSTRLEN 16 -#define MAXATTR 64 -#define MAXTABLES 64 -#define MAXTHREADS 256 -#define MAXATTRSIZE 8000 -#define START_TIMER NdbTimer timer; timer.doStart(); -#define STOP_TIMER timer.doStop(); -#define START_TIMER_TOP NdbTimer timer_top; timer_top.doStart(); -#define STOP_TIMER_TOP timer_top.doStop(); - -void* ThreadExec(void*); -struct ThreadNdb -{ - int NoOfOps; - int ThreadNo; - Ndb* NdbRef; -}; - -static NdbThread* threadLife[MAXTHREADS]; -static unsigned int tNoOfThreads; -static unsigned int tNoOfOpsPerExecute; -static unsigned int tNoOfRecords; -static unsigned int tNoOfOperations; -static int ThreadReady[MAXTHREADS]; -static int ThreadStart[MAXTHREADS]; - -NDB_COMMAND(benchronja, "benchronja", "benchronja", "benchronja", 65535){ - - ThreadNdb tabThread[MAXTHREADS]; - int i = 0 ; - int cont = 0 ; - Ndb* pMyNdb = NULL ; //( "TEST_DB" ); - int tmp = 0 ; - int nTest = 0 ; - char inp[100] ; - - tNoOfThreads = 1; // Default Value - tNoOfOpsPerExecute = 1; // Default Value - tNoOfOperations = 100000; // Default Value - tNoOfRecords = 500 ; // Default Value 1) - { - if (strcmp(argv[i], "-t") == 0){ - tNoOfThreads = atoi(argv[i+1]); - if ((tNoOfThreads < 1) || (tNoOfThreads > MAXTHREADS)) goto error_input; - }else if (strcmp(argv[i], "-o") == 0){ - tNoOfOperations = atoi(argv[i+1]); - if (tNoOfOperations < 1) goto error_input; - }else if (strcmp(argv[i], "-r") == 0){ - tNoOfRecords = atoi(argv[i+1]); - if ((tNoOfRecords < 1) || (tNoOfRecords > 1000000000)) goto error_input; - }else if (strcmp(argv[i], "-p") == 0){ - nTest = atoi(argv[i+1]) ; - if (0 > nTest || 18 < nTest) goto error_input ; - }else if (strcmp(argv[i], "-c") == 0){ - tNoOfOpsPerExecute = atoi(argv[i+1]); - if ((tNoOfOpsPerExecute < 1) || (tNoOfOpsPerExecute > 1024)) goto error_input; - }else{ - goto error_input; - } - argc -= 2; - i = i + 2; - } - - ndbout << "Initialisation started. " << endl; - pMyNdb = new Ndb("TEST_DB") ; - pMyNdb->init(); - ndbout << "Initialisation completed. " << endl; - - ndbout << endl << "Execute Ronja Benchmark" << endl; - ndbout << " NdbAPI node with id = " << pMyNdb->getNodeId() << endl; - ndbout << " " << tNoOfThreads << " thread(s) " << endl; - ndbout << " " << tNoOfOperations << " transaction(s) per thread and round " << endl; - - if (pMyNdb->waitUntilReady(120) != 0) { - ndbout << "Benchmark failed - NDB is not ready" << endl; - delete pMyNdb ; - return NDBT_ProgramExit(NDBT_FAILED); - }//if - - NdbThread_SetConcurrencyLevel(2 + tNoOfThreads); - - for (i = 0; i < tNoOfThreads ; i++) { - ThreadReady[i] = 0; - ThreadStart[i] = 0; - }//for - - for (i = 0; i < tNoOfThreads ; i++) { - tabThread[i].ThreadNo = i; - tabThread[i].NdbRef = NULL; - tabThread[i].NoOfOps = tNoOfOperations; - threadLife[i] = NdbThread_Create(ThreadExec, - (void**)&tabThread[i], - 32768, - "RonjaThread", - NDB_THREAD_PRIO_LOW); - }//for - - cont = 1; - while (cont) { - NdbSleep_MilliSleep(10); - cont = 0; - for (i = 0; i < tNoOfThreads ; i++) - if (!ThreadReady[i]) cont = 1; - }//while - - ndbout << "All threads started" << endl; - - if(!nTest){ - - for (;;){ - - inp[0] = 0; - ndbout << endl << "What to do next:" << endl; - ndbout << "1 \t=> Perform lookups in short table" << endl; - ndbout << "2 \t=> Perform lookups in long table" << endl; - ndbout << "3 \t=> Perform updates in short table" << endl; - ndbout << "4 \t=> Perform updates in long table" << endl; - ndbout << "5 \t=> Perform 50% lookups/50% updates in short table" << endl; - ndbout << "6 \t=> Perform 50% lookups/50% updates in long table" << endl; - ndbout << "7 \t=> Perform 80% lookups/20% updates in short table" << endl; - ndbout << "8 \t=> Perform 80% lookups/20% updates in long table" << endl; - ndbout << "9 \t=> Perform 25% lookups short/25% lookups long/25% updates short/25% updates long" << endl; - ndbout << "10\t=> Test bug with replicated interpreted updates, short table" << endl; - ndbout << "11\t=> Test interpreter functions, short table" << endl; - ndbout << "12\t=> Test bug with replicated interpreted updates, long table" << endl; - ndbout << "13\t=> Test interpreter functions, long table" << endl; - ndbout << "14\t=> Perform lookups in short table, no guess of TC" << endl; - ndbout << "15\t=> Perform lookups in long table, no guess of TC" << endl; - ndbout << "16\t=> Perform updates in short table, no guess of TC" << endl; - ndbout << "17\t=> Perform updates in long table, no guess of TC" << endl; - ndbout << "18\t=> Multi record updates of transactions" << endl; - ndbout << "All other responses will exit" << endl; - ndbout << "_____________________________" << endl << endl ; - - int inp_i = 0; - do { - inp[inp_i] = (char) fgetc(stdin); - if (inp[inp_i] == '\n' || inp[inp_i] == EOF) { - inp[inp_i] ='\0'; - break; - } - inp_i++; - - } while (inp[inp_i - 1] != '\n' && inp[inp_i - 1] != EOF); - - tmp = atoi(inp); - - if ((tmp > 18) || (tmp <= 0)) break; - - ndbout << "Starting test " << tmp << "..." << endl; - - for (i = 0; i < tNoOfThreads ; i++){ ThreadStart[i] = tmp; } - - cont = 1; - while (cont) { - NdbSleep_MilliSleep(10); - cont = 0; - for (i = 0; i < tNoOfThreads ; i++){ - if (!ThreadReady[i]) cont = 1; - } - }//while - }//for(;;) - - }else{ - - if(19 == nTest){ - ndbout << "Executing all 18 available tests..." << endl << endl; - for (int count = 1; count < nTest; count++){ - ndbout << "Test " << count << endl ; - ndbout << "------" << endl << endl ; - for (i = 0; i < tNoOfThreads ; i++) { ThreadStart[i] = count ; } - cont = 1; - while (cont) { - NdbSleep_MilliSleep(10); - cont = 0; - for (i = 0; i < tNoOfThreads ; i++){ - if (!ThreadReady[i]) cont = 1; - } - } - }//for - }else{ - ndbout << endl << "Executing test " << nTest << endl << endl; - for (i = 0; i < tNoOfThreads ; i++) { ThreadStart[i] = nTest ; } - cont = 1; - while (cont) { - NdbSleep_MilliSleep(10); - cont = 0; - for (i = 0; i < tNoOfThreads ; i++){ - if (!ThreadReady[i]) cont = 1; - } - } - }//if(18 == nTest) - } //if(!nTest) - - ndbout << "--------------------------------------------------" << endl; - - for (i = 0; i < tNoOfThreads ; i++) ThreadReady[i] = 0; - // Signaling threads to stop - for (i = 0; i < tNoOfThreads ; i++) ThreadStart[i] = 999; - - // Wait for threads to stop - cont = 1; - do { - NdbSleep_MilliSleep(1); - cont = 0; - for (i = 0; i < tNoOfThreads ; i++){ - if (ThreadReady[i] == 0) cont = 1; - } - } while (cont == 1); - - delete pMyNdb ; - ndbout << endl << "Ronja Benchmark completed" << endl; - return NDBT_ProgramExit(NDBT_OK) ; - -error_input: - ndbout << endl << " Ivalid parameter(s)" << endl; - ndbout << " Usage: benchronja [-t threads][-r rec] [-o ops] [-c ops_per_exec] [-p test], where:" << endl; - ndbout << " threads - the number of threads to start; default: 1" << endl; - ndbout << " rec - the number of records in the tables; default: 500" << endl; - ndbout << " ops - the number of operations per transaction; default: 100000" << endl; - ndbout << " ops_per_exec - the number of operations per execution; default: 1" << endl ; - ndbout << " test - the number of test to execute; 19 executes all available tests; default: 0"<< endl ; - ndbout << " which enters a loop expecting manual input of test number to execute." << endl << endl ; - delete pMyNdb ; - return NDBT_ProgramExit(NDBT_WRONGARGS) ; - - } -//////////////////////////////////////// - -void commitTrans(Ndb* aNdb, NdbConnection* aCon) -{ - int ret = aCon->execute(Commit); - assert (ret != -1); - aNdb->closeTransaction(aCon); -} - -void rollbackTrans(Ndb* aNdb, NdbConnection* aCon) -{ - int ret = aCon->execute(Rollback); - assert (ret != -1); - aNdb->closeTransaction(aCon); -} - -void updateNoCommit(NdbConnection* aCon, Uint32* flip, unsigned int key) -{ - NdbOperation* theOperation; - - *flip = *flip + 1; - theOperation = aCon->getNdbOperation("SHORT_REC"); - theOperation->updateTuple(); - theOperation->equal((Uint32)0, key); - theOperation->setValue((Uint32)1, (char*)flip); - int ret = aCon->execute(NoCommit); - assert (ret != -1); -} - -void updateNoCommitFail(NdbConnection* aCon, unsigned int key) -{ - NdbOperation* theOperation; - - Uint32 flip = 0; - theOperation = aCon->getNdbOperation("SHORT_REC"); - theOperation->updateTuple(); - theOperation->equal((Uint32)0, key); - theOperation->setValue((Uint32)1, (char*)flip); - int ret = aCon->execute(NoCommit); - assert (ret == -1); -} - -void deleteNoCommit(NdbConnection* aCon, Uint32* flip, unsigned int key) -{ - NdbOperation* theOperation; - - *flip = 0; - theOperation = aCon->getNdbOperation("SHORT_REC"); - theOperation->deleteTuple(); - theOperation->equal((Uint32)0, key); - int ret = aCon->execute(NoCommit); - assert (ret != -1); -} - -void insertNoCommit(NdbConnection* aCon, Uint32* flip, unsigned int key) -{ - NdbOperation* theOperation; - Uint32 placeholder[100]; - - *flip = *flip + 1; - theOperation = aCon->getNdbOperation("SHORT_REC"); - theOperation->insertTuple(); - theOperation->equal((Uint32)0, key); - theOperation->setValue((Uint32)1, (char*)flip); - theOperation->setValue((Uint32)2, (char*)&placeholder[0]); - theOperation->setValue((Uint32)3, (char*)&placeholder[0]); - int ret = aCon->execute(NoCommit); - assert (ret != -1); -} - -void writeNoCommit(NdbConnection* aCon, Uint32* flip, unsigned int key) -{ - NdbOperation* theOperation; - Uint32 placeholder[100]; - - *flip = *flip + 1; - theOperation = aCon->getNdbOperation("SHORT_REC"); - theOperation->writeTuple(); - theOperation->equal((Uint32)0, key); - theOperation->setValue((Uint32)1, (char*)flip); - theOperation->setValue((Uint32)2, (char*)&placeholder[0]); - theOperation->setValue((Uint32)3, (char*)&placeholder[0]); - int ret = aCon->execute(NoCommit); - assert (ret != -1); -} - -void readNoCommit(NdbConnection* aCon, Uint32* flip, Uint32 key, int expected_ret) -{ - NdbOperation* theOperation; - Uint32 readFlip; - - theOperation = aCon->getNdbOperation("SHORT_REC"); - theOperation->readTuple(); - theOperation->equal((Uint32)0, key); - theOperation->getValue((Uint32)1, (char*)&readFlip); - int ret = aCon->execute(NoCommit); - assert (ret == expected_ret); - if (ret == 0) - assert (*flip == readFlip); -} - -void readDirtyNoCommit(NdbConnection* aCon, Uint32* flip, Uint32 key, int expected_ret) -{ - NdbOperation* theOperation; - Uint32 readFlip; - - theOperation = aCon->getNdbOperation("SHORT_REC"); - theOperation->committedRead(); - theOperation->equal((Uint32)0, key); - theOperation->getValue((Uint32)1, (char*)&readFlip); - int ret = aCon->execute(NoCommit); - assert (ret == expected_ret); - if (ret == 0) - assert (*flip == readFlip); -} - -void readVerify(Ndb* aNdb, Uint32* flip, Uint32 key, int expected_ret) -{ - NdbConnection* theTransaction; - theTransaction = aNdb->startTransaction(); - readNoCommit(theTransaction, flip, key, expected_ret); - commitTrans(aNdb, theTransaction); -} - -void readDirty(Ndb* aNdb, Uint32* flip, Uint32 key, int expected_ret) -{ - NdbOperation* theOperation; - NdbConnection* theTransaction; - Uint32 readFlip; - - theTransaction = aNdb->startTransaction(); - theOperation = theTransaction->getNdbOperation("SHORT_REC"); - theOperation->committedRead(); - theOperation->equal((Uint32)0, key); - theOperation->getValue((Uint32)1, (char*)&readFlip); - int ret = theTransaction->execute(Commit); - assert (ret == expected_ret); - if (ret == 0) - assert (*flip == readFlip); - aNdb->closeTransaction(theTransaction); -} - -int multiRecordTest(Ndb* aNdb, unsigned int key) -{ - NdbConnection* theTransaction; - Uint32 flip = 0; - Uint32 save_flip; - ndbout << "0" << endl; - - theTransaction = aNdb->startTransaction(); - - updateNoCommit(theTransaction, &flip, key); - - readNoCommit(theTransaction, &flip, key, 0); - - updateNoCommit(theTransaction, &flip, key); - - readNoCommit(theTransaction, &flip, key, 0); - - commitTrans(aNdb, theTransaction); - - ndbout << "1 " << endl; - - readVerify(aNdb, &flip, key, 0); - readDirty(aNdb, &flip, key, 0); - save_flip = flip; - ndbout << "1.1 " << endl; - - theTransaction = aNdb->startTransaction(); - - deleteNoCommit(theTransaction, &flip, key); - - readNoCommit(theTransaction, &flip, key, -1); - readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!! - readDirtyNoCommit(theTransaction, &flip, key, -1); - ndbout << "1.2 " << endl; - - insertNoCommit(theTransaction, &flip, key); - - readNoCommit(theTransaction, &flip, key, 0); - readDirtyNoCommit(theTransaction, &flip, key, 0); - readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!! - ndbout << "1.3 " << endl; - - updateNoCommit(theTransaction, &flip, key); - - readNoCommit(theTransaction, &flip, key, 0); - readDirtyNoCommit(theTransaction, &flip, key, 0); - readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!! - ndbout << "1.4 " << endl; - - commitTrans(aNdb, theTransaction); - - ndbout << "2 " << endl; - - readDirty(aNdb, &flip, key, 0); // COMMITTED READ!!! - readVerify(aNdb, &flip, key, 0); - - save_flip = flip; - theTransaction = aNdb->startTransaction(); - - deleteNoCommit(theTransaction, &flip, key); - - readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!! - readDirtyNoCommit(theTransaction, &flip, key, -1); // COMMITTED READ!!! - readNoCommit(theTransaction, &flip, key, -1); - - insertNoCommit(theTransaction, &flip, key); - - readNoCommit(theTransaction, &flip, key, 0); - - updateNoCommit(theTransaction, &flip, key); - - readNoCommit(theTransaction, &flip, key, 0); - readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!! - readDirtyNoCommit(theTransaction, &flip, key, 0); // COMMITTED READ!!! - - deleteNoCommit(theTransaction, &flip, key); - - readNoCommit(theTransaction, &flip, key, -1); - readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!! - readDirtyNoCommit(theTransaction, &flip, key, -1); - - rollbackTrans(aNdb, theTransaction); - - ndbout << "3 " << endl; - - flip = save_flip; - readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!! - readVerify(aNdb, &flip, key, 0); - - theTransaction = aNdb->startTransaction(); - - updateNoCommit(theTransaction, &flip, key); - - readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!! - readDirtyNoCommit(theTransaction, &flip, key, 0); - readNoCommit(theTransaction, &flip, key, 0); - - deleteNoCommit(theTransaction, &flip, key); - - readNoCommit(theTransaction, &flip, key, -1); - readDirtyNoCommit(theTransaction, &flip, key, -1); - readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!! - - insertNoCommit(theTransaction, &flip, key); - - readNoCommit(theTransaction, &flip, key, 0); - readDirtyNoCommit(theTransaction, &flip, key, 0); - readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!! - - updateNoCommit(theTransaction, &flip, key); - - readNoCommit(theTransaction, &flip, key, 0); - readDirtyNoCommit(theTransaction, &flip, key, 0); - readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!! - - deleteNoCommit(theTransaction, &flip, key); - - readDirty(aNdb, &save_flip, key, 0); // COMMITTED READ!!! - readNoCommit(theTransaction, &flip, key, -1); - readDirtyNoCommit(theTransaction, &flip, key, -1); - - commitTrans(aNdb, theTransaction); - - ndbout << "4 " << endl; - - readVerify(aNdb, &flip, key, -1); - - theTransaction = aNdb->startTransaction(); - - insertNoCommit(theTransaction, &flip, key); - - readDirty(aNdb, &save_flip, key, -1); // COMMITTED READ!!! - readNoCommit(theTransaction, &flip, key, 0); - readDirtyNoCommit(theTransaction, &flip, key, 0); - - deleteNoCommit(theTransaction, &flip, key); - - readDirty(aNdb, &save_flip, key, -1); // COMMITTED READ!!! - readNoCommit(theTransaction, &flip, key, -1); - readDirtyNoCommit(theTransaction, &flip, key, -1); - - insertNoCommit(theTransaction, &flip, key); - - readDirty(aNdb, &save_flip, key, -1); // COMMITTED READ!!! - readNoCommit(theTransaction, &flip, key, 0); - readDirtyNoCommit(theTransaction, &flip, key, 0); - - updateNoCommit(theTransaction, &flip, key); - - readDirty(aNdb, &save_flip, key, -1); // COMMITTED READ!!! - readNoCommit(theTransaction, &flip, key, 0); - readDirtyNoCommit(theTransaction, &flip, key, 0); - - deleteNoCommit(theTransaction, &flip, key); - - readDirty(aNdb, &save_flip, key, -1); // COMMITTED READ!!! - readNoCommit(theTransaction, &flip, key, -1); - readDirtyNoCommit(theTransaction, &flip, key, -1); - - commitTrans(aNdb, theTransaction); - - ndbout << "5 " << endl; - - readDirty(aNdb, &flip, key, -1); // COMMITTED READ!!! - readVerify(aNdb, &flip, key, -1); - - theTransaction = aNdb->startTransaction(); - - insertNoCommit(theTransaction, &flip, key); - - readDirty(aNdb, &flip, key, -1); // COMMITTED READ!!! - readDirtyNoCommit(theTransaction, &flip, key, 0); // COMMITTED READ!!! - - commitTrans(aNdb, theTransaction); - readDirty(aNdb, &flip, key, 0); // COMMITTED READ!!! - - ndbout << "6 " << endl; - - theTransaction = aNdb->startTransaction(); - - deleteNoCommit(theTransaction, &flip, key); - updateNoCommitFail(theTransaction, key); - rollbackTrans(aNdb, theTransaction); - return 0; -} - -int lookup(Ndb* aNdb, unsigned int key, unsigned int long_short, int guess){ - - int placeholder[500]; - unsigned int flip, count; - int ret_value, i; - NdbConnection* theTransaction; - NdbOperation* theOperation; - if ( !aNdb ) return -1 ; - - if (guess != 0) - theTransaction = aNdb->startTransaction((Uint32)0, (const char*)&key, (Uint32)4); - else - theTransaction = aNdb->startTransaction(); - - for (i = 0; i < tNoOfOpsPerExecute; i++) { - if (long_short == 0) - theOperation = theTransaction->getNdbOperation("SHORT_REC"); - else - theOperation = theTransaction->getNdbOperation("LONG_REC"); - if (theOperation == NULL) { - ndbout << "Table missing" << endl; - aNdb->closeTransaction(theTransaction) ; - return -1; - }//if - theOperation->simpleRead(); - theOperation->equal((Uint32)0, key); - theOperation->getValue((Uint32)1, (char*)&flip); - theOperation->getValue((Uint32)2, (char*)&count); - if (theOperation->getValue((Uint32)3, (char*)&placeholder[0]) == NULL) { - ndbout << "Error in definition phase = " << theTransaction->getNdbError() << endl; - aNdb->closeTransaction(theTransaction); - return -1; - }//if - }//for - ret_value = theTransaction->execute(Commit); - if (ret_value == -1) - ndbout << "Error in lookup:" << theTransaction->getNdbError() << endl; - aNdb->closeTransaction(theTransaction); - return ret_value; -}//lookup() - -int update(Ndb* aNdb, unsigned int key, unsigned int long_short, int guess) -{ - int placeholder[500]; - int ret_value, i; - unsigned int flip, count; - NdbConnection* theTransaction; - NdbOperation* theOperation; - - if ( !aNdb ) return -1 ; - - if (guess != 0) - theTransaction = aNdb->startTransaction((Uint32)0, (const char*)&key, (Uint32)4); - else - theTransaction = aNdb->startTransaction(); - - for (i = 0; i < tNoOfOpsPerExecute; i++) { - if (long_short == 0) - theOperation = theTransaction->getNdbOperation("SHORT_REC"); // Use table SHORT_REC - else - theOperation = theTransaction->getNdbOperation("LONG_REC"); // Use table LONG_REC - if (theOperation == NULL) { - ndbout << "Table missing" << endl; - aNdb->closeTransaction(theTransaction) ; - delete aNdb ; - return -1; - }//if - theOperation->interpretedUpdateTuple(); // Send interpreted program to NDB kernel - theOperation->equal((Uint32)0, key); // Search key - theOperation->getValue((Uint32)1, (char*)&flip); // Read value of flip - theOperation->getValue((Uint32)2, (char*)&count); // Read value of count - theOperation->getValue((Uint32)3, (char*)&placeholder[0]); // Read value of placeholder - theOperation->load_const_u32((Uint32)1, (Uint32)0); // Load register 1 with 0 - theOperation->read_attr((Uint32)1, (Uint32)2); // Read Flip value into register 2 - theOperation->branch_eq((Uint32)1, (Uint32)2, (Uint32)0); // If Flip (register 2) == 0 (register 1) goto label 0 - theOperation->branch_label((Uint32)1); // Goto label 1 - theOperation->def_label((Uint32)0); // Define label 0 - theOperation->load_const_u32((Uint32)1, (Uint32)1); // Load register 1 with 1 - theOperation->def_label((Uint32)1); // Define label 0 - theOperation->write_attr((Uint32)1, (Uint32)1); // Write 1 (register 1) into Flip - ret_value = theOperation->incValue((Uint32)2, (Uint32)1); // Increment Count by 1 - if (ret_value == -1) { - ndbout << "Error in definition phase " << endl; - aNdb->closeTransaction(theTransaction); - return ret_value; - }//if - }//for - ret_value = theTransaction->execute(Commit); // Perform the actual read and update - if (ret_value == -1) { - ndbout << "Error in update:" << theTransaction->getNdbError() << endl; - aNdb->closeTransaction(theTransaction); // < epaulsa - return ret_value ; - }//if - aNdb->closeTransaction(theTransaction); - return ret_value; -}//update() - -int update_bug(Ndb* aNdb, unsigned int key, unsigned int long_short) -{ - int placeholder[500]; - int ret_value, i; - unsigned int flip, count; - NdbConnection* theTransaction; - NdbOperation* theOperation; - - if ( !aNdb ) return -1 ; - - theTransaction = aNdb->startTransaction(); - for (i = 0; i < tNoOfOpsPerExecute; i++) { - if (long_short == 0) - theOperation = theTransaction->getNdbOperation("SHORT_REC"); // Use table SHORT_REC - else - theOperation = theTransaction->getNdbOperation("LONG_REC"); // Use table LONG_REC - if (theOperation == NULL) { - ndbout << "Table missing" << endl; - aNdb->closeTransaction(theTransaction) ; - return -1; - }//if - theOperation->interpretedUpdateTuple(); // Send interpreted program to NDB kernel - theOperation->equal((Uint32)0, key); // Search key - theOperation->getValue((Uint32)1, (char*)&flip); // Read value of flip - theOperation->getValue((Uint32)2, (char*)&count); // Read value of count - theOperation->getValue((Uint32)3, (char*)&placeholder[0]); // Read value of placeholder - theOperation->load_const_u32((Uint32)1, (Uint32)0); // Load register 1 with 0 - theOperation->read_attr((Uint32)1, (Uint32)2); // Read Flip value into register 2 - theOperation->branch_eq((Uint32)1, (Uint32)2, (Uint32)0); // If Flip (register 2) == 0 (register 1) goto label 0 - theOperation->branch_label((Uint32)1); // Goto label 1 - theOperation->def_label((Uint32)0); // Define label 0 - theOperation->load_const_u32((Uint32)1, (Uint32)1); // Load register 1 with 1 - theOperation->def_label((Uint32)1); // Define label 0 - theOperation->write_attr((Uint32)1, (Uint32)1); // Write 1 (register 1) into Flip - ret_value = theOperation->incValue((Uint32)2, (Uint32)1); // Increment Count by 1 - if (ret_value == -1) { - ndbout << "Error in definition phase " << endl; - aNdb->closeTransaction(theTransaction); - return ret_value; - }//if - }//for - ret_value = theTransaction->execute(NoCommit); // Perform the actual read and update - if (ret_value == -1) { - ndbout << "Error in update:" << theTransaction->getNdbError() << endl; - aNdb->closeTransaction(theTransaction); - return ret_value ; - }//if - aNdb->closeTransaction(theTransaction); - return ret_value; -}//update_bug() - -int update_interpreter_test(Ndb* aNdb, unsigned int key, unsigned int long_short) -{ - int placeholder[500]; - int ret_value, i; - unsigned int flip, count; - NdbConnection* theTransaction; - NdbOperation* theOperation; - Uint32 Tlabel = 0; - - if ( !aNdb ) return -1 ; - -//------------------------------------------------------------------------------ -// Start the transaction and get a unique transaction id -//------------------------------------------------------------------------------ - theTransaction = aNdb->startTransaction(); - for (i = 0; i < tNoOfOpsPerExecute; i++) { -//------------------------------------------------------------------------------ -// Get the proper table object and load schema information if not already -// present. -//------------------------------------------------------------------------------ - if (long_short == 0) - theOperation = theTransaction->getNdbOperation("SHORT_REC"); // Use table SHORT_REC - else - theOperation = theTransaction->getNdbOperation("LONG_REC"); // Use table LONG_REC - if (theOperation == NULL) { - ndbout << "Table missing" << endl; - aNdb->closeTransaction(theTransaction) ; - return -1; - }//if -//------------------------------------------------------------------------------ -// Define the operation type and the tuple key (primary key in this case). -//------------------------------------------------------------------------------ - theOperation->interpretedUpdateTuple(); // Send interpreted program to NDB kernel - theOperation->equal((Uint32)0, key); // Search key - -//------------------------------------------------------------------------------ -// Perform initial read of attributes before updating them -//------------------------------------------------------------------------------ - theOperation->getValue((Uint32)1, (char*)&flip); // Read value of flip - theOperation->getValue((Uint32)2, (char*)&count); // Read value of count - theOperation->getValue((Uint32)3, (char*)&placeholder[0]); // Read value of placeholder - -//------------------------------------------------------------------------------ -// Test that the various branch operations can handle things correctly. -// Test first 2 + 3 = 5 with 32 bit registers -// Next test the same with 32 bit + 64 bit = 64 -//------------------------------------------------------------------------------ - theOperation->load_const_u32((Uint32)4, (Uint32)0); // Load register 4 with 0 - - theOperation->load_const_u32((Uint32)0, (Uint32)0); - theOperation->load_const_u32((Uint32)1, (Uint32)3); - theOperation->load_const_u32((Uint32)2, (Uint32)5); - theOperation->load_const_u32((Uint32)3, (Uint32)1); - theOperation->def_label(Tlabel++); - theOperation->def_label(Tlabel++); - theOperation->sub_reg((Uint32)2, (Uint32)3, (Uint32)2); - theOperation->branch_ne((Uint32)2, (Uint32)0, (Uint32)0); - theOperation->load_const_u32((Uint32)2, (Uint32)5); - theOperation->sub_reg((Uint32)1, (Uint32)3, (Uint32)1); - theOperation->branch_ne((Uint32)1, (Uint32)0, (Uint32)1); - - theOperation->load_const_u32((Uint32)1, (Uint32)2); // Load register 1 with 2 - theOperation->load_const_u32((Uint32)2, (Uint32)3); // Load register 2 with 3 - theOperation->add_reg((Uint32)1, (Uint32)2, (Uint32)1); // 2+3 = 5 into reg 1 - theOperation->load_const_u32((Uint32)2, (Uint32)5); // Load register 2 with 5 - - theOperation->def_label(Tlabel++); - - theOperation->branch_eq((Uint32)1, (Uint32)2, Tlabel); - theOperation->interpret_exit_nok((Uint32)6001); - - theOperation->def_label(Tlabel++); - theOperation->branch_ne((Uint32)1, (Uint32)2, Tlabel); - theOperation->branch_label(Tlabel + 1); - theOperation->def_label(Tlabel++); - theOperation->interpret_exit_nok((Uint32)6002); - - theOperation->def_label(Tlabel++); - theOperation->branch_lt((Uint32)1, (Uint32)2, Tlabel); - theOperation->branch_label(Tlabel + 1); - theOperation->def_label(Tlabel++); - theOperation->interpret_exit_nok((Uint32)6003); - - theOperation->def_label(Tlabel++); - theOperation->branch_gt((Uint32)1, (Uint32)2, Tlabel); - theOperation->branch_label(Tlabel + 1); - theOperation->def_label(Tlabel++); - theOperation->interpret_exit_nok((Uint32)6005); - - theOperation->def_label(Tlabel++); - theOperation->branch_eq_null((Uint32)1, Tlabel); - theOperation->branch_label(Tlabel + 1); - theOperation->def_label(Tlabel++); - theOperation->interpret_exit_nok((Uint32)6006); - - theOperation->def_label(Tlabel++); - theOperation->branch_ne_null((Uint32)1,Tlabel); - theOperation->interpret_exit_nok((Uint32)6007); - - theOperation->def_label(Tlabel++); - theOperation->branch_ge((Uint32)1, (Uint32)2, Tlabel); - theOperation->interpret_exit_nok((Uint32)6008); - - theOperation->def_label(Tlabel++); - theOperation->branch_eq_null((Uint32)6,Tlabel); - theOperation->interpret_exit_nok((Uint32)6009); - - theOperation->def_label(Tlabel++); - theOperation->branch_ne_null((Uint32)6, Tlabel); - theOperation->branch_label(Tlabel + 1); - theOperation->def_label(Tlabel++); - theOperation->interpret_exit_nok((Uint32)6010); - - theOperation->def_label(Tlabel++); - - theOperation->load_const_u32((Uint32)5, (Uint32)1); - theOperation->add_reg((Uint32)4, (Uint32)5, (Uint32)4); - - theOperation->load_const_u32((Uint32)5, (Uint32)1); - theOperation->branch_eq((Uint32)4, (Uint32)5, Tlabel); - - - theOperation->load_const_u32((Uint32)5, (Uint32)2); - theOperation->branch_eq((Uint32)4, (Uint32)5, (Tlabel + 1)); - - theOperation->load_const_u32((Uint32)5, (Uint32)3); - theOperation->branch_eq((Uint32)4, (Uint32)5, (Tlabel + 2)); - - theOperation->load_const_u32((Uint32)5, (Uint32)4); - theOperation->branch_eq((Uint32)4, (Uint32)5, (Tlabel + 3)); - - theOperation->branch_label(Tlabel + 4); - - theOperation->def_label(Tlabel++); - theOperation->load_const_u32((Uint32)1, (Uint32)200000); - theOperation->load_const_u32((Uint32)2, (Uint32)300000); - theOperation->add_reg((Uint32)1, (Uint32)2, (Uint32)1); - theOperation->load_const_u32((Uint32)2, (Uint32)500000); - theOperation->branch_label((Uint32)2); - - theOperation->def_label(Tlabel++); - theOperation->load_const_u32((Uint32)1, (Uint32)200000); - theOperation->load_const_u32((Uint32)2, (Uint32)300000); - theOperation->add_reg((Uint32)1, (Uint32)2, (Uint32)1); - theOperation->load_const_u32((Uint32)2, (Uint32)500000); - theOperation->branch_label((Uint32)2); - - theOperation->def_label(Tlabel++); - theOperation->load_const_u32((Uint32)1, (Uint32)2); - Uint64 x = 0; - theOperation->load_const_u64((Uint32)2, (Uint64)(x - 1)); - theOperation->add_reg((Uint32)1, (Uint32)2, (Uint32)1); - theOperation->load_const_u32((Uint32)2, (Uint32)1); - theOperation->branch_label((Uint32)2); - - theOperation->def_label(Tlabel++); - theOperation->load_const_u32((Uint32)1, (Uint32)2); - theOperation->load_const_u64((Uint32)2, (Uint64)(x - 1)); - theOperation->add_reg((Uint32)1, (Uint32)2, (Uint32)1); - theOperation->load_const_u64((Uint32)2, (Uint64)1); - theOperation->branch_label((Uint32)2); - - theOperation->def_label(Tlabel++); - theOperation->read_attr((Uint32)1, (Uint32)2); - theOperation->branch_eq((Uint32)1, (Uint32)2, Tlabel); - theOperation->load_const_u32((Uint32)1, (Uint32)0); - theOperation->branch_label(Tlabel + 1); - theOperation->def_label(Tlabel++); - theOperation->load_const_u32((Uint32)1, (Uint32)1); - theOperation->def_label(Tlabel++); - theOperation->write_attr((Uint32)1, (Uint32)1); - ret_value = theOperation->incValue((Uint32)2, (Uint32)1); - if (ret_value == -1) { - ndbout << "Error in definition phase " << endl; - ndbout << "Error = " << theOperation->getNdbError() << " on line = " << theOperation->getNdbErrorLine() << endl; - aNdb->closeTransaction(theTransaction); - return ret_value; - }//if - }//for -//------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ - ret_value = theTransaction->execute(Commit); // Perform the actual read and update - if (ret_value == -1) { - ndbout << "Error in update:" << theTransaction->getNdbError() << endl; - aNdb->closeTransaction(theTransaction); // < epaulsa - return ret_value ; - }//if -//------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ - aNdb->closeTransaction(theTransaction); - return ret_value; -}//update_interpreter_test() - -void* ThreadExec(void* ThreadData){ - - ThreadNdb* tabThread = (ThreadNdb*)ThreadData; - Ndb* pMyNdb = NULL ; - myRandom48Init(NdbTick_CurrentMillisecond()); - - int Tsuccess = 0 ; - int check = 0 ; - int loop_count_ops = 0; - int count, i, Ti; - int tType = 0 ; - int remType = 0 ; - unsigned int thread_no = 0 ; - unsigned long total_milliseconds; - unsigned int key = 0 ; - unsigned int prob = 0 ; - unsigned long transaction_time = 0 ; - unsigned long transaction_max_time = 0 ; - unsigned long min_time, max_time[MAX_TIMERS]; - double mean_time, mean_square_time, std_time; - - thread_no = tabThread->ThreadNo; - pMyNdb = tabThread->NdbRef; - if (!pMyNdb) { - pMyNdb = new Ndb( "TEST_DB" ); - pMyNdb->init(); - }//if - - for (;;){ - - min_time = 0xFFFFFFFF; - //for (Ti = 0; Ti < MAX_TIMERS ; Ti++) max_time[Ti] = 0; - memset(&max_time, 0, sizeof max_time) ; - mean_time = 0; - mean_square_time = 0; - ThreadReady[thread_no] = 1; - - while (!ThreadStart[thread_no]){ - NdbSleep_MilliSleep(1); - } - - // Check if signal to exit is received - if (ThreadStart[thread_no] == 999){ - delete pMyNdb; - pMyNdb = NULL ; - ThreadReady[thread_no] = 1; - NdbThread_Exit(0) ; - return 0 ; - }//if - - tType = ThreadStart[thread_no]; - remType = tType; - ThreadStart[thread_no] = 0; - ThreadReady[thread_no] = 0 ; - - // Start transaction, type of transaction - // is received in the array ThreadStart - loop_count_ops = tNoOfOperations; - - START_TIMER_TOP - for (count=0 ; count < loop_count_ops ; count++) { - - Tsuccess = 0; -//---------------------------------------------------- -// Generate a random key between 0 and tNoOfRecords - 1 -//---------------------------------------------------- - key = myRandom48(tNoOfRecords); -//---------------------------------------------------- -// Start time measurement of transaction. -//---------------------------------------------------- - START_TIMER - //do { - switch (remType){ - case 1: -//---------------------------------------------------- -// Only lookups in short record table -//---------------------------------------------------- - Tsuccess = lookup(pMyNdb, key, 0, 1); - break; - - case 2: -//---------------------------------------------------- -// Only lookups in long record table -//---------------------------------------------------- - Tsuccess = lookup(pMyNdb, key, 1, 1); - break; - case 3: -//---------------------------------------------------- -// Only updates in short record table -//---------------------------------------------------- - Tsuccess = update(pMyNdb, key, 0, 1); - break; - case 4: -//---------------------------------------------------- -// Only updates in long record table -//---------------------------------------------------- - Tsuccess = update(pMyNdb, key, 1, 1); - break; - case 5: -//---------------------------------------------------- -// 50% read/50 % update in short record table -//---------------------------------------------------- - prob = myRandom48(100); - if (prob < 50) - Tsuccess = update(pMyNdb, key, 0, 1); - else - Tsuccess = lookup(pMyNdb, key, 0, 1); - break; - case 6: -//---------------------------------------------------- -// 50% read/50 % update in long record table -//---------------------------------------------------- - prob = myRandom48(100); - if (prob < 50) - Tsuccess = update(pMyNdb, key, 1, 1); - else - Tsuccess = lookup(pMyNdb, key, 1, 1); - break; - case 7: -//---------------------------------------------------- -// 80 read/20 % update in short record table -//---------------------------------------------------- - prob = myRandom48(100); - if (prob < 20) - Tsuccess = update(pMyNdb, key, 0, 1); - else - Tsuccess = lookup(pMyNdb, key, 0, 1); - break; - case 8: -//---------------------------------------------------- -// 80 read/20 % update in long record table -//---------------------------------------------------- - prob = myRandom48(100); - if (prob < 20) - Tsuccess = update(pMyNdb, key, 1, 1); - else - Tsuccess = lookup(pMyNdb, key, 1, 1); - break; - case 9: -//---------------------------------------------------- -// 25 read short/25 % read long/25 % update short/25 % update long -//---------------------------------------------------- - prob = myRandom48(100); - if (prob < 25) - Tsuccess = update(pMyNdb, key, 0, 1); - else if (prob < 50) - Tsuccess = update(pMyNdb, key, 1, 1); - else if (prob < 75) - Tsuccess = lookup(pMyNdb, key, 0, 1); - else - Tsuccess = lookup(pMyNdb, key, 1, 1); - break; - case 10: -//---------------------------------------------------- -// Test bug with replicated interpreted update, short table -//---------------------------------------------------- - Tsuccess = update_bug(pMyNdb, key, 0); - break; - case 11: -//---------------------------------------------------- -// Test interpreter functions, short table -//---------------------------------------------------- - Tsuccess = update_interpreter_test(pMyNdb, key, 0); - break; - case 12: -//---------------------------------------------------- -// Test bug with replicated interpreted update, long table -//---------------------------------------------------- - Tsuccess = update_bug(pMyNdb, key, 1); - break; - case 13: -//---------------------------------------------------- -// Test interpreter functions, long table -//---------------------------------------------------- - Tsuccess = update_interpreter_test(pMyNdb, key, 1); - break; - case 14: -//---------------------------------------------------- -// Only lookups in short record table -//---------------------------------------------------- - Tsuccess = lookup(pMyNdb, key, 0, 0); - break; - case 15: -//---------------------------------------------------- -// Only lookups in long record table -//---------------------------------------------------- - Tsuccess = lookup(pMyNdb, key, 1, 0); - break; - case 16: -//---------------------------------------------------- -// Only updates in short record table -//---------------------------------------------------- - Tsuccess = update(pMyNdb, key, 0, 0); - break; - case 17: -//---------------------------------------------------- -// Only updates in long record table -//---------------------------------------------------- - Tsuccess = update(pMyNdb, key, 1, 0); - break; - case 18: - Tsuccess = multiRecordTest(pMyNdb, key); - break; - default: - break; - }//switch - //} while (0);// - if(-1 == Tsuccess) { - NDBT_ProgramExit(NDBT_FAILED); - exit(-1); - } // for -//---------------------------------------------------- -// Stop time measurement of transaction. -//---------------------------------------------------- - STOP_TIMER - transaction_time = (unsigned long)timer.elapsedTime() ;//stopTimer(&theStartTime); -//---------------------------------------------------- -// Perform calculations of time measurements. -//---------------------------------------------------- - transaction_max_time = transaction_time; - for (Ti = 0; Ti < MAX_TIMERS; Ti++) { - if (transaction_max_time > max_time[Ti]) { - Uint32 tmp = max_time[Ti]; - max_time[Ti] = transaction_max_time; - transaction_max_time = tmp; - }//if - }//if - if (transaction_time < min_time) min_time = transaction_time; - mean_time = (double)transaction_time + mean_time; - mean_square_time = (double)(transaction_time * transaction_time) + mean_square_time; - }//for -//---------------------------------------------------- -// Calculate mean and standard deviation -//---------------------------------------------------- - STOP_TIMER_TOP - total_milliseconds = (unsigned long)timer_top.elapsedTime() ;//stopTimer(&total_time); - mean_time = mean_time / loop_count_ops; - mean_square_time = mean_square_time / loop_count_ops; - std_time = sqrt(mean_square_time - (mean_time * mean_time)); -//---------------------------------------------------- -// Report statistics -//---------------------------------------------------- - ndbout << "Thread = " << thread_no << " reporting:" << endl ; - ndbout << "------------------------------" << endl ; - ndbout << "Total time is " << (unsigned int)(total_milliseconds /1000); - ndbout << " seconds and " << (unsigned int)(total_milliseconds % 1000); - ndbout << " milliseconds" << endl; - ndbout << "Minimum time = " << (unsigned int)min_time << " milliseconds" << endl; - for (Ti = 0; Ti < MAX_TIMERS; Ti++) { - ndbout << "Maximum timer " << Ti << " = " << (unsigned int)max_time[Ti] << " milliseconds" << endl; - ndbout << "Mean time = " << (unsigned int)mean_time << " milliseconds" << endl; - ndbout << "Standard deviation on time = " << (unsigned int)std_time; - ndbout << " milliseconds" << endl << endl ; - }//for - ndbout << endl ; - - } // for(;;) - - delete pMyNdb ; - NdbThread_Exit(0) ; - return 0 ; // Compiler is happy now -} - diff --git a/ndb/test/ndbapi/ronja/initronja/Makefile b/ndb/test/ndbapi/ronja/initronja/Makefile deleted file mode 100644 index dd66dd813d1..00000000000 --- a/ndb/test/ndbapi/ronja/initronja/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := initronja - -SOURCES := initronja.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/ronja/initronja/initronja.cpp b/ndb/test/ndbapi/ronja/initronja/initronja.cpp deleted file mode 100644 index f3f4d9628e2..00000000000 --- a/ndb/test/ndbapi/ronja/initronja/initronja.cpp +++ /dev/null @@ -1,349 +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 */ - - -/* *************************************************** - INITRONJA - Initialise benchmark for Ronja Database - * *************************************************** */ - -#include "NdbApi.hpp" -#include -#include -#include -#include - -#define MAXSTRLEN 16 -#define MAXATTR 64 -#define MAXTABLES 64 -#define MAXTHREADS 256 -#define MAXATTRSIZE 8000 - -static unsigned int tNoOfRecords; -static unsigned int tNoOfLoops; -static unsigned int tNoOfTables; -static int tAttributeSize; -static int tNodeId; -static unsigned int tValue; -static unsigned int tNoOfOperations; -static char tableName[MAXTABLES][MAXSTRLEN]; -static char attrName[MAXATTR][MAXSTRLEN]; - -inline int InsertRecords(Ndb*, int) ; - -NDB_COMMAND(initronja, "initronja", "initronja", "initronja", 65535){ - - Ndb* pNdb = NULL ; - NdbSchemaCon *MySchemaTransaction = NULL ; - NdbSchemaOp *MySchemaOp = NULL ; - - - int check, status, i, j, cont ; - check = status = i = j = cont = 0 ; - tNoOfRecords = 500 ; - tNoOfLoops = tNoOfRecords / 10; - - i = 1; - while (argc > 1){ - - if (strcmp(argv[i], "-r") == 0){ - if( NULL == argv[i+1] ) goto error_input ; - tNoOfRecords = atoi(argv[i+1]); - tNoOfRecords = tNoOfRecords - (tNoOfRecords % 10); - tNoOfLoops = tNoOfRecords / 10; - if ((tNoOfRecords < 1) || (tNoOfRecords > 1000000000)) goto error_input; - }else{ - goto error_input; - } - - argc -= 2; - i = i + 2; // - } - - pNdb = new Ndb( "TEST_DB" ) ; - ndbout << "Initialisation started. " << endl; - pNdb->init(); - ndbout << "Initialisation completed. " << endl; - - tNodeId = pNdb->getNodeId(); - ndbout << endl << "Initial loading of Ronja Database" << endl; - ndbout << " NdbAPI node with id = " << tNodeId << endl; - - if (pNdb->waitUntilReady(30) != 0) { - ndbout << "Benchmark failed - NDB is not ready" << endl; - delete pNdb ; - return NDBT_ProgramExit(NDBT_FAILED) ; - }//if - - ndbout << endl << "Creating the table SHORT_REC" << "..." << endl; - - MySchemaTransaction = pNdb->startSchemaTransaction(); - if(!MySchemaTransaction) goto error_handler; - MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); - if(!MySchemaOp) goto error_handler; -#if defined NDB_OSE || defined NDB_SOFTOSE - check = MySchemaOp->createTable( "SHORT_REC" - ,8 // Table Size - ,TupleKey // Key Type - ,40 // Nr of Pages - ,All - ,6 - ,78 - ,80 - ,1 - ,false); -#else - check = MySchemaOp->createTable( "SHORT_REC" - ,8 // Table Size - ,TupleKey // Key Type - ,40 // Nr of Pages - ); -#endif - if (check == -1) goto error_handler; - - ndbout << "Key attribute..." ; - check = MySchemaOp->createAttribute( (char*)"Key", TupleKey, 32, 1, - UnSigned, MMBased, NotNullAttribute ); - if (check == -1) goto error_handler; - ndbout << "\t\tOK" << endl ; - - ndbout << "Flip attribute..." ; - check = MySchemaOp->createAttribute("Flip", NoKey, 32, 1, - UnSigned, MMBased, NotNullAttribute ); - if (check == -1) goto error_handler; - ndbout << "\t\tOK" << endl ; - - ndbout << "Count attribute..." ; - check = MySchemaOp->createAttribute("Count", NoKey, 32, 1, - UnSigned, MMBased, NotNullAttribute ); - if (check == -1) goto error_handler; - ndbout << "\t\tOK" << endl ; - - ndbout << "Placeholder attribute..." ; - check = MySchemaOp->createAttribute("Placeholder", NoKey, 8, 90, - UnSigned, MMBased, NotNullAttribute ); - if (check == -1) goto error_handler; - ndbout << "\tOK" << endl ; - - if (MySchemaTransaction->execute() == -1) { - if(721 == MySchemaOp->getNdbError().code){ - ndbout << "Table SHORT_REC already exists" << endl ; - }else{ - ndbout << MySchemaTransaction->getNdbError() << endl; - } - }else{ - ndbout << "SHORT_REC created " << endl; - }// if - - pNdb->closeSchemaTransaction(MySchemaTransaction); - - ndbout << endl << "Creating the table LONG_REC..." << endl; - - MySchemaTransaction = pNdb->startSchemaTransaction(); - if(!MySchemaTransaction) goto error_handler; - - MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); - if(!MySchemaOp) goto error_handler; -#if defined NDB_OSE || defined NDB_SOFTOSE - check = MySchemaOp->createTable( "LONG_REC" - ,8 // Table Size - ,TupleKey // Key Type - ,40 // Nr of Pages - ,All - ,6 - ,78 - ,80 - ,1 - ,false); -#else - check = MySchemaOp->createTable( "LONG_REC" - ,8 // Table Size - ,TupleKey // Key Type - ,40 // Nr of Pages - ); -#endif - - if (check == -1) goto error_handler; - - ndbout << "Key attribute..." ; - check = MySchemaOp->createAttribute( (char*)"Key", TupleKey, 32, 1, - UnSigned, MMBased, NotNullAttribute ); - if (check == -1) goto error_handler; - ndbout << "\t\tOK" << endl ; - - ndbout << "Flip attribute..." ; - check = MySchemaOp->createAttribute("Flip", NoKey, 32, 1, - UnSigned, MMBased, NotNullAttribute ); - if (check == -1) goto error_handler; - ndbout << "\t\tOK" << endl ; - - ndbout << "Count attribute..." ; - check = MySchemaOp->createAttribute("Count", NoKey, 32, 1, - UnSigned, MMBased, NotNullAttribute ); - if (check == -1) goto error_handler; - ndbout << "\t\tOK" << endl ; - - ndbout << "Placeholder attribute..." ; - check = MySchemaOp->createAttribute("Placeholder", NoKey, 8, 1014, - UnSigned, MMBased, NotNullAttribute ); - if (check == -1) goto error_handler; - ndbout << "\tOK" << endl ; - - if (MySchemaTransaction->execute() == -1) { - if(721 == MySchemaOp->getNdbError().code){ - ndbout << "Table LONG_REC already exists" << endl ; - }else{ - ndbout << MySchemaTransaction->getNdbError() << endl; - } - }else{ - ndbout << "LONG_REC created" << endl; - }// if - - pNdb->closeSchemaTransaction(MySchemaTransaction); - - - check = InsertRecords(pNdb, tNoOfRecords); - - delete pNdb ; - - if(-1 == check){ - ndbout << endl << "Initial loading of Ronja Database failed" << endl; - return NDBT_ProgramExit(NDBT_FAILED) ; - }else{ - ndbout << endl << "Initial loading of Ronja Database completed" << endl; - return NDBT_ProgramExit(NDBT_OK) ; - } - - - - - -error_handler: - ndbout << "SchemaTransaction returned error:" ; - ndbout << MySchemaTransaction->getNdbError() << endl; - pNdb->closeSchemaTransaction(MySchemaTransaction); - delete pNdb ; - NDBT_ProgramExit(NDBT_FAILED) ; - exit(-1); - -error_input: - ndbout << endl << " Ivalid parameter(s)" << endl; - ndbout << " Usage: initronja [-r n] , where 'n' is the number of records to be inserted" << endl; - ndbout << " If omitted, 500 records will be created by default" << endl; - ndbout << " Note: use this number in combination with '-r' argument when running 'benchronja'" << endl << endl; - NDBT_ProgramExit(NDBT_WRONGARGS) ; - exit(1); -} -//////////////////////////////////////// - -inline int InsertRecords(Ndb* pNdb, int nNoRecords){ - - NdbConnection *MyTransaction = NULL ; - NdbOperation* MyOperation[10]; - - int Tsuccess = 0 ; - int loop_count_ops = 2 * tNoOfLoops; - int loop_count_tables = 10; - int loop_count_attributes = 0 ; - int check = 0; - int count = 0 ; - int count_tables = 0; - int count_attributes = 0 ; - int i = 0 ; - int tType = 0 ; - unsigned int attrValue[1000]; - unsigned int setAttrValue = 0; - unsigned int keyValue[3]; - - for (i = 0; i < 1000; i ++) attrValue[i] = 1; - - for (count=0 ; count < loop_count_ops ; count++){ - if ((((count / 100)* 100) == count) && (count != 0)){ - ndbout << "1000 records inserted again, " << (count/100) << "000 records now inserted" << endl; - } - - MyTransaction = pNdb->startTransaction(); - if(!MyTransaction){ - ndbout << "startTransaction: " << pNdb->getNdbError(); - ndbout << " count = " << count << endl; - return -1 ; - } - - for (count_tables = 0; count_tables < loop_count_tables; count_tables++) { - if (count < tNoOfLoops) { - keyValue[0] = count*10 + count_tables ; - MyOperation[count_tables] = MyTransaction->getNdbOperation("SHORT_REC") ; - }else{ - keyValue[0] = (count - tNoOfLoops)*10 + count_tables; - MyOperation[count_tables] = MyTransaction->getNdbOperation("LONG_REC"); - }//if - - if (!MyOperation[count_tables]) goto error_handler1; - - check = MyOperation[count_tables]->insertTuple(); - if (check == -1) goto error_handler2; - - check = MyOperation[count_tables]->equal("Key",(char*)&keyValue[0]); - if (check == -1) goto error_handler4; - - check = MyOperation[count_tables]->setValue("Flip",(char*)&setAttrValue); - if (check == -1) goto error_handler5; - - check = MyOperation[count_tables]->setValue("Count",(char*)&setAttrValue); - if (check == -1) goto error_handler5; - - check = MyOperation[count_tables]->setValue("Placeholder",(char*)&attrValue[0]); - if (check == -1) goto error_handler5; - }//for - - if (MyTransaction->execute( Commit ) == -1){ - ndbout << MyTransaction->getNdbError()<< endl ; - ndbout << "count = " << count << endl; - }//if - - pNdb->closeTransaction(MyTransaction) ; - }//for - return 0; - -error_handler1: - ndbout << "Error occured in getNdbOperation " << endl; - ndbout << MyTransaction->getNdbError() << endl; - pNdb->closeTransaction(MyTransaction); - return -1 ; - -error_handler2: - ndbout << "Error occured in defining operation " << endl; - ndbout << MyOperation[count_tables]->getNdbError() << endl; - pNdb->closeTransaction(MyTransaction); - return -1 ; - -error_handler3: - pNdb->closeTransaction(MyTransaction); - return -1 ; - -error_handler4: - ndbout << "Error occured in equal " << endl; - ndbout << MyOperation[count_tables]->getNdbError() << endl; - pNdb->closeTransaction(MyTransaction); - return -1 ; - -error_handler5: - ndbout << "Error occured in get/setValue " << endl; - ndbout << MyOperation[count_tables]->getNdbError() << endl; - pNdb->closeTransaction(MyTransaction); - return -1 ; - -} diff --git a/ndb/test/ndbapi/size.cpp b/ndb/test/ndbapi/size.cpp new file mode 100644 index 00000000000..c506771ebde --- /dev/null +++ b/ndb/test/ndbapi/size.cpp @@ -0,0 +1,27 @@ +/* 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 */ + +#include +#include "utv.h" + +int main(void) +{ + printf("cdrstruct=%d\n",sizeof(struct cdr_record)); + printf("long int=%d\n",sizeof(long int)); + printf("int=%d\n",sizeof(int)); + printf("short int=%d\n",sizeof(short int)); + return 0; +} diff --git a/ndb/test/ndbapi/telco/InsertRecs.cpp b/ndb/test/ndbapi/telco/InsertRecs.cpp deleted file mode 100644 index f42786d666d..00000000000 --- a/ndb/test/ndbapi/telco/InsertRecs.cpp +++ /dev/null @@ -1,571 +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 */ - -// InsertRecs.cpp : Defines the entry point for the console application. -// - - -#include -#include -#include - - -// data for CALL_CONTEXT and GROUP_RESOURCE -static TCHAR STATUS_DATA[]=_T("000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F") - _T("101112131415161718191A1B1C1D1E1F000102030405060708090A0B0C0D0E0F") - _T("202122232425262728292A2B2C2D2E2F000102030405060708090A0B0C0D0E0F") - _T("303132333435363738393A3B3C3D3E3F000102030405060708090A0B0C0D0E0F") - _T("404142434445464748494A4B4C4D4E4F000102030405060708090A0B0C0D0E0F") - _T("505152535455565758595A5B5C5D5E5F000102030405060708090A0B0C0D0E0F") - _T("606162636465666768696A6B6C6D6E6F000102030405060708090A0B0C0D0E0F") - _T("707172737475767778797A7B7C7D7E7F000102030405060708090A0B0C0D0E0F") - _T("808182838485868788898A8B8C8D8E8F000102030405060708090A0B0C0D0E0F") - _T("909192939495969798999A9B9C9D9E9F000102030405060708090A0B0C0D0E0F") - _T("10010110210310410510610710810910A000102030405060708090A0B0C0D0EF") - _T("10B10C10D10E10F110111112113114115000102030405060708090A0B0C0D0EF") - _T("11611711811911A11B11C11D11E11F120000102030405060708090A0B0C0D0EF") - _T("12112212312412512612712812912A12B000102030405060708090A0B0C0D0EF") - _T("12C12D12E12F130131132134135136137000102030405060708090A0B0C0D0EF") - _T("13813913A13B13C13D13E13F140141142000102030405060708090A0B0C0D0EF") - _T("14314414514614714814914A14B14C14D000102030405060708090A0B0C0D0EF") - _T("14E14F150151152153154155156157158000102030405060708090A0B0C0D0EF") - _T("15915A15B15C15D15E15F160161162163000102030405060708090A0B0C0D0EF") - _T("16416516616716816916A16B16C16D16E000102030405060708090A0B0C0D0EF") - _T("16F170171172173174175176177178179000102030405060708090A0B0C0D0EF") - _T("17A17B17C17D17E17F180181182183184000102030405060708090A0B0C0D0EF") - _T("18518618718818918A18B18C18D18E18F000102030405060708090A0B0C0D0EF") - _T("19019119219319419519619719819919A000102030405060708090A0B0C0D0EF") - _T("19B19C19D19E19F200201202203204205000102030405060708090A0B0C0D0EF") - _T("20620720820920A20B20C20D20F210211000102030405060708090A0B0C0D0EF") - _T("21221321421521621721821921A21B21C000102030405060708090A0B0C0D0EF") - _T("21D21E21F220221222223224225226227000102030405060708090A0B0C0D0EF") - _T("22822922A22B22C22D22E22F230231232000102030405060708090A0B0C0D0EF") - _T("23323423523623723823923A23B23C23D000102030405060708090A0B0C0D0EF") - _T("23E23F240241242243244245246247248000102030405060708090A0B0C0D0EF") - _T("24924A24B24C24D24E24F250251252253000102030405060708090A0B0C0D0EF") - _T("101112131415161718191A1B1C1D1E1F000102030405060708090A0B0C0D0E0F") - _T("202122232425262728292A2B2C2D2E2F000102030405060708090A0B0C0D0E0F") - _T("303132333435363738393A3B3C3D3E3F000102030405060708090A0B0C0D0E0F") - _T("404142434445464748494A4B4C4D4E4F000102030405060708090A0B0C0D0E0F") - _T("505152535455565758595A5B5C5D5E5F000102030405060708090A0B0C0D0E0F") - _T("606162636465666768696A6B6C6D6E6F000102030405060708090A0B0C0D0E0F") - _T("707172737475767778797A7B7C7D7E7F000102030405060708090A0B0C0D0E0F") - _T("808182838485868788898A8B8C8D8E8F000102030405060708090A0B0C0D0E0F") - _T("909192939495969798999A9B9C9D9E9F000102030405060708090A0B0C0D0E0F") - _T("10010110210310410510610710810910A000102030405060708090A0B0C0D0EF") - _T("10B10C10D10E10F110111112113114115000102030405060708090A0B0C0D0EF") - _T("11611711811911A11B11C11D11E11F120000102030405060708090A0B0C0D0EF") - _T("12112212312412512612712812912A12B000102030405060708090A0B0C0D0EF") - _T("12C12D12E12F130131132134135136137000102030405060708090A0B0C0D0EF") - _T("13813913A13B13C13D13E13F140141142000102030405060708090A0B0C0D0EF") - _T("14314414514614714814914A14B14C14D000102030405060708090A0B0C0D0EF") - _T("14E14F150151152153154155156157158000102030405060708090A0B0C0D0EF") - _T("15915A15B15C15D15E15F160161162163000102030405060708090A0B0C0D0EF") - _T("16416516616716816916A16B16C16D16E000102030405060708090A0B0C0D0EF") - _T("16F170171172173174175176177178179000102030405060708090A0B0C0D0EF") - _T("17A17B17C17D17E17F180181182183184000102030405060708090A0B0C0D0EF") - _T("18518618718818918A18B18C18D18E18F000102030405060708090A0B0C0D0EF") - _T("19019119219319419519619719819919A000102030405060708090A0B0C0D0EF") - _T("19B19C19D19E19F200201202203204205000102030405060708090A0B0C0D0EF") - _T("20620720820920A20B20C20D20F210211000102030405060708090A0B0C0D0EF") - _T("21221321421521621721821921A21B21C000102030405060708090A0B0C0D0EF") - _T("21D21E21F220221222223224225226227000102030405060708090A0B0C0D0EF") - _T("22822922A22B22C22D22E22F230231232000102030405060708090A0B0C0D0EF") - _T("23323423523623723823923A23B23C23D000102030405060708090A0B0C0D0EF") - _T("2366890FE1438751097E7F6325DC0E6326F") - _T("25425525625725825925A25B25C25D25E25F000102030405060708090A0B0C0F"); -// Thread function for Call Context Inserts - -struct _ParamStruct -{ - HANDLE hShutdownEvent; - int nStartingRecordNum; - long* pnNumCallsProcessed; -}; - -HANDLE hShutdownEvent = 0; - -BOOL WINAPI ConsoleCtrlHandler(DWORD dwCtrlType) -{ - if(CTRL_C_EVENT == dwCtrlType) - { - SetEvent(hShutdownEvent); - return TRUE; - } - return FALSE; -} - - - - -DWORD WINAPI RuntimeCallContext(LPVOID lpParam) -{ - long nNumCallsProcessed = 0; - - struct _ParamStruct* pData = (struct _ParamStruct*)lpParam; - int nStartingRecordID = pData->nStartingRecordNum; - - Ndb* pNdb; - NdbConnection* pNdbConnection; - NdbOperation* pNdbOperation; - NdbRecAttr* pNdbRecAttrContextData; - - char pchContextData[4008]; - - LARGE_INTEGER freq; - LARGE_INTEGER liStartTime, liEndTime; - - pNdb = new Ndb("TEST_DB"); - if(!pNdb) - { - printf("new Ndb failed\n"); - return 0; - } - - try - { - if(pNdb->init(1) - || pNdb->waitUntilReady()) - { - throw pNdb; - } - - while(WaitForSingleObject(pData->hShutdownEvent,0) != WAIT_OBJECT_0) - { - nStartingRecordID++; - - bool bTimeLatency = (nStartingRecordID == 100) ? TRUE : FALSE; - - if (bTimeLatency) - { - BOOL bSuccess = QueryPerformanceFrequency(&freq); - if (!bSuccess) - printf("Error retrieving frequency: %d\n", GetLastError()); - - } - - for (int i=0; i < 20; i++) - { - switch(i) - { - case 3: - case 6: - case 9: - case 11: - case 12: - case 15: - case 18: // Query Record - if (bTimeLatency) - QueryPerformanceCounter(&liStartTime); - - pNdbConnection = pNdb->startTransaction((Uint32)0, (const char*)&nStartingRecordID, (Uint32)4); - if(!pNdbConnection) - { - throw pNdb; - } - pNdbOperation = pNdbConnection->getNdbOperation(_T("CallContext")); - if(!pNdbOperation) - { - throw pNdbConnection; - } - if(pNdbOperation->readTuple() - || pNdbOperation->equal(_T("ContextId"), nStartingRecordID)) - { - throw pNdbOperation; - } - pNdbRecAttrContextData = pNdbOperation->getValue(_T("ContextData"), pchContextData); - if(!pNdbRecAttrContextData) - { - throw pNdbOperation; - } - if(pNdbConnection->execute(Commit)) - { - throw pNdbConnection; - } - pNdb->closeTransaction(pNdbConnection); - - if (bTimeLatency) - { - QueryPerformanceCounter(&liEndTime); - printf("Read = %d msec.\n", (liEndTime.QuadPart - liStartTime.QuadPart) / (freq.QuadPart/1000)); - } - break; - - case 19: // Delete Record - if (bTimeLatency) - QueryPerformanceCounter(&liStartTime); - - pNdbConnection = pNdb->startTransaction((Uint32)0, (const char*)&nStartingRecordID, (Uint32)4); - if(!pNdbConnection) - { - throw pNdb; - } - pNdbOperation = pNdbConnection->getNdbOperation(_T("CallContext")); - if(!pNdbOperation) - { - throw pNdbConnection; - } - if(pNdbOperation->deleteTuple() - || pNdbOperation->equal(_T("ContextId"), nStartingRecordID)) - { - throw pNdbOperation; - } - if(pNdbConnection->execute(Commit)) - { - throw pNdbConnection; - } - pNdb->closeTransaction(pNdbConnection); - - if (bTimeLatency) - { - QueryPerformanceCounter(&liEndTime); - printf("Delete = %d msec.\n", (liEndTime.QuadPart - liStartTime.QuadPart) / (freq.QuadPart/1000)); - } - break; - - case 0: // Insert Record - if (bTimeLatency) - QueryPerformanceCounter(&liStartTime); - - pNdbConnection = pNdb->startTransaction((Uint32)0, (const char*)&nStartingRecordID, (Uint32)4); - if(!pNdbConnection) - { - throw pNdb; - } - pNdbOperation = pNdbConnection->getNdbOperation(_T("CallContext")); - if(!pNdbOperation) - { - throw pNdbConnection; - } - if(pNdbOperation->insertTuple() - || pNdbOperation->equal(_T("ContextId"), nStartingRecordID) - || pNdbOperation->setValue(_T("Version"), Int32(1)) - || pNdbOperation->setValue(_T("LockFlag"), Int32(1)) - || pNdbOperation->setValue(_T("LockTime"), Int32(1)) - || pNdbOperation->setValue(_T("LockTimeUSec"), Int32(1)) - || pNdbOperation->setValue(_T("ContextData"), STATUS_DATA, sizeof(STATUS_DATA))) - { - throw pNdbOperation; - } - if(pNdbConnection->execute(Commit)) - { - throw pNdbConnection; - } - pNdb->closeTransaction(pNdbConnection); - - if (bTimeLatency) - { - QueryPerformanceCounter(&liEndTime); - printf("Insert = %d msec.\n", (liEndTime.QuadPart - liStartTime.QuadPart) / (freq.QuadPart/1000)); - } - break; - - default: // Update Record - if (bTimeLatency) - QueryPerformanceCounter(&liStartTime); - - pNdbConnection = pNdb->startTransaction((Uint32)0, (const char*)&nStartingRecordID, (Uint32)4); - if(!pNdbConnection) - { - throw pNdb; - } - pNdbOperation = pNdbConnection->getNdbOperation(_T("CallContext")); - if(!pNdbOperation) - { - throw pNdbConnection; - } - if(pNdbOperation->updateTuple()) - { - throw pNdbOperation; - } - if(pNdbOperation->equal(_T("ContextId"), nStartingRecordID) - || pNdbOperation->setValue(_T("ContextData"), STATUS_DATA, sizeof(STATUS_DATA))) - { - throw pNdbOperation; - } - if(pNdbConnection->execute(Commit)) - { - throw pNdbConnection; - } - pNdb->closeTransaction(pNdbConnection); - - if (bTimeLatency) - { - QueryPerformanceCounter(&liEndTime); - printf("Update = %d msec.\n", (liEndTime.QuadPart - liStartTime.QuadPart) / (freq.QuadPart/1000)); - } - - break; - } - } - - nNumCallsProcessed++; - - InterlockedIncrement(pData->pnNumCallsProcessed); - } - - delete pNdb; - } - catch(Ndb* pNdb) - { - printf("%d: \n\t%s\n\t%s\n", - pNdb->getNdbError(), - pNdb->getNdbErrorString(), - "Ndb"); - delete pNdb; - } - catch(NdbConnection* pNdbConnection) - { - printf("%d: \n\t%s\n\t%s\n", - pNdbConnection->getNdbError(), - pNdbConnection->getNdbErrorString(), - "NdbConnection"); - pNdb->closeTransaction(pNdbConnection); - delete pNdb; - } - catch(NdbOperation* pNdbOperation) - { - printf("%d: \n\t%s\n\t%s\n", - pNdbOperation->getNdbError(), - pNdbOperation->getNdbErrorString(), - "NdbOperation"); - pNdb->closeTransaction(pNdbConnection); - delete pNdb; - } - - return 0; -} - - -void Initialize(Ndb* pNdb, long nInsert, bool bStoredTable) -{ - NdbSchemaCon* pNdbSchemaCon; - NdbSchemaOp* pNdbSchemaOp; - NdbConnection* pNdbConnection; - NdbOperation* pNdbOperation; - - try - { - _tprintf(_T("Create CallContext table\n")); - - pNdbSchemaCon = pNdb->startSchemaTransaction(); - if(!pNdbSchemaCon) - { - throw pNdb; - } - pNdbSchemaOp = pNdbSchemaCon->getNdbSchemaOp(); - if(!pNdbSchemaOp) - { - throw pNdbSchemaCon; - } - if(pNdbSchemaOp->createTable(_T("CallContext"), 8, TupleKey, 2, All, 6, 78, 80, 1, bStoredTable) - || pNdbSchemaOp->createAttribute(_T("ContextId"), TupleKey, 32, 1, Signed) - || pNdbSchemaOp->createAttribute(_T("Version"), NoKey, 32, 1, Signed) - || pNdbSchemaOp->createAttribute(_T("LockFlag"), NoKey, 32, 1, Signed) - || pNdbSchemaOp->createAttribute(_T("LockTime"), NoKey, 32, 1, Signed) - || pNdbSchemaOp->createAttribute(_T("LockTimeUSec"), NoKey, 32, 1, Signed) - || pNdbSchemaOp->createAttribute(_T("ContextData"), NoKey, 8, 4004, String)) - { - throw pNdbSchemaOp; - } - if(pNdbSchemaCon->execute()) - { - throw pNdbSchemaCon; - } - pNdb->closeSchemaTransaction(pNdbSchemaCon); - - _tprintf(_T("Insert %d tuples in the CallContext table\n"), nInsert); - for(long i=0; istartTransaction((Uint32)0, (const char*)&iContextId, (Uint32)4); - if(!pNdbConnection) - { - throw pNdb; - } - pNdbOperation = pNdbConnection->getNdbOperation(_T("CallContext")); - if(!pNdbOperation) - { - throw pNdbConnection; - } - if(pNdbOperation->insertTuple() - || pNdbOperation->equal(_T("ContextId"), iContextId) - || pNdbOperation->setValue(_T("Version"), Int32(1)) - || pNdbOperation->setValue(_T("LockFlag"), Int32(1)) - || pNdbOperation->setValue(_T("LockTime"), Int32(1)) - || pNdbOperation->setValue(_T("LockTimeUSec"), Int32(1)) - || pNdbOperation->setValue(_T("ContextData"), STATUS_DATA, sizeof(STATUS_DATA))) - { - throw pNdbOperation; - } - if(pNdbConnection->execute(Commit)) - { - throw pNdbConnection; - } - pNdb->closeTransaction(pNdbConnection); - } - _tprintf(_T("initialisation done\n")); - } - catch(Ndb* pNdb) - { - printf("%d: \n\t%s\n\t%s\n", - pNdb->getNdbError(), - pNdb->getNdbErrorString(), - "Ndb"); - delete pNdb; - } - catch(NdbConnection* pNdbConnection) - { - printf("%d: \n\t%s\n\t%s\n", - pNdbConnection->getNdbError(), - pNdbConnection->getNdbErrorString(), - "NdbConnection"); - pNdb->closeTransaction(pNdbConnection); - delete pNdb; - } - catch(NdbOperation* pNdbOperation) - { - printf("%d: \n\t%s\n\t%s\n", - pNdbOperation->getNdbError(), - pNdbOperation->getNdbErrorString(), - "NdbOperation"); - pNdb->closeTransaction(pNdbConnection); - delete pNdb; - } - catch(NdbSchemaCon* pNdbSchemaCon) - { - printf("%d: \n\t%s\n\t%s\n", - pNdbSchemaCon->getNdbError(), - pNdbSchemaCon->getNdbErrorString(), - "pNdbSchemaCon"); - pNdb->closeSchemaTransaction(pNdbSchemaCon); - delete pNdb; - } - catch(NdbSchemaOp* pNdbSchemaOp) - { - printf("%d: \n\t%s\n\t%s\n", - pNdbSchemaOp->getNdbError(), - pNdbSchemaOp->getNdbErrorString(), - "pNdbSchemaOp"); - pNdb->closeTransaction(pNdbConnection); - delete pNdb; - } -} - - -int _tmain(int argc, _TCHAR* argv[]) -{ - long nNumThreads=4; - long nSeed = 0; - long nInsert = 0; - bool bStoredTable = true; - if(lstrcmp(argv[1],_T("/?")) == 0) - { - _tprintf(_T("InsertRecs [No.Of Threads] [Record Seed No.] [Init no. of rec.] [Stored?]\n")); - return 0; - } - - if(argc > 1) - nNumThreads = _ttol(argv[1]); - else - nNumThreads = 4; - if (argc > 2) - nSeed = _ttol(argv[2]); - _tprintf(_T("Num of Threads = %d, Seed = %d"), nNumThreads, nSeed); - - if(argc>3) - nInsert = _ttol(argv[3]); - if(argc>4) - bStoredTable = (_ttol(argv[4])!=0); - - long nNumCallsProcessed = 0; - - SetConsoleCtrlHandler(ConsoleCtrlHandler,true); - hShutdownEvent = CreateEvent(NULL,TRUE,FALSE,NULL); - - // initiate windows sockets - WORD wVersionRequested; - WSADATA wsaData; - int err; - wVersionRequested = MAKEWORD( 2, 2 ); - err = WSAStartup( wVersionRequested, &wsaData ); - if ( err != 0 ) { - _tprintf(_T("could not find a usable WinSock DLL\n")); - return 0; - } - if ( LOBYTE( wsaData.wVersion ) != 2 - || HIBYTE( wsaData.wVersion ) != 2 ) - { - _tprintf(_T("could not find a usable WinSock DLL\n")); - WSACleanup(); - return 0; - } - - Ndb* pNdb = new Ndb("TEST_DB"); - if(!pNdb) - { - _tprintf(_T("could not construct ndb\n")); - return 0; - } - if(pNdb->init(1) - || pNdb->waitUntilReady()) - { - _tprintf(_T("could not initialize ndb\n")); - return 0; - } - - if(nInsert>0) - { - Initialize(pNdb, nInsert, bStoredTable); - } - - if(nNumThreads>0) - { - _tprintf(_T("creating %d threads\n"), nNumThreads); - DWORD dwStartTime = GetTickCount(); - - DWORD dwThreadID = 0; - HANDLE hThreads[50]; - - struct _ParamStruct params[50]; - - for(int ij=0;ijnStartingRecordNum; - - HRESULT hr = CoInitialize(NULL); - if(FAILED(hr)) - { - printf("Error Initializing COM Library\n"); - return (int)hr; - } - - _ConnectionPtr cn = NULL; - _CommandPtr cmdUpdate = NULL, cmdInsert = NULL, cmdDelete = NULL, cmdSelect = NULL; - _RecordsetPtr rs = NULL; - _ParameterPtr paramContextID = NULL; - _ParameterPtr paramVersion = NULL; - _ParameterPtr paramLockFlag = NULL; - _ParameterPtr ttparamLockFlag = NULL; - _ParameterPtr paramLockTime = NULL; - _ParameterPtr paramLockTimeUSec = NULL; - _ParameterPtr paramContextData = NULL; - _variant_t vtVersion; - _variant_t vtLockFlag; - _variant_t vtLockTime; - _variant_t vtLockTimeUSec; - _variant_t vtContextData; - // Initialize Values - vtVersion = CALL_CONTEXT_VERSION; - vtLockFlag = CALL_CONTEXT_LOCK_FLAG; - vtLockTime = CALL_CONTEXT_LOCK_TIME; - vtLockTimeUSec = CALL_CONTEXT_LOCK_TIME_USEC; - vtContextData = STATUS_DATA; - - LARGE_INTEGER freq; - - DWORD dwStartTime, dwEndTime; - LARGE_INTEGER liStartTime, liEndTime; - - try - { - cn.CreateInstance(__uuidof(Connection)); - cn->ConnectionString = _T("DSN=TTTelcoCS;"); - cn->Open(_T(""),_T(""),_T(""),adConnectUnspecified); - - cmdUpdate.CreateInstance(__uuidof(Command)); - cmdInsert.CreateInstance(__uuidof(Command)); - cmdDelete.CreateInstance(__uuidof(Command)); - cmdSelect.CreateInstance(__uuidof(Command)); - - TCHAR tszInsert[10000], tszUpdate[10000]; - memset(tszInsert, 0, sizeof(tszInsert)); - memset(tszUpdate, 0, sizeof(tszUpdate)); - strcpy(tszInsert, "INSERT INTO dbo.CallContext(ContextId,Version,LockFlag,LockTime,LockTimeUSec,ContextData) VALUES(?,?,?,?,?,'"); - strcat(tszInsert, STATUS_DATA); - strcat(tszInsert, "')"); - - cmdInsert->CommandText= tszInsert; - cmdInsert->ActiveConnection = cn; - cmdInsert->Prepared = TRUE; - - - strcpy(tszUpdate, "UPDATE dbo.CallContext SET ContextData = '"); - strcat(tszUpdate, STATUS_DATA); - strcat(tszUpdate, "' WHERE ContextId = ?"); - cmdUpdate->CommandText= tszUpdate; - cmdUpdate->ActiveConnection = cn; - cmdUpdate->Prepared = TRUE; - - cmdDelete->CommandText=_T("DELETE FROM dbo.CallContext WHERE ContextId = ?"); - cmdDelete->ActiveConnection = cn; - cmdDelete->Prepared = TRUE; - - cmdSelect->CommandText=_T("SELECT ContextData FROM dbo.CallContext WHERE ContextId = ?"); - cmdSelect->ActiveConnection = cn; - cmdSelect->Prepared = TRUE; - - - //Create params - paramContextID = cmdInsert->CreateParameter(_T("ContextID"),adInteger,adParamInput,sizeof(int),nStartingRecordID); - paramVersion = cmdInsert->CreateParameter(_T("Version"),adInteger,adParamInput,sizeof(int),1);//vtVersion); - paramLockFlag = cmdInsert->CreateParameter(_T("LockFlag"),adInteger,adParamInput,sizeof(int),1);//vtLockFlag); - ttparamLockFlag = cmdUpdate->CreateParameter(_T("LockFlag"),adInteger,adParamInput,sizeof(int),1);//vtLockFlag); - paramLockTime = cmdInsert->CreateParameter(_T("LockTime"),adInteger,adParamInput,sizeof(int),1);//vtLockTime); - paramLockTimeUSec = cmdInsert->CreateParameter(_T("LockTimeUSec"),adInteger,adParamInput,sizeof(int),1);//vtLockTimeUSec); - paramContextData = cmdInsert->CreateParameter(_T("ContextData"), adBSTR, adParamInput, SysStringByteLen(vtContextData.bstrVal), vtContextData); - //paramContextData->put_Value(vtContextData); - - - - //Append params - cmdInsert->Parameters->Append(paramContextID); - cmdInsert->Parameters->Append(paramVersion); - cmdInsert->Parameters->Append(paramLockFlag); - cmdInsert->Parameters->Append(paramLockTime); - cmdInsert->Parameters->Append(paramLockTimeUSec); - //cmdInsert->Parameters->Append(paramContextData); - - - cmdUpdate->Parameters->Append(paramContextID); - //cmdUpdate->Parameters->Append(paramContextID); - - cmdSelect->Parameters->Append(paramContextID); - - cmdDelete->Parameters->Append(paramContextID); - - while(WaitForSingleObject(pData->hShutdownEvent,0) != WAIT_OBJECT_0) - { - paramContextID->Value = nStartingRecordID++; - - bool bTimeLatency = (nStartingRecordID == 100) ? TRUE : FALSE; - - if (bTimeLatency) - { - BOOL bSuccess = QueryPerformanceFrequency(&freq); - if (!bSuccess) - printf("Error retrieving frequency: %d\n", GetLastError()); - - } - - - - for (int i=0; i < 20; i++) - { - switch(i) - { - case 3: - case 6: - case 9: - case 11: - case 12: - case 15: - case 18: // Query Record - if (bTimeLatency) - QueryPerformanceCounter(&liStartTime); - - cmdSelect->Execute(NULL, NULL, -1); - if (bTimeLatency) - { - QueryPerformanceCounter(&liEndTime); - printf("Read = %d msec.\n", (liEndTime.QuadPart - liStartTime.QuadPart) / (freq.QuadPart/1000)); - } - break; - case 19: // Delete Record - if (bTimeLatency) - QueryPerformanceCounter(&liStartTime); - cmdDelete->Execute(NULL,NULL,adExecuteNoRecords); - if (bTimeLatency) - { - QueryPerformanceCounter(&liEndTime); - printf("Delete = %d msec.\n", (liEndTime.QuadPart - liStartTime.QuadPart) / (freq.QuadPart/1000)); - } - break; - case 0: // Insert Record - if (bTimeLatency) - QueryPerformanceCounter(&liStartTime); - cmdInsert->Execute(NULL,NULL,adExecuteNoRecords); - if (bTimeLatency) - { - QueryPerformanceCounter(&liEndTime); - printf("Insert = %d msec.\n", (liEndTime.QuadPart - liStartTime.QuadPart) / (freq.QuadPart/1000)); - } - break; - default: // Update Record - if (bTimeLatency) - QueryPerformanceCounter(&liStartTime); - cmdUpdate->Execute(NULL,NULL,adExecuteNoRecords); - if (bTimeLatency) - { - QueryPerformanceCounter(&liEndTime); - printf("Update = %d msec.\n", (liEndTime.QuadPart - liStartTime.QuadPart) / (freq.QuadPart/1000)); - } - - break; - } - } - - nNumCallsProcessed++; - - InterlockedIncrement(pData->pnNumCallsProcessed); - } - - cn->Close(); - } - catch(_com_error &e) - { - printf("%d: \n\t%s\n\t%s\n", - e.Error(), - e.ErrorMessage(), - e.Source()); - - } - - return 0; -} - - -int _tmain(int argc, _TCHAR* argv[]) -{ - long nNumThreads=4; - long nSeed = 0; - if(lstrcmp(argv[1],_T("/?")) == 0) - { - _tprintf(_T("InsertRecs [No.Of Threads] [Record Seed No.]\n")); - return 0; - } - - if(argc > 1) - nNumThreads = _ttol(argv[1]); - else - nNumThreads = 4; - if (argc > 2) - nSeed = _ttol(argv[2]); - _tprintf(_T("Num of Threads = %d, Seed = %d"), nNumThreads, nSeed); - - long nNumCallsProcessed = 0; - - SetConsoleCtrlHandler(ConsoleCtrlHandler,true); - hShutdownEvent = CreateEvent(NULL,TRUE,FALSE,NULL); - - DWORD dwStartTime = GetTickCount(); - - DWORD dwThreadID = 0; - HANDLE hThreads[50]; - - struct _ParamStruct params[50]; - - - for(int ij=0;ij - -#include -#include -#include -#include -#include -#include - -const char* const c_szDatabaseName = "TEST_DB"; - -const char* const c_szTableNameStored = "CCStored"; -const char* const c_szTableNameTemp = "CCTemp"; - -const char* const c_szContextId = "ContextId"; -const char* const c_szVersion = "Version"; -const char* const c_szLockFlag = "LockFlag"; -const char* const c_szLockTime = "LockTime"; -const char* const c_szLockTimeUSec = "LockTimeUSec"; -const char* const c_szContextData = "ContextData"; - -const char* g_szTableName = c_szTableNameStored; - - -#ifdef NDB_WIN32 -HANDLE hShutdownEvent = 0; -#else -#include -bool bShutdownEvent = false; -#endif -long g_nMaxContextIdPerThread = 5000; -long g_nNumThreads = 0; -long g_nMaxCallsPerSecond = 0; -long g_nMaxRetry = 50; -bool g_bWriteTuple = false; -bool g_bInsertInitial = false; -bool g_bVerifyInitial = false; - -NdbMutex* g_pNdbMutexPrintf = 0; -NdbMutex* g_pNdbMutexIncrement = 0; -long g_nNumCallsProcessed = 0; -NDB_TICKS g_tStartTime = 0; -NDB_TICKS g_tEndTime = 0; - -long g_nNumberOfInitialInsert = 0; -long g_nNumberOfInitialVerify = 0; - -const long c_nMaxMillisecForAllCall = 5000; -long* g_plCountMillisecForCall = 0; -const long c_nMaxMillisecForAllTrans = 5000; -long* g_plCountMillisecForTrans = 0; -bool g_bReport = false; -bool g_bReportPlus = false; - - -// data for CALL_CONTEXT and GROUP_RESOURCE -static char STATUS_DATA[]= -"000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F" -"101112131415161718191A1B1C1D1E1F000102030405060708090A0B0C0D0E0F" -"202122232425262728292A2B2C2D2E2F000102030405060708090A0B0C0D0E0F" -"303132333435363738393A3B3C3D3E3F000102030405060708090A0B0C0D0E0F" -"404142434445464748494A4B4C4D4E4F000102030405060708090A0B0C0D0E0F" -"505152535455565758595A5B5C5D5E5F000102030405060708090A0B0C0D0E0F" -"606162636465666768696A6B6C6D6E6F000102030405060708090A0B0C0D0E0F" -"707172737475767778797A7B7C7D7E7F000102030405060708090A0B0C0D0E0F" -"808182838485868788898A8B8C8D8E8F000102030405060708090A0B0C0D0E0F" -"909192939495969798999A9B9C9D9E9F000102030405060708090A0B0C0D0E0F" -"10010110210310410510610710810910A000102030405060708090A0B0C0D0EF" -"10B10C10D10E10F110111112113114115000102030405060708090A0B0C0D0EF" -"11611711811911A11B11C11D11E11F120000102030405060708090A0B0C0D0EF" -"12112212312412512612712812912A12B000102030405060708090A0B0C0D0EF" -"12C12D12E12F130131132134135136137000102030405060708090A0B0C0D0EF" -"13813913A13B13C13D13E13F140141142000102030405060708090A0B0C0D0EF" -"14314414514614714814914A14B14C14D000102030405060708090A0B0C0D0EF" -"14E14F150151152153154155156157158000102030405060708090A0B0C0D0EF" -"15915A15B15C15D15E15F160161162163000102030405060708090A0B0C0D0EF" -"16416516616716816916A16B16C16D16E000102030405060708090A0B0C0D0EF" -"16F170171172173174175176177178179000102030405060708090A0B0C0D0EF" -"17A17B17C17D17E17F180181182183184000102030405060708090A0B0C0D0EF" -"18518618718818918A18B18C18D18E18F000102030405060708090A0B0C0D0EF" -"19019119219319419519619719819919A000102030405060708090A0B0C0D0EF" -"19B19C19D19E19F200201202203204205000102030405060708090A0B0C0D0EF" -"20620720820920A20B20C20D20F210211000102030405060708090A0B0C0D0EF" -"21221321421521621721821921A21B21C000102030405060708090A0B0C0D0EF" -"21D21E21F220221222223224225226227000102030405060708090A0B0C0D0EF" -"22822922A22B22C22D22E22F230231232000102030405060708090A0B0C0D0EF" -"23323423523623723823923A23B23C23D000102030405060708090A0B0C0D0EF" -"23E23F240241242243244245246247248000102030405060708090A0B0C0D0EF" -"24924A24B24C24D24E24F250251252253000102030405060708090A0B0C0D0EF" -"101112131415161718191A1B1C1D1E1F000102030405060708090A0B0C0D0E0F" -"202122232425262728292A2B2C2D2E2F000102030405060708090A0B0C0D0E0F" -"303132333435363738393A3B3C3D3E3F000102030405060708090A0B0C0D0E0F" -"404142434445464748494A4B4C4D4E4F000102030405060708090A0B0C0D0E0F" -"505152535455565758595A5B5C5D5E5F000102030405060708090A0B0C0D0E0F" -"606162636465666768696A6B6C6D6E6F000102030405060708090A0B0C0D0E0F" -"707172737475767778797A7B7C7D7E7F000102030405060708090A0B0C0D0E0F" -"808182838485868788898A8B8C8D8E8F000102030405060708090A0B0C0D0E0F" -"909192939495969798999A9B9C9D9E9F000102030405060708090A0B0C0D0E0F" -"10010110210310410510610710810910A000102030405060708090A0B0C0D0EF" -"10B10C10D10E10F110111112113114115000102030405060708090A0B0C0D0EF" -"11611711811911A11B11C11D11E11F120000102030405060708090A0B0C0D0EF" -"12112212312412512612712812912A12B000102030405060708090A0B0C0D0EF" -"12C12D12E12F130131132134135136137000102030405060708090A0B0C0D0EF" -"13813913A13B13C13D13E13F140141142000102030405060708090A0B0C0D0EF" -"14314414514614714814914A14B14C14D000102030405060708090A0B0C0D0EF" -"14E14F150151152153154155156157158000102030405060708090A0B0C0D0EF" -"15915A15B15C15D15E15F160161162163000102030405060708090A0B0C0D0EF" -"16416516616716816916A16B16C16D16E000102030405060708090A0B0C0D0EF" -"16F170171172173174175176177178179000102030405060708090A0B0C0D0EF" -"17A17B17C17D17E17F180181182183184000102030405060708090A0B0C0D0EF" -"18518618718818918A18B18C18D18E18F000102030405060708090A0B0C0D0EF" -"19019119219319419519619719819919A000102030405060708090A0B0C0D0EF" -"19B19C19D19E19F200201202203204205000102030405060708090A0B0C0D0EF" -"20620720820920A20B20C20D20F210211000102030405060708090A0B0C0D0EF" -"21221321421521621721821921A21B21C000102030405060708090A0B0C0D0EF" -"21D21E21F220221222223224225226227000102030405060708090A0B0C0D0EF" -"22822922A22B22C22D22E22F230231232000102030405060708090A0B0C0D0EF" -"23323423523623723823923A23B23C23D000102030405060708090A0B0C0D0EF" -"2366890FE1438751097E7F6325DC0E6326F" -"25425525625725825925A25B25C25D25E25F000102030405060708090A0B0C0F"; - -long g_nStatusDataSize = sizeof(STATUS_DATA); - - -// Thread function for Call Context Inserts - - -#ifdef NDB_WIN32 - -BOOL WINAPI ConsoleCtrlHandler(DWORD dwCtrlType) -{ - if(CTRL_C_EVENT == dwCtrlType) - { - SetEvent(hShutdownEvent); - return TRUE; - } - return FALSE; -} - -#else - -void CtrlCHandler(int) -{ - bShutdownEvent = true; -} - -#endif - - - -void ReportNdbError(const char* szMsg, const NdbError& err) -{ - NdbMutex_Lock(g_pNdbMutexPrintf); - printf("%s: %d: %s\n", szMsg, err.code, (err.message ? err.message : "")); - NdbMutex_Unlock(g_pNdbMutexPrintf); -} - - -void -ReportCallsPerSecond(long nNumCallsProcessed, - NDB_TICKS tStartTime, - NDB_TICKS tEndTime) -{ - NDB_TICKS tElapsed = tEndTime - tStartTime; - long lCallsPerSec; - if(tElapsed>0) - lCallsPerSec = (long)((1000*nNumCallsProcessed)/tElapsed); - else - lCallsPerSec = 0; - - NdbMutex_Lock(g_pNdbMutexPrintf); - printf("Time Taken for %ld Calls is %ld msec (= %ld calls/sec)\n", - nNumCallsProcessed, (long)tElapsed, lCallsPerSec); - NdbMutex_Unlock(g_pNdbMutexPrintf); -} - - -#ifndef NDB_WIN32 -void InterlockedIncrement(long* lp) // expensive -{ - NdbMutex_Lock(g_pNdbMutexIncrement); - (*lp)++; - NdbMutex_Unlock(g_pNdbMutexIncrement); -} -#endif - - -void InterlockedIncrementAndReport(void) -{ - NdbMutex_Lock(g_pNdbMutexIncrement); - ++g_nNumCallsProcessed; - if((g_nNumCallsProcessed%1000)==0) - { - g_tEndTime = NdbTick_CurrentMillisecond(); - if(g_tStartTime) - ReportCallsPerSecond(1000, g_tStartTime, g_tEndTime); - - g_tStartTime = g_tEndTime; - } - NdbMutex_Unlock(g_pNdbMutexIncrement); -} - - -void SleepOneCall(void) -{ - int iMillisecToSleep; - if(g_nMaxCallsPerSecond>0) - iMillisecToSleep = (1000*g_nNumThreads)/g_nMaxCallsPerSecond; - else - iMillisecToSleep = 50; - - if(iMillisecToSleep>0) - NdbSleep_MilliSleep(iMillisecToSleep); - -} - - - -int QueryTransaction(Ndb* pNdb, - long iContextId, - long* piVersion, - long* piLockFlag, - long* piLockTime, - long* piLockTimeUSec, - char* pchContextData, - NdbError& err) -{ - int iRes = -1; - NdbConnection* pNdbConnection = pNdb->startTransaction(0, (const char*)&iContextId, 4); - if(pNdbConnection) - { - NdbOperation* pNdbOperation = pNdbConnection->getNdbOperation(g_szTableName); - if(pNdbOperation) - { - NdbRecAttr* pNdbRecAttrVersion; - NdbRecAttr* pNdbRecAttrLockFlag; - NdbRecAttr* pNdbRecAttrLockTime; - NdbRecAttr* pNdbRecAttrLockTimeUSec; - NdbRecAttr* pNdbRecAttrContextData; - if(!pNdbOperation->readTuple() - && !pNdbOperation->equal(c_szContextId, (Int32)iContextId) - && (pNdbRecAttrVersion=pNdbOperation->getValue(c_szVersion, (char*)piVersion)) - && (pNdbRecAttrLockFlag=pNdbOperation->getValue(c_szLockFlag, (char*)piLockFlag)) - && (pNdbRecAttrLockTime=pNdbOperation->getValue(c_szLockTime, (char*)piLockTime)) - && (pNdbRecAttrLockTimeUSec=pNdbOperation->getValue(c_szLockTimeUSec, (char*)piLockTimeUSec)) - && (pNdbRecAttrContextData=pNdbOperation->getValue(c_szContextData, pchContextData))) - { - if(!pNdbConnection->execute(Commit)) - iRes = 0; - else - err = pNdbConnection->getNdbError(); - } - else - err = pNdbOperation->getNdbError(); - } - else - err = pNdbConnection->getNdbError(); - - pNdb->closeTransaction(pNdbConnection); - } - else - err = pNdb->getNdbError(); - - return iRes; -} - - -int RetryQueryTransaction(Ndb* pNdb, - long iContextId, - long* piVersion, - long* piLockFlag, - long* piLockTime, - long* piLockTimeUSec, - char* pchContextData, - NdbError& err, - int& nRetry) -{ - int iRes = -1; - nRetry = 0; - bool bRetry = true; - while(bRetry && nRetrystartTransaction(0, (const char*)&iContextId, 4); - if(pNdbConnection) - { - NdbOperation* pNdbOperation = pNdbConnection->getNdbOperation(g_szTableName); - if(pNdbOperation) - { - if(!pNdbOperation->deleteTuple() - && !pNdbOperation->equal(c_szContextId, (Int32)iContextId)) - { - if(pNdbConnection->execute(Commit) == 0) - iRes = 0; - else - err = pNdbConnection->getNdbError(); - } - else - err = pNdbOperation->getNdbError(); - } - else - err = pNdbConnection->getNdbError(); - - pNdb->closeTransaction(pNdbConnection); - } - else - err = pNdb->getNdbError(); - - return iRes; -} - - - -int RetryDeleteTransaction(Ndb* pNdb, long iContextId, NdbError& err, int& nRetry) -{ - int iRes = -1; - nRetry = 0; - bool bRetry = true; - bool bUnknown = false; - while(bRetry && nRetrystartTransaction(0, (const char*)&iContextID, 4); - if(pNdbConnection) - { - NdbOperation* pNdbOperation = pNdbConnection->getNdbOperation(g_szTableName); - if(pNdbOperation) - { - if(!(g_bWriteTuple ? pNdbOperation->writeTuple() : pNdbOperation->insertTuple()) - && !pNdbOperation->equal(c_szContextId, (Int32)iContextID) - && !pNdbOperation->setValue(c_szVersion, (Int32)iVersion) - && !pNdbOperation->setValue(c_szLockFlag, (Int32)iLockFlag) - && !pNdbOperation->setValue(c_szLockTime, (Int32)iLockTime) - && !pNdbOperation->setValue(c_szLockTimeUSec, (Int32)iLockTimeUSec) - && !pNdbOperation->setValue(c_szContextData, pchContextData, g_nStatusDataSize)) - { - if(!pNdbConnection->execute(Commit)) - iRes = 0; - else - err = pNdbConnection->getNdbError(); - } - else - err = pNdbOperation->getNdbError(); - } - else - err = pNdbConnection->getNdbError(); - - pNdb->closeTransaction(pNdbConnection); - } - else - err = pNdb->getNdbError(); - - return iRes; -} - - - -int RetryInsertTransaction(Ndb* pNdb, - long iContextId, - long iVersion, - long iLockFlag, - long iLockTime, - long iLockTimeUSec, - const char* pchContextData, - NdbError& err, int& nRetry) -{ - int iRes = -1; - nRetry = 0; - bool bRetry = true; - bool bUnknown = false; - while(bRetry && nRetrystartTransaction(0, (const char*)&iContextId, 4); - if(pNdbConnection) - { - NdbOperation* pNdbOperation = pNdbConnection->getNdbOperation(g_szTableName); - if(pNdbOperation) - { - if(!pNdbOperation->updateTuple() - && !pNdbOperation->equal(c_szContextId, (Int32)iContextId) - && !pNdbOperation->setValue(c_szContextData, STATUS_DATA, g_nStatusDataSize)) - { - if(!pNdbConnection->execute(Commit)) - iRes = 0; - else - err = pNdbConnection->getNdbError(); - } - else - err = pNdbOperation->getNdbError(); - } - else - err = pNdbConnection->getNdbError(); - - pNdb->closeTransaction(pNdbConnection); - } - else - err = pNdb->getNdbError(); - - return iRes; -} - - -int RetryUpdateTransaction(Ndb* pNdb, long iContextId, NdbError& err, int& nRetry) -{ - int iRes = -1; - nRetry = 0; - bool bRetry = true; - while(bRetry && nRetry0) - { - sprintf(szMsg, "insert retried %d times, time %ld msec.", - nRetry, lMillisecForThisTrans); - ReportNdbError(szMsg, err); - } - if(iRes) - { - ReportNdbError("Insert initial record failed", err); - return iRes; - } - InterlockedIncrement(&g_nNumberOfInitialInsert); - } - return iRes; -} - - - -int VerifyInitialRecords(Ndb* pNdb, long nVerify, long nSeed) -{ - int iRes = -1; - char* pchContextData = new char[g_nStatusDataSize]; - char szMsg[100]; - long iPrevLockTime = -1; - long iPrevLockTimeUSec = -1; - for(long i=0; i0) - { - sprintf(szMsg, "verify retried %d times, time %ld msec.", - nRetry, lMillisecForThisTrans); - ReportNdbError(szMsg, err); - } - if(iRes) - { - ReportNdbError("Read initial record failed", err); - delete[] pchContextData; - return iRes; - } - if(memcmp(pchContextData, STATUS_DATA, g_nStatusDataSize)) - { - sprintf(szMsg, "wrong context data in tuple %d", iContextID); - ReportNdbError(szMsg, err); - delete[] pchContextData; - return -1; - } - if(iVersion!=nSeed - || iLockFlag!=iContextID - || iLockTimeinit(1) || pNdb->waitUntilReady()) - { - ReportNdbError("init of Ndb failed", pNdb->getNdbError()); - delete pNdb; - delete[] pchContextData; - return 0; - } - - if(g_bInsertInitial) - { - if(InsertInitialRecords(pNdb, g_nMaxContextIdPerThread, -nStartingRecordID-g_nMaxContextIdPerThread)) - { - delete pNdb; - delete[] pchContextData; - return 0; - } - } - - if(g_bVerifyInitial) - { - NdbError err; - memset(&err, 0, sizeof(err)); - if(VerifyInitialRecords(pNdb, g_nMaxContextIdPerThread, -nStartingRecordID-g_nMaxContextIdPerThread)) - { - delete pNdb; - delete[] pchContextData; - return 0; - } - } - if(g_bInsertInitial || g_bVerifyInitial) - { - delete[] pchContextData; - return 0; - } - - long nContextID = nStartingRecordID; -#ifdef NDB_WIN32 - while(WaitForSingleObject(hShutdownEvent,0) != WAIT_OBJECT_0) -#else - while(!bShutdownEvent) -#endif - { - ++nContextID; - nContextID %= g_nMaxContextIdPerThread; - nContextID += nStartingRecordID; - - bool bTimeLatency = (nContextID==100); - - NDB_TICKS tStartCall = NdbTick_CurrentMillisecond(); - for (int i=0; i < 20; i++) - { - int nRetry = 0; - NdbError err; - memset(&err, 0, sizeof(err)); - NDB_TICKS tStartTrans = NdbTick_CurrentMillisecond(); - switch(i) - { - case 3: - case 6: - case 9: - case 11: - case 12: - case 15: - case 18: // Query Record - szOp = "Read"; - iRes = RetryQueryTransaction(pNdb, nContextID, &iVersion, &iLockFlag, - &iLockTime, &iLockTimeUSec, pchContextData, err, nRetry); - break; - - case 19: // Delete Record - szOp = "Delete"; - iRes = RetryDeleteTransaction(pNdb, nContextID, err, nRetry); - break; - - case 0: // Insert Record - szOp = "Insert"; - iRes = RetryInsertTransaction(pNdb, nContextID, 1, 1, 1, 1, STATUS_DATA, err, nRetry); - break; - - default: // Update Record - szOp = "Update"; - iRes = RetryUpdateTransaction(pNdb, nContextID, err, nRetry); - break; - } - NDB_TICKS tEndTrans = NdbTick_CurrentMillisecond(); - long lMillisecForThisTrans = (long)(tEndTrans-tStartTrans); - - if(g_bReport) - { - assert(lMillisecForThisTrans>=0 && lMillisecForThisTrans0) - { - sprintf(szMsg, "%s retried %d times, time %ld msec.", - szOp, nRetry, lMillisecForThisTrans); - ReportNdbError(szMsg, err); - } - else if(bTimeLatency) - { - NdbMutex_Lock(g_pNdbMutexPrintf); - printf("%s = %ld msec.\n", szOp, lMillisecForThisTrans); - NdbMutex_Unlock(g_pNdbMutexPrintf); - } - - if(iRes) - { - sprintf(szMsg, "%s failed after %ld calls, terminating thread", - szOp, nNumCallsProcessed); - ReportNdbError(szMsg, err); - delete pNdb; - delete[] pchContextData; - return 0; - } - } - NDB_TICKS tEndCall = NdbTick_CurrentMillisecond(); - long lMillisecForThisCall = (long)(tEndCall-tStartCall); - - if(g_bReport) - { - assert(lMillisecForThisCall>=0 && lMillisecForThisCall0) - { - int iMillisecToSleep = (1000*g_nNumThreads)/g_nMaxCallsPerSecond; - iMillisecToSleep -= lMillisecForThisCall; - if(iMillisecToSleep>0) - { - NdbSleep_MilliSleep(iMillisecToSleep); - } - } - } - - NdbMutex_Lock(g_pNdbMutexPrintf); - printf("Terminating thread after %ld calls\n", nNumCallsProcessed); - NdbMutex_Unlock(g_pNdbMutexPrintf); - - delete pNdb; - delete[] pchContextData; - return 0; -} - - -int CreateCallContextTable(Ndb* pNdb, const char* szTableName, bool bStored) -{ - int iRes = -1; - NdbError err; - memset(&err, 0, sizeof(err)); - - NdbSchemaCon* pNdbSchemaCon = pNdb->startSchemaTransaction(); - if(pNdbSchemaCon) - { - NdbSchemaOp* pNdbSchemaOp = pNdbSchemaCon->getNdbSchemaOp(); - if(pNdbSchemaOp) - { - if(!pNdbSchemaOp->createTable(szTableName, 8, TupleKey, 2, - All, 6, 78, 80, 1, bStored) - && !pNdbSchemaOp->createAttribute(c_szContextId, TupleKey, 32, 1, Signed) - && !pNdbSchemaOp->createAttribute(c_szVersion, NoKey, 32, 1, Signed) - && !pNdbSchemaOp->createAttribute(c_szLockFlag, NoKey, 32, 1, Signed) - && !pNdbSchemaOp->createAttribute(c_szLockTime, NoKey, 32, 1, Signed) - && !pNdbSchemaOp->createAttribute(c_szLockTimeUSec, NoKey, 32, 1, Signed) - && !pNdbSchemaOp->createAttribute(c_szContextData, NoKey, 8, g_nStatusDataSize, String)) - { - if(!pNdbSchemaCon->execute()) - iRes = 0; - else - err = pNdbSchemaCon->getNdbError(); - } - else - err = pNdbSchemaOp->getNdbError(); - } - else - err = pNdbSchemaCon->getNdbError(); - pNdb->closeSchemaTransaction(pNdbSchemaCon); - } - else - err = pNdb->getNdbError(); - - if(iRes) - { - ReportNdbError("create call context table failed", err); - } - return iRes; -} - - - -void ReportResponseTimeStatistics(const char* szStat, long* plCount, const long lSize) -{ - long lCount = 0; - Int64 llSum = 0; - Int64 llSum2 = 0; - long lMin = -1; - long lMax = -1; - - for(long l=0; l0) - { - lCount += plCount[l]; - llSum += (Int64)l*(Int64)plCount[l]; - llSum2 += (Int64)l*(Int64)l*(Int64)plCount[l]; - if(lMin==-1 || llMax) - { - lMax = l; - } - } - } - - long lAvg = long(llSum/lCount); - double dblVar = ((double)lCount*(double)llSum2 - (double)llSum*(double)llSum)/((double)lCount*(double)(lCount-1)); - long lStd = long(sqrt(dblVar)); - - long lMed = -1; - long l95 = -1; - long lSel = -1; - for(long l=lMin; l<=lMax; ++l) - { - if(plCount[l]>0) - { - lSel += plCount[l]; - if(lMed==-1 && lSel>=(lCount/2)) - { - lMed = l; - } - if(l95==-1 && lSel>=((lCount*95)/100)) - { - l95 = l; - } - if(g_bReportPlus) - { - printf("%ld\t%ld\n", l, plCount[l]); - } - } - } - - printf("%s: Count=%ld, Min=%ld, Max=%ld, Avg=%ld, Std=%ld, Med=%ld, 95%%=%ld\n", - szStat, lCount, lMin, lMax, lAvg, lStd, lMed, l95); -} - - - -void ShowHelp(const char* szCmd) -{ - printf("%s -t [-s] [-b] [-c] [-m] [-d] [-i] [-v] [-f] [-w] [-r[+]]\n", szCmd); - printf("%s -?\n", szCmd); - puts("-d\t\tcreate the table"); - puts("-i\t\tinsert initial records"); - puts("-v\t\tverify initial records"); - puts("-t\tnumber of threads making calls"); - puts("-s\toffset for primary key"); - puts("-b\tbatch size per thread"); - puts("-c\tmax number of calls per second for this process"); - puts("-m\tsize of context data"); - puts("-f\t\tno checkpointing and no logging"); - puts("-w\t\tuse writeTuple instead of insertTuple"); - puts("-r\t\treport response time statistics"); - puts("-r+\t\treport response time distribution"); - puts("-?\t\thelp"); -} - - -int main(int argc, char* argv[]) -{ - int iRes = -1; - g_nNumThreads = 0; - g_nMaxCallsPerSecond = 0; - long nSeed = 0; - bool bStoredTable = true; - bool bCreateTable = false; - g_bWriteTuple = false; - g_bReport = false; - g_bReportPlus = false; - - for(int i=1; isizeof(STATUS_DATA)) - { - g_nStatusDataSize = sizeof(STATUS_DATA); - } - break; - case 'i': - g_bInsertInitial = true; - break; - case 'v': - g_bVerifyInitial = true; - break; - case 'd': - bCreateTable = true; - break; - case 'f': - bStoredTable = false; - break; - case 'w': - g_bWriteTuple = true; - break; - case 'r': - g_bReport = true; - if(argv[i][2]=='+') - { - g_bReportPlus = true; - } - break; - case 'c': - g_nMaxCallsPerSecond = atol(argv[i]+2); - break; - case '?': - default: - ShowHelp(argv[0]); - return -1; - } - } - else - { - ShowHelp(argv[0]); - return -1; - } - } - if(bCreateTable) - puts("-d\tcreate the table"); - if(g_bInsertInitial) - printf("-i\tinsert initial records\n"); - if(g_bVerifyInitial) - printf("-v\tverify initial records\n"); - if(g_nNumThreads>0) - printf("-t%ld\tnumber of threads making calls\n", g_nNumThreads); - if(g_nNumThreads>0) - { - printf("-s%ld\toffset for primary key\n", nSeed); - printf("-b%ld\tbatch size per thread\n", g_nMaxContextIdPerThread); - } - if(g_nMaxCallsPerSecond>0) - printf("-c%ld\tmax number of calls per second for this process\n", g_nMaxCallsPerSecond); - if(!bStoredTable) - puts("-f\tno checkpointing and no logging to disk"); - if(g_bWriteTuple) - puts("-w\tuse writeTuple instead of insertTuple"); - if(g_bReport) - puts("-r\treport response time statistics"); - if(g_bReportPlus) - puts("-r+\treport response time distribution"); - - if(!bCreateTable && g_nNumThreads<=0) - { - ShowHelp(argv[0]); - return -1; - } - printf("-m%ld\tsize of context data\n", g_nStatusDataSize); - - g_szTableName = (bStoredTable ? c_szTableNameStored : c_szTableNameTemp); - -#ifdef NDB_WIN32 - SetConsoleCtrlHandler(ConsoleCtrlHandler, true); -#else - signal(SIGINT, CtrlCHandler); -#endif - - if(g_bReport) - { - g_plCountMillisecForCall = new long[c_nMaxMillisecForAllCall]; - memset(g_plCountMillisecForCall, 0, c_nMaxMillisecForAllCall*sizeof(long)); - g_plCountMillisecForTrans = new long[c_nMaxMillisecForAllTrans]; - memset(g_plCountMillisecForTrans, 0, c_nMaxMillisecForAllTrans*sizeof(long)); - } - - g_pNdbMutexIncrement = NdbMutex_Create(); - g_pNdbMutexPrintf = NdbMutex_Create(); -#ifdef NDB_WIN32 - hShutdownEvent = CreateEvent(NULL,TRUE,FALSE,NULL); -#endif - - Ndb* pNdb = new Ndb(c_szDatabaseName); - if(!pNdb) - { - printf("could not construct ndb\n"); - return 1; - } - - if(pNdb->init(1) || pNdb->waitUntilReady()) - { - ReportNdbError("could not initialize ndb\n", pNdb->getNdbError()); - delete pNdb; - return 2; - } - - if(bCreateTable) - { - printf("Create CallContext table\n"); - if (bStoredTable) - { - if (CreateCallContextTable(pNdb, c_szTableNameStored, true)) - { - printf("Create table failed\n"); - delete pNdb; - return 3; - } - } - else - { - if (CreateCallContextTable(pNdb, c_szTableNameTemp, false)) - { - printf("Create table failed\n"); - delete pNdb; - return 3; - } - } - } - - if(g_nNumThreads>0) - { - printf("creating %d threads\n", (int)g_nNumThreads); - if(g_bInsertInitial) - { - printf("each thread will insert %ld initial records, total %ld inserts\n", - g_nMaxContextIdPerThread, g_nNumThreads*g_nMaxContextIdPerThread); - } - if(g_bVerifyInitial) - { - printf("each thread will verify %ld initial records, total %ld reads\n", - g_nMaxContextIdPerThread, g_nNumThreads*g_nMaxContextIdPerThread); - } - - g_nNumberOfInitialInsert = 0; - g_nNumberOfInitialVerify = 0; - - NDB_TICKS tStartTime = NdbTick_CurrentMillisecond(); - NdbThread* pThreads[256]; - int pnStartingRecordNum[256]; - int ij; - for(ij=0;ij +#include +#include +#include +#include + + +#define CHECK(b) if (!(b)) { \ + g_err << "ERR: "<< step->getName() \ + << " failed on line " << __LINE__ << endl; \ + result = NDBT_FAILED; \ + continue; } + + +int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ + + int records = ctx->getNumRecords(); + HugoTransactions hugoTrans(*ctx->getTab()); + if (hugoTrans.loadTable(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +bool testMaster = true; +bool testSlave = false; + +int setMaster(NDBT_Context* ctx, NDBT_Step* step){ + testMaster = true; + testSlave = false; + return NDBT_OK; +} +int setMasterAsSlave(NDBT_Context* ctx, NDBT_Step* step){ + testMaster = true; + testSlave = true; + return NDBT_OK; +} +int setSlave(NDBT_Context* ctx, NDBT_Step* step){ + testMaster = false; + testSlave = true; + return NDBT_OK; +} + +int runAbort(NDBT_Context* ctx, NDBT_Step* step){ + NdbBackup backup(GETNDB(step)->getNodeId()+1); + + NdbRestarter restarter; + + if (restarter.getNumDbNodes() < 2){ + ctx->stopTest(); + return NDBT_OK; + } + + if(restarter.waitClusterStarted(60) != 0){ + g_err << "Cluster failed to start" << endl; + return NDBT_FAILED; + } + + if (testMaster) { + if (testSlave) { + if (backup.NFMasterAsSlave(restarter) == -1){ + return NDBT_FAILED; + } + } else { + if (backup.NFMaster(restarter) == -1){ + return NDBT_FAILED; + } + } + } else { + if (backup.NFSlave(restarter) == -1){ + return NDBT_FAILED; + } + } + + return NDBT_OK; +} + +int runFail(NDBT_Context* ctx, NDBT_Step* step){ + NdbBackup backup(GETNDB(step)->getNodeId()+1); + + NdbRestarter restarter; + + if (restarter.getNumDbNodes() < 2){ + ctx->stopTest(); + return NDBT_OK; + } + + if(restarter.waitClusterStarted(60) != 0){ + g_err << "Cluster failed to start" << endl; + return NDBT_FAILED; + } + + if (testMaster) { + if (testSlave) { + if (backup.FailMasterAsSlave(restarter) == -1){ + return NDBT_FAILED; + } + } else { + if (backup.FailMaster(restarter) == -1){ + return NDBT_FAILED; + } + } + } else { + if (backup.FailSlave(restarter) == -1){ + return NDBT_FAILED; + } + } + + return NDBT_OK; +} + +int runBackupOne(NDBT_Context* ctx, NDBT_Step* step){ + NdbBackup backup(GETNDB(step)->getNodeId()+1); + unsigned backupId = 0; + + if (backup.start(backupId) == -1){ + return NDBT_FAILED; + } + ndbout << "Started backup " << backupId << endl; + ctx->setProperty("BackupId", backupId); + + return NDBT_OK; +} + +int runRestartInitial(NDBT_Context* ctx, NDBT_Step* step){ + NdbRestarter restarter; + + Ndb* pNdb = GETNDB(step); + + const NdbDictionary::Table *tab = ctx->getTab(); + pNdb->getDictionary()->dropTable(tab->getName()); + + if (restarter.restartAll(true) != 0) + return NDBT_FAILED; + + return NDBT_OK; +} + +int runRestoreOne(NDBT_Context* ctx, NDBT_Step* step){ + NdbBackup backup(GETNDB(step)->getNodeId()+1); + unsigned backupId = ctx->getProperty("BackupId"); + + ndbout << "Restoring backup " << backupId << endl; + + if (backup.restore(backupId) == -1){ + return NDBT_FAILED; + } + + return NDBT_OK; +} + +int runVerifyOne(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; + int count = 0; + + ndbout << *(const NDBT_Table*)ctx->getTab() << endl; + + UtilTransactions utilTrans(*ctx->getTab()); + HugoTransactions hugoTrans(*ctx->getTab()); + + do{ + + // Check that there are as many records as we expected + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + + g_err << "count = " << count; + g_err << " records = " << records; + g_err << endl; + + CHECK(count == records); + + // Read and verify every record + CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0); + + } while (false); + + return result; +} + +int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + + UtilTransactions utilTrans(*ctx->getTab()); + if (utilTrans.clearTable2(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +#include "bank/Bank.hpp" + +int runCreateBank(NDBT_Context* ctx, NDBT_Step* step){ + Bank bank; + int overWriteExisting = true; + if (bank.createAndLoadBank(overWriteExisting) != NDBT_OK) + return NDBT_FAILED; + return NDBT_OK; +} + +int runBankTimer(NDBT_Context* ctx, NDBT_Step* step){ + Bank bank; + int wait = 30; // Max seconds between each "day" + int yield = 1; // Loops before bank returns + + while (ctx->isTestStopped() == false) { + bank.performIncreaseTime(wait, yield); + } + return NDBT_OK; +} + +int runBankTransactions(NDBT_Context* ctx, NDBT_Step* step){ + Bank bank; + int wait = 10; // Max ms between each transaction + int yield = 100; // Loops before bank returns + + while (ctx->isTestStopped() == false) { + bank.performTransactions(wait, yield); + } + return NDBT_OK; +} + +int runBankGL(NDBT_Context* ctx, NDBT_Step* step){ + Bank bank; + int yield = 20; // Loops before bank returns + int result = NDBT_OK; + + while (ctx->isTestStopped() == false) { + if (bank.performMakeGLs(yield) != NDBT_OK){ + ndbout << "bank.performMakeGLs FAILED" << endl; + result = NDBT_FAILED; + } + } + return NDBT_OK; +} + +int runBankSum(NDBT_Context* ctx, NDBT_Step* step){ + Bank bank; + int wait = 2000; // Max ms between each sum of accounts + int yield = 1; // Loops before bank returns + int result = NDBT_OK; + + while (ctx->isTestStopped() == false) { + if (bank.performSumAccounts(wait, yield) != NDBT_OK){ + ndbout << "bank.performSumAccounts FAILED" << endl; + result = NDBT_FAILED; + } + } + return result ; +} + +int runDropBank(NDBT_Context* ctx, NDBT_Step* step){ + Bank bank; + if (bank.dropBank() != NDBT_OK) + return NDBT_FAILED; + return NDBT_OK; +} + +int runBackupBank(NDBT_Context* ctx, NDBT_Step* step){ + int loops = ctx->getNumLoops(); + int l = 0; + int maxSleep = 30; // Max seconds between each backup + Ndb* pNdb = GETNDB(step); + NdbBackup backup(GETNDB(step)->getNodeId()+1); + unsigned minBackupId = ~0; + unsigned maxBackupId = 0; + unsigned backupId = 0; + int result = NDBT_OK; + + while (l < loops && result != NDBT_FAILED){ + + if (pNdb->waitUntilReady() != 0){ + result = NDBT_FAILED; + continue; + } + + // Sleep for a while + NdbSleep_SecSleep(maxSleep); + + // Perform backup + if (backup.start(backupId) != 0){ + ndbout << "backup.start failed" << endl; + result = NDBT_FAILED; + continue; + } + ndbout << "Started backup " << backupId << endl; + + // Remember min and max backupid + if (backupId < minBackupId) + minBackupId = backupId; + + if (backupId > maxBackupId) + maxBackupId = backupId; + + ndbout << " maxBackupId = " << maxBackupId + << ", minBackupId = " << minBackupId << endl; + ctx->setProperty("MinBackupId", minBackupId); + ctx->setProperty("MaxBackupId", maxBackupId); + + l++; + } + + ctx->stopTest(); + + return result; +} + +int runRestoreBankAndVerify(NDBT_Context* ctx, NDBT_Step* step){ + NdbRestarter restarter; + NdbBackup backup(GETNDB(step)->getNodeId()+1); + unsigned minBackupId = ctx->getProperty("MinBackupId"); + unsigned maxBackupId = ctx->getProperty("MaxBackupId"); + unsigned backupId = minBackupId; + int result = NDBT_OK; + int errSumAccounts = 0; + int errValidateGL = 0; + + ndbout << " maxBackupId = " << maxBackupId << endl; + ndbout << " minBackupId = " << minBackupId << endl; + + while (backupId <= maxBackupId){ + + // TEMPORARY FIX + // To erase all tables from cache(s) + // To be removed, maybe replaced by ndb.invalidate(); + { + Bank bank; + + if (bank.dropBank() != NDBT_OK){ + result = NDBT_FAILED; + break; + } + } + // END TEMPORARY FIX + + ndbout << "Performing initial restart" << endl; + if (restarter.restartAll(true) != 0) + return NDBT_FAILED; + + if (restarter.waitClusterStarted() != 0) + return NDBT_FAILED; + + ndbout << "Restoring backup " << backupId << endl; + if (backup.restore(backupId) == -1){ + return NDBT_FAILED; + } + ndbout << "Backup " << backupId << " restored" << endl; + + // Let bank verify + Bank bank; + + int wait = 0; + int yield = 1; + if (bank.performSumAccounts(wait, yield) != 0){ + ndbout << "bank.performSumAccounts FAILED" << endl; + ndbout << " backupId = " << backupId << endl << endl; + result = NDBT_FAILED; + errSumAccounts++; + } + + if (bank.performValidateAllGLs() != 0){ + ndbout << "bank.performValidateAllGLs FAILED" << endl; + ndbout << " backupId = " << backupId << endl << endl; + result = NDBT_FAILED; + errValidateGL++; + } + + backupId++; + } + + if (result != NDBT_OK){ + ndbout << "Verification of backup failed" << endl + << " errValidateGL="< -#include -#include -#include -#include - - -#define CHECK(b) if (!(b)) { \ - g_err << "ERR: "<< step->getName() \ - << " failed on line " << __LINE__ << endl; \ - result = NDBT_FAILED; \ - continue; } - - -int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ - - int records = ctx->getNumRecords(); - HugoTransactions hugoTrans(*ctx->getTab()); - if (hugoTrans.loadTable(GETNDB(step), records) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -bool testMaster = true; -bool testSlave = false; - -int setMaster(NDBT_Context* ctx, NDBT_Step* step){ - testMaster = true; - testSlave = false; - return NDBT_OK; -} -int setMasterAsSlave(NDBT_Context* ctx, NDBT_Step* step){ - testMaster = true; - testSlave = true; - return NDBT_OK; -} -int setSlave(NDBT_Context* ctx, NDBT_Step* step){ - testMaster = false; - testSlave = true; - return NDBT_OK; -} - -int runAbort(NDBT_Context* ctx, NDBT_Step* step){ - NdbBackup backup(GETNDB(step)->getNodeId()+1); - - NdbRestarter restarter; - - if (restarter.getNumDbNodes() < 2){ - ctx->stopTest(); - return NDBT_OK; - } - - if(restarter.waitClusterStarted(60) != 0){ - g_err << "Cluster failed to start" << endl; - return NDBT_FAILED; - } - - if (testMaster) { - if (testSlave) { - if (backup.NFMasterAsSlave(restarter) == -1){ - return NDBT_FAILED; - } - } else { - if (backup.NFMaster(restarter) == -1){ - return NDBT_FAILED; - } - } - } else { - if (backup.NFSlave(restarter) == -1){ - return NDBT_FAILED; - } - } - - return NDBT_OK; -} - -int runFail(NDBT_Context* ctx, NDBT_Step* step){ - NdbBackup backup(GETNDB(step)->getNodeId()+1); - - NdbRestarter restarter; - - if (restarter.getNumDbNodes() < 2){ - ctx->stopTest(); - return NDBT_OK; - } - - if(restarter.waitClusterStarted(60) != 0){ - g_err << "Cluster failed to start" << endl; - return NDBT_FAILED; - } - - if (testMaster) { - if (testSlave) { - if (backup.FailMasterAsSlave(restarter) == -1){ - return NDBT_FAILED; - } - } else { - if (backup.FailMaster(restarter) == -1){ - return NDBT_FAILED; - } - } - } else { - if (backup.FailSlave(restarter) == -1){ - return NDBT_FAILED; - } - } - - return NDBT_OK; -} - -int runBackupOne(NDBT_Context* ctx, NDBT_Step* step){ - NdbBackup backup(GETNDB(step)->getNodeId()+1); - unsigned backupId = 0; - - if (backup.start(backupId) == -1){ - return NDBT_FAILED; - } - ndbout << "Started backup " << backupId << endl; - ctx->setProperty("BackupId", backupId); - - return NDBT_OK; -} - -int runRestartInitial(NDBT_Context* ctx, NDBT_Step* step){ - NdbRestarter restarter; - - Ndb* pNdb = GETNDB(step); - - const NdbDictionary::Table *tab = ctx->getTab(); - pNdb->getDictionary()->dropTable(tab->getName()); - - if (restarter.restartAll(true) != 0) - return NDBT_FAILED; - - return NDBT_OK; -} - -int runRestoreOne(NDBT_Context* ctx, NDBT_Step* step){ - NdbBackup backup(GETNDB(step)->getNodeId()+1); - unsigned backupId = ctx->getProperty("BackupId"); - - ndbout << "Restoring backup " << backupId << endl; - - if (backup.restore(backupId) == -1){ - return NDBT_FAILED; - } - - return NDBT_OK; -} - -int runVerifyOne(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - Ndb* pNdb = GETNDB(step); - int result = NDBT_OK; - int count = 0; - - ndbout << *(const NDBT_Table*)ctx->getTab() << endl; - - UtilTransactions utilTrans(*ctx->getTab()); - HugoTransactions hugoTrans(*ctx->getTab()); - - do{ - - // Check that there are as many records as we expected - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - - g_err << "count = " << count; - g_err << " records = " << records; - g_err << endl; - - CHECK(count == records); - - // Read and verify every record - CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0); - - } while (false); - - return result; -} - -int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - - UtilTransactions utilTrans(*ctx->getTab()); - if (utilTrans.clearTable2(GETNDB(step), records) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - - -#include "../bank/Bank.hpp" - -int runCreateBank(NDBT_Context* ctx, NDBT_Step* step){ - Bank bank; - int overWriteExisting = true; - if (bank.createAndLoadBank(overWriteExisting) != NDBT_OK) - return NDBT_FAILED; - return NDBT_OK; -} - -int runBankTimer(NDBT_Context* ctx, NDBT_Step* step){ - Bank bank; - int wait = 30; // Max seconds between each "day" - int yield = 1; // Loops before bank returns - - while (ctx->isTestStopped() == false) { - bank.performIncreaseTime(wait, yield); - } - return NDBT_OK; -} - -int runBankTransactions(NDBT_Context* ctx, NDBT_Step* step){ - Bank bank; - int wait = 10; // Max ms between each transaction - int yield = 100; // Loops before bank returns - - while (ctx->isTestStopped() == false) { - bank.performTransactions(wait, yield); - } - return NDBT_OK; -} - -int runBankGL(NDBT_Context* ctx, NDBT_Step* step){ - Bank bank; - int yield = 20; // Loops before bank returns - int result = NDBT_OK; - - while (ctx->isTestStopped() == false) { - if (bank.performMakeGLs(yield) != NDBT_OK){ - ndbout << "bank.performMakeGLs FAILED" << endl; - result = NDBT_FAILED; - } - } - return NDBT_OK; -} - -int runBankSum(NDBT_Context* ctx, NDBT_Step* step){ - Bank bank; - int wait = 2000; // Max ms between each sum of accounts - int yield = 1; // Loops before bank returns - int result = NDBT_OK; - - while (ctx->isTestStopped() == false) { - if (bank.performSumAccounts(wait, yield) != NDBT_OK){ - ndbout << "bank.performSumAccounts FAILED" << endl; - result = NDBT_FAILED; - } - } - return result ; -} - -int runDropBank(NDBT_Context* ctx, NDBT_Step* step){ - Bank bank; - if (bank.dropBank() != NDBT_OK) - return NDBT_FAILED; - return NDBT_OK; -} - -int runBackupBank(NDBT_Context* ctx, NDBT_Step* step){ - int loops = ctx->getNumLoops(); - int l = 0; - int maxSleep = 30; // Max seconds between each backup - Ndb* pNdb = GETNDB(step); - NdbBackup backup(GETNDB(step)->getNodeId()+1); - unsigned minBackupId = ~0; - unsigned maxBackupId = 0; - unsigned backupId = 0; - int result = NDBT_OK; - - while (l < loops && result != NDBT_FAILED){ - - if (pNdb->waitUntilReady() != 0){ - result = NDBT_FAILED; - continue; - } - - // Sleep for a while - NdbSleep_SecSleep(maxSleep); - - // Perform backup - if (backup.start(backupId) != 0){ - ndbout << "backup.start failed" << endl; - result = NDBT_FAILED; - continue; - } - ndbout << "Started backup " << backupId << endl; - - // Remember min and max backupid - if (backupId < minBackupId) - minBackupId = backupId; - - if (backupId > maxBackupId) - maxBackupId = backupId; - - ndbout << " maxBackupId = " << maxBackupId - << ", minBackupId = " << minBackupId << endl; - ctx->setProperty("MinBackupId", minBackupId); - ctx->setProperty("MaxBackupId", maxBackupId); - - l++; - } - - ctx->stopTest(); - - return result; -} - -int runRestoreBankAndVerify(NDBT_Context* ctx, NDBT_Step* step){ - NdbRestarter restarter; - NdbBackup backup(GETNDB(step)->getNodeId()+1); - unsigned minBackupId = ctx->getProperty("MinBackupId"); - unsigned maxBackupId = ctx->getProperty("MaxBackupId"); - unsigned backupId = minBackupId; - int result = NDBT_OK; - int errSumAccounts = 0; - int errValidateGL = 0; - - ndbout << " maxBackupId = " << maxBackupId << endl; - ndbout << " minBackupId = " << minBackupId << endl; - - while (backupId <= maxBackupId){ - - // TEMPORARY FIX - // To erase all tables from cache(s) - // To be removed, maybe replaced by ndb.invalidate(); - { - Bank bank; - - if (bank.dropBank() != NDBT_OK){ - result = NDBT_FAILED; - break; - } - } - // END TEMPORARY FIX - - ndbout << "Performing initial restart" << endl; - if (restarter.restartAll(true) != 0) - return NDBT_FAILED; - - if (restarter.waitClusterStarted() != 0) - return NDBT_FAILED; - - ndbout << "Restoring backup " << backupId << endl; - if (backup.restore(backupId) == -1){ - return NDBT_FAILED; - } - ndbout << "Backup " << backupId << " restored" << endl; - - // Let bank verify - Bank bank; - - int wait = 0; - int yield = 1; - if (bank.performSumAccounts(wait, yield) != 0){ - ndbout << "bank.performSumAccounts FAILED" << endl; - ndbout << " backupId = " << backupId << endl << endl; - result = NDBT_FAILED; - errSumAccounts++; - } - - if (bank.performValidateAllGLs() != 0){ - ndbout << "bank.performValidateAllGLs FAILED" << endl; - ndbout << " backupId = " << backupId << endl << endl; - result = NDBT_FAILED; - errValidateGL++; - } - - backupId++; - } - - if (result != NDBT_OK){ - ndbout << "Verification of backup failed" << endl - << " errValidateGL="< +#include +#include +#include +#include + +#define GETNDB(ps) ((NDBT_NdbApiStep*)ps)->getNdb() + + +/** + * TODO + * dirtyWrite, write, dirtyUpdate + * delete should be visible to same transaction + * + */ + +int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ + + int records = ctx->getNumRecords(); + HugoTransactions hugoTrans(*ctx->getTab()); + if (hugoTrans.loadTable(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runInsert(NDBT_Context* ctx, NDBT_Step* step){ + + int records = ctx->getNumRecords(); + HugoTransactions hugoTrans(*ctx->getTab()); + // Insert records, dont allow any + // errors(except temporary) while inserting + if (hugoTrans.loadTable(GETNDB(step), records, 1, false) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runInsertTwice(NDBT_Context* ctx, NDBT_Step* step){ + + int records = ctx->getNumRecords(); + HugoTransactions hugoTrans(*ctx->getTab()); + // Insert records, expect primary key violation 630 + if (hugoTrans.loadTable(GETNDB(step), records, 1, false) != 630){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runVerifyInsert(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + + HugoTransactions hugoTrans(*ctx->getTab()); + if (hugoTrans.pkDelRecords(GETNDB(step), records, 1, false) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runInsertUntilStopped(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + int i = 0; + HugoTransactions hugoTrans(*ctx->getTab()); + while (ctx->isTestStopped() == false) { + g_info << i << ": "; + if (hugoTrans.loadTable(GETNDB(step), records) != 0){ + g_info << endl; + return NDBT_FAILED; + } + i++; + } + g_info << endl; + return NDBT_OK; +} + +int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + int batchSize = ctx->getProperty("BatchSize", 1); + + HugoTransactions hugoTrans(*ctx->getTab()); + if (hugoTrans.pkDelRecords(GETNDB(step), records, batchSize) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runPkDelete(NDBT_Context* ctx, NDBT_Step* step){ + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + + int i = 0; + HugoTransactions hugoTrans(*ctx->getTab()); + while (igetNumLoops(); + int records = ctx->getNumRecords(); + int batchSize = ctx->getProperty("BatchSize", 1); + int i = 0; + HugoTransactions hugoTrans(*ctx->getTab()); + while (igetNumLoops(); + int records = ctx->getNumRecords(); + int batchSize = ctx->getProperty("BatchSize", 1); + int i = 0; + bool dirty = true; + HugoTransactions hugoTrans(*ctx->getTab()); + while (igetNumRecords(); + int batchSize = ctx->getProperty("BatchSize", 1); + int i = 0; + HugoTransactions hugoTrans(*ctx->getTab()); + while (ctx->isTestStopped() == false) { + g_info << i << ": "; + if (hugoTrans.pkReadRecords(GETNDB(step), records, batchSize) != 0){ + g_info << endl; + return NDBT_FAILED; + } + i++; + } + g_info << endl; + return NDBT_OK; +} + +int runPkUpdate(NDBT_Context* ctx, NDBT_Step* step){ + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + int batchSize = ctx->getProperty("BatchSize", 1); + int i = 0; + HugoTransactions hugoTrans(*ctx->getTab()); + while (igetNumRecords(); + int batchSize = ctx->getProperty("BatchSize", 1); + int i = 0; + HugoTransactions hugoTrans(*ctx->getTab()); + while (ctx->isTestStopped()) { + g_info << i << ": "; + if (hugoTrans.pkUpdateRecords(GETNDB(step), records, batchSize) != 0){ + g_info << endl; + return NDBT_FAILED; + } + i++; + } + g_info << endl; + return NDBT_OK; +} + +int runLocker(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int records = ctx->getNumRecords(); + HugoTransactions hugoTrans(*ctx->getTab()); + + if (hugoTrans.lockRecords(GETNDB(step), records, 10, 500) != 0){ + result = NDBT_FAILED; + } + ctx->stopTest(); + + return result; +} + +int +runInsertOne(NDBT_Context* ctx, NDBT_Step* step){ + + if(ctx->getProperty("InsertCommitted", (Uint32)0) != 0){ + abort(); + } + + while(ctx->getProperty("Read1Performed", (Uint32)0) == 0){ + NdbSleep_MilliSleep(20); + } + + HugoTransactions hugoTrans(*ctx->getTab()); + + if (hugoTrans.loadTable(GETNDB(step), 1, 1) != 0){ + return NDBT_FAILED; + } + + ctx->setProperty("InsertCommitted", 1); + + NdbSleep_SecSleep(2); + + return NDBT_OK; +} + +static +int +readOneNoCommit(Ndb* pNdb, NdbConnection* pTrans, + const NdbDictionary::Table* tab,NDBT_ResultRow * row){ + + NdbOperation * pOp = pTrans->getNdbOperation(tab->getName()); + if (pOp == NULL){ + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + HugoTransactions tmp(*tab); + + int check = pOp->readTuple(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + + // Define primary keys + for(int a = 0; agetNoOfColumns(); a++){ + if (tab->getColumn(a)->getPrimaryKey() == true){ + if(tmp.equalForAttr(pOp, a, 0) != 0){ + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + } + } + + // Define attributes to read + for(int a = 0; agetNoOfColumns(); a++){ + if((row->attributeStore(a) = + pOp->getValue(tab->getColumn(a)->getName())) == 0) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + } + + check = pTrans->execute(NoCommit); + if( check == -1 ) { + const NdbError err = pTrans->getNdbError(); + ERR(err); + return err.code; + } + return NDBT_OK; +} + +int +runReadOne(NDBT_Context* ctx, NDBT_Step* step){ + + Ndb* pNdb = GETNDB(step); + const NdbDictionary::Table* tab = ctx->getTab(); + NDBT_ResultRow row1(*tab); + NDBT_ResultRow row2(*tab); + + if(ctx->getProperty("Read1Performed", (Uint32)0) != 0){ + abort(); + } + + if(ctx->getProperty("InsertCommitted", (Uint32)0) != 0){ + abort(); + } + + NdbConnection * pTrans = pNdb->startTransaction(); + if (pTrans == NULL) { + abort(); + } + + // Read a record with NoCommit + // Since the record isn't inserted yet it wil return 626 + const int res1 = readOneNoCommit(pNdb, pTrans, tab, &row1); + g_info << "|- res1 = " << res1 << endl; + + ctx->setProperty("Read1Performed", 1); + + while(ctx->getProperty("InsertCommitted", (Uint32)0) == 0 && + !ctx->isTestStopped()){ + g_info << "|- Waiting for insert" << endl; + NdbSleep_MilliSleep(20); + } + + if(ctx->isTestStopped()){ + abort(); + } + + // Now the record should have been inserted + // Read it once again in the same transaction + // Should also reutrn 626 if reads are consistent + + // NOTE! Currently it's not possible to start a new operation + // on a transaction that has returned an error code + // This is wat fail in this test + // MASV 20030624 + const int res2 = readOneNoCommit(pNdb, pTrans, tab, &row2); + + pTrans->execute(Commit); + pNdb->closeTransaction(pTrans); + g_info << "|- res2 = " << res2 << endl; + + if (res2 == 626 && res1 == res2) + return NDBT_OK; + else + return NDBT_FAILED; +} + +int runFillTable(NDBT_Context* ctx, NDBT_Step* step){ + int batch = 512; //4096; + HugoTransactions hugoTrans(*ctx->getTab()); + if (hugoTrans.fillTable(GETNDB(step), batch ) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runClearTable2(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + + UtilTransactions utilTrans(*ctx->getTab()); + if (utilTrans.clearTable2(GETNDB(step), records, 240) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +#define CHECK(b) if (!(b)) { \ + ndbout << "ERR: "<< step->getName() \ + << " failed on line " << __LINE__ << endl; \ + result = NDBT_FAILED; \ + break; } + +int runNoCommitSleep(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + int sleepTime = 100; // ms + for (int i = 2; i < 8; i++){ + + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 0); + + ndbout << i <<": Sleeping for " << sleepTime << " ms" << endl; + NdbSleep_MilliSleep(sleepTime); + + // Dont care about result of these ops + hugoOps.pkReadRecord(pNdb, 1, true); + hugoOps.closeTransaction(pNdb); + + sleepTime = sleepTime *i; + } + + hugoOps.closeTransaction(pNdb); + + return result; +} + +int runCommit626(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + + do{ + // Commit transaction + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); + CHECK(hugoOps.execute_Commit(pNdb) == 626); + CHECK(hugoOps.closeTransaction(pNdb) == 0); + + // Commit transaction + // Multiple operations + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 2, true) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 3, true) == 0); + CHECK(hugoOps.execute_Commit(pNdb) == 626); + }while(false); + + hugoOps.closeTransaction(pNdb); + + return result; +} + +int runCommit630(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + + do{ + // Commit transaction + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0); + CHECK(hugoOps.execute_Commit(pNdb) == 630); + }while(false); + + hugoOps.closeTransaction(pNdb); + + return result; +} + +int runCommit_TryCommit626(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + + do{ + // Commit transaction, TryCommit + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); + CHECK(hugoOps.execute_Commit(pNdb, TryCommit) == 626); + CHECK(hugoOps.closeTransaction(pNdb) == 0); + + // Commit transaction, TryCommit + // Several operations in one transaction + // The insert is OK + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 2, true) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 3, true) == 0); + CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 4, true) == 0); + CHECK(hugoOps.execute_Commit(pNdb, TryCommit) == 626); + }while(false); + + hugoOps.closeTransaction(pNdb); + + return result; +} + +int runCommit_TryCommit630(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + + do{ + // Commit transaction, TryCommit + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0); + CHECK(hugoOps.execute_Commit(pNdb, TryCommit) == 630); + }while(false); + + hugoOps.closeTransaction(pNdb); + + return result; +} + +int runCommit_CommitAsMuchAsPossible626(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + + do{ + // Commit transaction, CommitAsMuchAsPossible + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); + CHECK(hugoOps.execute_Commit(pNdb, CommitAsMuchAsPossible) == 626); + CHECK(hugoOps.closeTransaction(pNdb) == 0); + + // Commit transaction, CommitAsMuchAsPossible + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 2, true) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 3, true) == 0); + CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 4, true) == 0); + CHECK(hugoOps.execute_Commit(pNdb, CommitAsMuchAsPossible) == 626); + CHECK(hugoOps.closeTransaction(pNdb) == 0); + }while(false); + + hugoOps.closeTransaction(pNdb); + + return result; +} + +int runCommit_CommitAsMuchAsPossible630(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + + do{ + // Commit transaction, CommitAsMuchAsPossible + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0); + CHECK(hugoOps.execute_Commit(pNdb, CommitAsMuchAsPossible) == 630); + }while(false); + + hugoOps.closeTransaction(pNdb); + + return result; +} + +int runNoCommit626(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + + do{ + // No commit transaction, readTuple + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 1, false) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 626); + CHECK(hugoOps.closeTransaction(pNdb) == 0); + + // No commit transaction, readTupleExcluive + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 626); + }while(false); + + hugoOps.closeTransaction(pNdb); + + return result; +} + +int runNoCommit630(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + + do{ + // No commit transaction + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 630); + }while(false); + + hugoOps.closeTransaction(pNdb); + + return result; +} + +int runNoCommitRollback626(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + + do{ + // No commit transaction, rollback + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 626); + CHECK(hugoOps.execute_Rollback(pNdb) == 0); + CHECK(hugoOps.closeTransaction(pNdb) == 0); + + // No commit transaction, rollback + // Multiple operations + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 2, true) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 3, true) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 4, true) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 626); + CHECK(hugoOps.execute_Rollback(pNdb) == 0); + }while(false); + + hugoOps.closeTransaction(pNdb); + + return result; +} + +int runNoCommitRollback630(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + + do{ + // No commit transaction, rollback + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 630); + CHECK(hugoOps.execute_Rollback(pNdb) == 0); + }while(false); + + hugoOps.closeTransaction(pNdb); + + return result; +} + + +int runNoCommitAndClose(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + + do{ + // Read + CHECK(hugoOps.startTransaction(pNdb) == 0); + for (int i = 0; i < 10; i++) + CHECK(hugoOps.pkReadRecord(pNdb, i, true) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 0); + CHECK(hugoOps.closeTransaction(pNdb) == 0); + + // Update + CHECK(hugoOps.startTransaction(pNdb) == 0); + for (int i = 0; i < 10; i++) + CHECK(hugoOps.pkUpdateRecord(pNdb, i) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 0); + CHECK(hugoOps.closeTransaction(pNdb) == 0); + + // Delete + CHECK(hugoOps.startTransaction(pNdb) == 0); + for (int i = 0; i < 10; i++) + CHECK(hugoOps.pkDeleteRecord(pNdb, i) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 0); + CHECK(hugoOps.closeTransaction(pNdb) == 0); + + // Try to insert, record should already exist + CHECK(hugoOps.startTransaction(pNdb) == 0); + for (int i = 0; i < 10; i++) + CHECK(hugoOps.pkInsertRecord(pNdb, i) == 0); + CHECK(hugoOps.execute_Commit(pNdb) == 630); + CHECK(hugoOps.closeTransaction(pNdb) == 0); + + }while(false); + + hugoOps.closeTransaction(pNdb); + + return result; +} + + + +int runCheckRollbackDelete(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + + do{ + + // Read value and save it for later + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 5) == 0); + CHECK(hugoOps.execute_Commit(pNdb) == 0); + CHECK(hugoOps.saveCopyOfRecord() == NDBT_OK); + CHECK(hugoOps.closeTransaction(pNdb) == 0); + + // Delete record 5 + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkDeleteRecord(pNdb, 5) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 0); + + // Check record is deleted + CHECK(hugoOps.pkReadRecord(pNdb, 5, true) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 626); + CHECK(hugoOps.execute_Rollback(pNdb) == 0); + + CHECK(hugoOps.closeTransaction(pNdb) == 0); + + // Check record is not deleted + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 5, true) == 0); + CHECK(hugoOps.execute_Commit(pNdb) == 0); + CHECK(hugoOps.closeTransaction(pNdb) == 0); + + // Check record is back to original value + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 5, true) == 0); + CHECK(hugoOps.execute_Commit(pNdb) == 0); + CHECK(hugoOps.compareRecordToCopy() == NDBT_OK); + + + }while(false); + + hugoOps.closeTransaction(pNdb); + + return result; +} + +int runCheckRollbackUpdate(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + int numRecords = 5; + do{ + + // Read value and save it for later + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 1, false, numRecords) == 0); + CHECK(hugoOps.execute_Commit(pNdb) == 0); + CHECK(hugoOps.verifyUpdatesValue(0) == NDBT_OK); // Update value 0 + CHECK(hugoOps.closeTransaction(pNdb) == 0); + + // Update record 5 + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkUpdateRecord(pNdb, 1, numRecords, 5) == 0);// Updates value 5 + CHECK(hugoOps.execute_NoCommit(pNdb) == 0); + + // Check record is updated + CHECK(hugoOps.pkReadRecord(pNdb, 1, true, numRecords) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 0); + CHECK(hugoOps.verifyUpdatesValue(5) == NDBT_OK); // Updates value 5 + CHECK(hugoOps.execute_Rollback(pNdb) == 0); + + CHECK(hugoOps.closeTransaction(pNdb) == 0); + + // Check record is back to original value + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 1, true, numRecords) == 0); + CHECK(hugoOps.execute_Commit(pNdb) == 0); + CHECK(hugoOps.verifyUpdatesValue(0) == NDBT_OK); // Updates value 0 + + }while(false); + + hugoOps.closeTransaction(pNdb); + + return result; +} + +int runCheckRollbackDeleteMultiple(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + + do{ + // Read value and save it for later + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 5, false, 10) == 0); + CHECK(hugoOps.execute_Commit(pNdb) == 0); + CHECK(hugoOps.verifyUpdatesValue(0) == NDBT_OK); + CHECK(hugoOps.closeTransaction(pNdb) == 0); + + Uint32 updatesValue = 0; + + for(Uint32 i = 0; i<1; i++){ + // Read record 5 - 10 + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 5, true, 10) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 0); + + for(Uint32 j = 0; j<10; j++){ + // Update record 5 - 10 + updatesValue++; + CHECK(hugoOps.pkUpdateRecord(pNdb, 5, 10, updatesValue) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 0); + + CHECK(hugoOps.pkReadRecord(pNdb, 5, true, 10) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 0); + CHECK(hugoOps.verifyUpdatesValue(updatesValue) == 0); + } + + for(Uint32 j = 0; j<10; j++){ + // Delete record 5 - 10 times + CHECK(hugoOps.pkDeleteRecord(pNdb, 5, 10) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 0); + +#if 0 + // Check records are deleted + CHECK(hugoOps.pkReadRecord(pNdb, 5, true, 10) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 626); +#endif + + updatesValue++; + CHECK(hugoOps.pkInsertRecord(pNdb, 5, 10, updatesValue) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 0); + + CHECK(hugoOps.pkReadRecord(pNdb, 5, true, 10) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 0); + CHECK(hugoOps.verifyUpdatesValue(updatesValue) == 0); + } + + CHECK(hugoOps.pkDeleteRecord(pNdb, 5, 10) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 0); + + // Check records are deleted + CHECK(hugoOps.pkReadRecord(pNdb, 5, true, 10) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 626); + CHECK(hugoOps.execute_Rollback(pNdb) == 0); + + CHECK(hugoOps.closeTransaction(pNdb) == 0); + } + + // Check records are not deleted + // after rollback + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 5, true, 10) == 0); + CHECK(hugoOps.execute_Commit(pNdb) == 0); + CHECK(hugoOps.verifyUpdatesValue(0) == NDBT_OK); + + }while(false); + + hugoOps.closeTransaction(pNdb); + + return result; +} + + +int runCheckImplicitRollbackDelete(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + + do{ + // Read record 5 + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 5, true) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 0); + CHECK(hugoOps.closeTransaction(pNdb) == 0); + + // Update record 5 + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkUpdateRecord(pNdb, 5) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 0); + CHECK(hugoOps.closeTransaction(pNdb) == 0); + + // Delete record 5 + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkDeleteRecord(pNdb, 5) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 0); + CHECK(hugoOps.closeTransaction(pNdb) == 0); + + // Check record is not deleted + // Close transaction should have rollbacked + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 5, true) == 0); + CHECK(hugoOps.execute_Commit(pNdb) == 0); + }while(false); + + hugoOps.closeTransaction(pNdb); + + return result; +} + +int runCheckCommitDelete(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + + do{ + // Read 10 records + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 5, true, 10) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 0); + + // Update 10 records + CHECK(hugoOps.pkUpdateRecord(pNdb, 5, 10) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 0); + + // Delete 10 records + CHECK(hugoOps.pkDeleteRecord(pNdb, 5, 10) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 0); + + CHECK(hugoOps.execute_Commit(pNdb) == 0); + CHECK(hugoOps.closeTransaction(pNdb) == 0); + + // Check record's are deleted + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 5, true, 10) == 0); + CHECK(hugoOps.execute_Commit(pNdb) == 626); + + }while(false); + + hugoOps.closeTransaction(pNdb); + + return result; +} + +int runRollbackNothing(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + + do{ + // Delete record 5 - 15 + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkDeleteRecord(pNdb, 5, 10) == 0); + // Rollback + CHECK(hugoOps.execute_Rollback(pNdb) == 0); + CHECK(hugoOps.closeTransaction(pNdb) == 0); + + // Check records are not deleted + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, 5, true, 10) == 0); + CHECK(hugoOps.execute_Commit(pNdb) == 0); + CHECK(hugoOps.closeTransaction(pNdb) == 0); + + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.execute_Rollback(pNdb) == 0); + + }while(false); + + hugoOps.closeTransaction(pNdb); + + return result; +} + +int runMassiveRollback(NDBT_Context* ctx, NDBT_Step* step){ + + NdbRestarter restarter; + const int records = 4 * restarter.getNumDbNodes(); + + HugoTransactions hugoTrans(*ctx->getTab()); + if (hugoTrans.loadTable(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + + int result = NDBT_OK; + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + + const Uint32 OPS_PER_TRANS = 256; + const Uint32 OPS_TOTAL = 4096; + + for(int row = 0; row < records; row++){ + CHECK(hugoOps.startTransaction(pNdb) == 0); + for(int i = 0; igetTab()); + if (hugoTrans.loadTable(GETNDB(step), 1) != 0){ + return NDBT_FAILED; + } + + int result = NDBT_OK; + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + + const Uint32 OPS_TOTAL = 4096; + const Uint32 LOOPS = 10; + + for(int loop = 0; loop -#include -#include -#include -#include - -#define GETNDB(ps) ((NDBT_NdbApiStep*)ps)->getNdb() - - -/** - * TODO - * dirtyWrite, write, dirtyUpdate - * delete should be visible to same transaction - * - */ - -int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ - - int records = ctx->getNumRecords(); - HugoTransactions hugoTrans(*ctx->getTab()); - if (hugoTrans.loadTable(GETNDB(step), records) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runInsert(NDBT_Context* ctx, NDBT_Step* step){ - - int records = ctx->getNumRecords(); - HugoTransactions hugoTrans(*ctx->getTab()); - // Insert records, dont allow any - // errors(except temporary) while inserting - if (hugoTrans.loadTable(GETNDB(step), records, 1, false) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runInsertTwice(NDBT_Context* ctx, NDBT_Step* step){ - - int records = ctx->getNumRecords(); - HugoTransactions hugoTrans(*ctx->getTab()); - // Insert records, expect primary key violation 630 - if (hugoTrans.loadTable(GETNDB(step), records, 1, false) != 630){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runVerifyInsert(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - - HugoTransactions hugoTrans(*ctx->getTab()); - if (hugoTrans.pkDelRecords(GETNDB(step), records, 1, false) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runInsertUntilStopped(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - int i = 0; - HugoTransactions hugoTrans(*ctx->getTab()); - while (ctx->isTestStopped() == false) { - g_info << i << ": "; - if (hugoTrans.loadTable(GETNDB(step), records) != 0){ - g_info << endl; - return NDBT_FAILED; - } - i++; - } - g_info << endl; - return NDBT_OK; -} - -int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - int batchSize = ctx->getProperty("BatchSize", 1); - - HugoTransactions hugoTrans(*ctx->getTab()); - if (hugoTrans.pkDelRecords(GETNDB(step), records, batchSize) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runPkDelete(NDBT_Context* ctx, NDBT_Step* step){ - int loops = ctx->getNumLoops(); - int records = ctx->getNumRecords(); - - int i = 0; - HugoTransactions hugoTrans(*ctx->getTab()); - while (igetNumLoops(); - int records = ctx->getNumRecords(); - int batchSize = ctx->getProperty("BatchSize", 1); - int i = 0; - HugoTransactions hugoTrans(*ctx->getTab()); - while (igetNumLoops(); - int records = ctx->getNumRecords(); - int batchSize = ctx->getProperty("BatchSize", 1); - int i = 0; - bool dirty = true; - HugoTransactions hugoTrans(*ctx->getTab()); - while (igetNumRecords(); - int batchSize = ctx->getProperty("BatchSize", 1); - int i = 0; - HugoTransactions hugoTrans(*ctx->getTab()); - while (ctx->isTestStopped() == false) { - g_info << i << ": "; - if (hugoTrans.pkReadRecords(GETNDB(step), records, batchSize) != 0){ - g_info << endl; - return NDBT_FAILED; - } - i++; - } - g_info << endl; - return NDBT_OK; -} - -int runPkUpdate(NDBT_Context* ctx, NDBT_Step* step){ - int loops = ctx->getNumLoops(); - int records = ctx->getNumRecords(); - int batchSize = ctx->getProperty("BatchSize", 1); - int i = 0; - HugoTransactions hugoTrans(*ctx->getTab()); - while (igetNumRecords(); - int batchSize = ctx->getProperty("BatchSize", 1); - int i = 0; - HugoTransactions hugoTrans(*ctx->getTab()); - while (ctx->isTestStopped()) { - g_info << i << ": "; - if (hugoTrans.pkUpdateRecords(GETNDB(step), records, batchSize) != 0){ - g_info << endl; - return NDBT_FAILED; - } - i++; - } - g_info << endl; - return NDBT_OK; -} - -int runLocker(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - int records = ctx->getNumRecords(); - HugoTransactions hugoTrans(*ctx->getTab()); - - if (hugoTrans.lockRecords(GETNDB(step), records, 10, 500) != 0){ - result = NDBT_FAILED; - } - ctx->stopTest(); - - return result; -} - -int -runInsertOne(NDBT_Context* ctx, NDBT_Step* step){ - - if(ctx->getProperty("InsertCommitted", (Uint32)0) != 0){ - abort(); - } - - while(ctx->getProperty("Read1Performed", (Uint32)0) == 0){ - NdbSleep_MilliSleep(20); - } - - HugoTransactions hugoTrans(*ctx->getTab()); - - if (hugoTrans.loadTable(GETNDB(step), 1, 1) != 0){ - return NDBT_FAILED; - } - - ctx->setProperty("InsertCommitted", 1); - - NdbSleep_SecSleep(2); - - return NDBT_OK; -} - -static -int -readOneNoCommit(Ndb* pNdb, NdbConnection* pTrans, - const NdbDictionary::Table* tab,NDBT_ResultRow * row){ - - NdbOperation * pOp = pTrans->getNdbOperation(tab->getName()); - if (pOp == NULL){ - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - HugoTransactions tmp(*tab); - - int check = pOp->readTuple(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - - // Define primary keys - for(int a = 0; agetNoOfColumns(); a++){ - if (tab->getColumn(a)->getPrimaryKey() == true){ - if(tmp.equalForAttr(pOp, a, 0) != 0){ - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - } - } - - // Define attributes to read - for(int a = 0; agetNoOfColumns(); a++){ - if((row->attributeStore(a) = - pOp->getValue(tab->getColumn(a)->getName())) == 0) { - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - } - - check = pTrans->execute(NoCommit); - if( check == -1 ) { - const NdbError err = pTrans->getNdbError(); - ERR(err); - return err.code; - } - return NDBT_OK; -} - -int -runReadOne(NDBT_Context* ctx, NDBT_Step* step){ - - Ndb* pNdb = GETNDB(step); - const NdbDictionary::Table* tab = ctx->getTab(); - NDBT_ResultRow row1(*tab); - NDBT_ResultRow row2(*tab); - - if(ctx->getProperty("Read1Performed", (Uint32)0) != 0){ - abort(); - } - - if(ctx->getProperty("InsertCommitted", (Uint32)0) != 0){ - abort(); - } - - NdbConnection * pTrans = pNdb->startTransaction(); - if (pTrans == NULL) { - abort(); - } - - // Read a record with NoCommit - // Since the record isn't inserted yet it wil return 626 - const int res1 = readOneNoCommit(pNdb, pTrans, tab, &row1); - g_info << "|- res1 = " << res1 << endl; - - ctx->setProperty("Read1Performed", 1); - - while(ctx->getProperty("InsertCommitted", (Uint32)0) == 0 && - !ctx->isTestStopped()){ - g_info << "|- Waiting for insert" << endl; - NdbSleep_MilliSleep(20); - } - - if(ctx->isTestStopped()){ - abort(); - } - - // Now the record should have been inserted - // Read it once again in the same transaction - // Should also reutrn 626 if reads are consistent - - // NOTE! Currently it's not possible to start a new operation - // on a transaction that has returned an error code - // This is wat fail in this test - // MASV 20030624 - const int res2 = readOneNoCommit(pNdb, pTrans, tab, &row2); - - pTrans->execute(Commit); - pNdb->closeTransaction(pTrans); - g_info << "|- res2 = " << res2 << endl; - - if (res2 == 626 && res1 == res2) - return NDBT_OK; - else - return NDBT_FAILED; -} - -int runFillTable(NDBT_Context* ctx, NDBT_Step* step){ - int batch = 512; //4096; - HugoTransactions hugoTrans(*ctx->getTab()); - if (hugoTrans.fillTable(GETNDB(step), batch ) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runClearTable2(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - - UtilTransactions utilTrans(*ctx->getTab()); - if (utilTrans.clearTable2(GETNDB(step), records, 240) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -#define CHECK(b) if (!(b)) { \ - ndbout << "ERR: "<< step->getName() \ - << " failed on line " << __LINE__ << endl; \ - result = NDBT_FAILED; \ - break; } - -int runNoCommitSleep(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - HugoOperations hugoOps(*ctx->getTab()); - Ndb* pNdb = GETNDB(step); - int sleepTime = 100; // ms - for (int i = 2; i < 8; i++){ - - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); - CHECK(hugoOps.execute_NoCommit(pNdb) == 0); - - ndbout << i <<": Sleeping for " << sleepTime << " ms" << endl; - NdbSleep_MilliSleep(sleepTime); - - // Dont care about result of these ops - hugoOps.pkReadRecord(pNdb, 1, true); - hugoOps.closeTransaction(pNdb); - - sleepTime = sleepTime *i; - } - - hugoOps.closeTransaction(pNdb); - - return result; -} - -int runCommit626(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - HugoOperations hugoOps(*ctx->getTab()); - Ndb* pNdb = GETNDB(step); - - do{ - // Commit transaction - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); - CHECK(hugoOps.execute_Commit(pNdb) == 626); - CHECK(hugoOps.closeTransaction(pNdb) == 0); - - // Commit transaction - // Multiple operations - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 2, true) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 3, true) == 0); - CHECK(hugoOps.execute_Commit(pNdb) == 626); - }while(false); - - hugoOps.closeTransaction(pNdb); - - return result; -} - -int runCommit630(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - HugoOperations hugoOps(*ctx->getTab()); - Ndb* pNdb = GETNDB(step); - - do{ - // Commit transaction - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0); - CHECK(hugoOps.execute_Commit(pNdb) == 630); - }while(false); - - hugoOps.closeTransaction(pNdb); - - return result; -} - -int runCommit_TryCommit626(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - HugoOperations hugoOps(*ctx->getTab()); - Ndb* pNdb = GETNDB(step); - - do{ - // Commit transaction, TryCommit - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); - CHECK(hugoOps.execute_Commit(pNdb, TryCommit) == 626); - CHECK(hugoOps.closeTransaction(pNdb) == 0); - - // Commit transaction, TryCommit - // Several operations in one transaction - // The insert is OK - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 2, true) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 3, true) == 0); - CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 4, true) == 0); - CHECK(hugoOps.execute_Commit(pNdb, TryCommit) == 626); - }while(false); - - hugoOps.closeTransaction(pNdb); - - return result; -} - -int runCommit_TryCommit630(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - HugoOperations hugoOps(*ctx->getTab()); - Ndb* pNdb = GETNDB(step); - - do{ - // Commit transaction, TryCommit - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0); - CHECK(hugoOps.execute_Commit(pNdb, TryCommit) == 630); - }while(false); - - hugoOps.closeTransaction(pNdb); - - return result; -} - -int runCommit_CommitAsMuchAsPossible626(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - HugoOperations hugoOps(*ctx->getTab()); - Ndb* pNdb = GETNDB(step); - - do{ - // Commit transaction, CommitAsMuchAsPossible - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); - CHECK(hugoOps.execute_Commit(pNdb, CommitAsMuchAsPossible) == 626); - CHECK(hugoOps.closeTransaction(pNdb) == 0); - - // Commit transaction, CommitAsMuchAsPossible - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 2, true) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 3, true) == 0); - CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 4, true) == 0); - CHECK(hugoOps.execute_Commit(pNdb, CommitAsMuchAsPossible) == 626); - CHECK(hugoOps.closeTransaction(pNdb) == 0); - }while(false); - - hugoOps.closeTransaction(pNdb); - - return result; -} - -int runCommit_CommitAsMuchAsPossible630(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - HugoOperations hugoOps(*ctx->getTab()); - Ndb* pNdb = GETNDB(step); - - do{ - // Commit transaction, CommitAsMuchAsPossible - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0); - CHECK(hugoOps.execute_Commit(pNdb, CommitAsMuchAsPossible) == 630); - }while(false); - - hugoOps.closeTransaction(pNdb); - - return result; -} - -int runNoCommit626(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - HugoOperations hugoOps(*ctx->getTab()); - Ndb* pNdb = GETNDB(step); - - do{ - // No commit transaction, readTuple - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 1, false) == 0); - CHECK(hugoOps.execute_NoCommit(pNdb) == 626); - CHECK(hugoOps.closeTransaction(pNdb) == 0); - - // No commit transaction, readTupleExcluive - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); - CHECK(hugoOps.execute_NoCommit(pNdb) == 626); - }while(false); - - hugoOps.closeTransaction(pNdb); - - return result; -} - -int runNoCommit630(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - HugoOperations hugoOps(*ctx->getTab()); - Ndb* pNdb = GETNDB(step); - - do{ - // No commit transaction - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0); - CHECK(hugoOps.execute_NoCommit(pNdb) == 630); - }while(false); - - hugoOps.closeTransaction(pNdb); - - return result; -} - -int runNoCommitRollback626(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - HugoOperations hugoOps(*ctx->getTab()); - Ndb* pNdb = GETNDB(step); - - do{ - // No commit transaction, rollback - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); - CHECK(hugoOps.execute_NoCommit(pNdb) == 626); - CHECK(hugoOps.execute_Rollback(pNdb) == 0); - CHECK(hugoOps.closeTransaction(pNdb) == 0); - - // No commit transaction, rollback - // Multiple operations - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 1, true) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 2, true) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 3, true) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 4, true) == 0); - CHECK(hugoOps.execute_NoCommit(pNdb) == 626); - CHECK(hugoOps.execute_Rollback(pNdb) == 0); - }while(false); - - hugoOps.closeTransaction(pNdb); - - return result; -} - -int runNoCommitRollback630(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - HugoOperations hugoOps(*ctx->getTab()); - Ndb* pNdb = GETNDB(step); - - do{ - // No commit transaction, rollback - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0); - CHECK(hugoOps.execute_NoCommit(pNdb) == 630); - CHECK(hugoOps.execute_Rollback(pNdb) == 0); - }while(false); - - hugoOps.closeTransaction(pNdb); - - return result; -} - - -int runNoCommitAndClose(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - HugoOperations hugoOps(*ctx->getTab()); - Ndb* pNdb = GETNDB(step); - - do{ - // Read - CHECK(hugoOps.startTransaction(pNdb) == 0); - for (int i = 0; i < 10; i++) - CHECK(hugoOps.pkReadRecord(pNdb, i, true) == 0); - CHECK(hugoOps.execute_NoCommit(pNdb) == 0); - CHECK(hugoOps.closeTransaction(pNdb) == 0); - - // Update - CHECK(hugoOps.startTransaction(pNdb) == 0); - for (int i = 0; i < 10; i++) - CHECK(hugoOps.pkUpdateRecord(pNdb, i) == 0); - CHECK(hugoOps.execute_NoCommit(pNdb) == 0); - CHECK(hugoOps.closeTransaction(pNdb) == 0); - - // Delete - CHECK(hugoOps.startTransaction(pNdb) == 0); - for (int i = 0; i < 10; i++) - CHECK(hugoOps.pkDeleteRecord(pNdb, i) == 0); - CHECK(hugoOps.execute_NoCommit(pNdb) == 0); - CHECK(hugoOps.closeTransaction(pNdb) == 0); - - // Try to insert, record should already exist - CHECK(hugoOps.startTransaction(pNdb) == 0); - for (int i = 0; i < 10; i++) - CHECK(hugoOps.pkInsertRecord(pNdb, i) == 0); - CHECK(hugoOps.execute_Commit(pNdb) == 630); - CHECK(hugoOps.closeTransaction(pNdb) == 0); - - }while(false); - - hugoOps.closeTransaction(pNdb); - - return result; -} - - - -int runCheckRollbackDelete(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - HugoOperations hugoOps(*ctx->getTab()); - Ndb* pNdb = GETNDB(step); - - do{ - - // Read value and save it for later - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 5) == 0); - CHECK(hugoOps.execute_Commit(pNdb) == 0); - CHECK(hugoOps.saveCopyOfRecord() == NDBT_OK); - CHECK(hugoOps.closeTransaction(pNdb) == 0); - - // Delete record 5 - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkDeleteRecord(pNdb, 5) == 0); - CHECK(hugoOps.execute_NoCommit(pNdb) == 0); - - // Check record is deleted - CHECK(hugoOps.pkReadRecord(pNdb, 5, true) == 0); - CHECK(hugoOps.execute_NoCommit(pNdb) == 626); - CHECK(hugoOps.execute_Rollback(pNdb) == 0); - - CHECK(hugoOps.closeTransaction(pNdb) == 0); - - // Check record is not deleted - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 5, true) == 0); - CHECK(hugoOps.execute_Commit(pNdb) == 0); - CHECK(hugoOps.closeTransaction(pNdb) == 0); - - // Check record is back to original value - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 5, true) == 0); - CHECK(hugoOps.execute_Commit(pNdb) == 0); - CHECK(hugoOps.compareRecordToCopy() == NDBT_OK); - - - }while(false); - - hugoOps.closeTransaction(pNdb); - - return result; -} - -int runCheckRollbackUpdate(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - HugoOperations hugoOps(*ctx->getTab()); - Ndb* pNdb = GETNDB(step); - int numRecords = 5; - do{ - - // Read value and save it for later - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 1, false, numRecords) == 0); - CHECK(hugoOps.execute_Commit(pNdb) == 0); - CHECK(hugoOps.verifyUpdatesValue(0) == NDBT_OK); // Update value 0 - CHECK(hugoOps.closeTransaction(pNdb) == 0); - - // Update record 5 - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkUpdateRecord(pNdb, 1, numRecords, 5) == 0);// Updates value 5 - CHECK(hugoOps.execute_NoCommit(pNdb) == 0); - - // Check record is updated - CHECK(hugoOps.pkReadRecord(pNdb, 1, true, numRecords) == 0); - CHECK(hugoOps.execute_NoCommit(pNdb) == 0); - CHECK(hugoOps.verifyUpdatesValue(5) == NDBT_OK); // Updates value 5 - CHECK(hugoOps.execute_Rollback(pNdb) == 0); - - CHECK(hugoOps.closeTransaction(pNdb) == 0); - - // Check record is back to original value - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 1, true, numRecords) == 0); - CHECK(hugoOps.execute_Commit(pNdb) == 0); - CHECK(hugoOps.verifyUpdatesValue(0) == NDBT_OK); // Updates value 0 - - }while(false); - - hugoOps.closeTransaction(pNdb); - - return result; -} - -int runCheckRollbackDeleteMultiple(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - HugoOperations hugoOps(*ctx->getTab()); - Ndb* pNdb = GETNDB(step); - - do{ - // Read value and save it for later - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 5, false, 10) == 0); - CHECK(hugoOps.execute_Commit(pNdb) == 0); - CHECK(hugoOps.verifyUpdatesValue(0) == NDBT_OK); - CHECK(hugoOps.closeTransaction(pNdb) == 0); - - Uint32 updatesValue = 0; - - for(Uint32 i = 0; i<1; i++){ - // Read record 5 - 10 - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 5, true, 10) == 0); - CHECK(hugoOps.execute_NoCommit(pNdb) == 0); - - for(Uint32 j = 0; j<10; j++){ - // Update record 5 - 10 - updatesValue++; - CHECK(hugoOps.pkUpdateRecord(pNdb, 5, 10, updatesValue) == 0); - CHECK(hugoOps.execute_NoCommit(pNdb) == 0); - - CHECK(hugoOps.pkReadRecord(pNdb, 5, true, 10) == 0); - CHECK(hugoOps.execute_NoCommit(pNdb) == 0); - CHECK(hugoOps.verifyUpdatesValue(updatesValue) == 0); - } - - for(Uint32 j = 0; j<10; j++){ - // Delete record 5 - 10 times - CHECK(hugoOps.pkDeleteRecord(pNdb, 5, 10) == 0); - CHECK(hugoOps.execute_NoCommit(pNdb) == 0); - -#if 0 - // Check records are deleted - CHECK(hugoOps.pkReadRecord(pNdb, 5, true, 10) == 0); - CHECK(hugoOps.execute_NoCommit(pNdb) == 626); -#endif - - updatesValue++; - CHECK(hugoOps.pkInsertRecord(pNdb, 5, 10, updatesValue) == 0); - CHECK(hugoOps.execute_NoCommit(pNdb) == 0); - - CHECK(hugoOps.pkReadRecord(pNdb, 5, true, 10) == 0); - CHECK(hugoOps.execute_NoCommit(pNdb) == 0); - CHECK(hugoOps.verifyUpdatesValue(updatesValue) == 0); - } - - CHECK(hugoOps.pkDeleteRecord(pNdb, 5, 10) == 0); - CHECK(hugoOps.execute_NoCommit(pNdb) == 0); - - // Check records are deleted - CHECK(hugoOps.pkReadRecord(pNdb, 5, true, 10) == 0); - CHECK(hugoOps.execute_NoCommit(pNdb) == 626); - CHECK(hugoOps.execute_Rollback(pNdb) == 0); - - CHECK(hugoOps.closeTransaction(pNdb) == 0); - } - - // Check records are not deleted - // after rollback - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 5, true, 10) == 0); - CHECK(hugoOps.execute_Commit(pNdb) == 0); - CHECK(hugoOps.verifyUpdatesValue(0) == NDBT_OK); - - }while(false); - - hugoOps.closeTransaction(pNdb); - - return result; -} - - -int runCheckImplicitRollbackDelete(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - HugoOperations hugoOps(*ctx->getTab()); - Ndb* pNdb = GETNDB(step); - - do{ - // Read record 5 - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 5, true) == 0); - CHECK(hugoOps.execute_NoCommit(pNdb) == 0); - CHECK(hugoOps.closeTransaction(pNdb) == 0); - - // Update record 5 - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkUpdateRecord(pNdb, 5) == 0); - CHECK(hugoOps.execute_NoCommit(pNdb) == 0); - CHECK(hugoOps.closeTransaction(pNdb) == 0); - - // Delete record 5 - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkDeleteRecord(pNdb, 5) == 0); - CHECK(hugoOps.execute_NoCommit(pNdb) == 0); - CHECK(hugoOps.closeTransaction(pNdb) == 0); - - // Check record is not deleted - // Close transaction should have rollbacked - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 5, true) == 0); - CHECK(hugoOps.execute_Commit(pNdb) == 0); - }while(false); - - hugoOps.closeTransaction(pNdb); - - return result; -} - -int runCheckCommitDelete(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - HugoOperations hugoOps(*ctx->getTab()); - Ndb* pNdb = GETNDB(step); - - do{ - // Read 10 records - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 5, true, 10) == 0); - CHECK(hugoOps.execute_NoCommit(pNdb) == 0); - - // Update 10 records - CHECK(hugoOps.pkUpdateRecord(pNdb, 5, 10) == 0); - CHECK(hugoOps.execute_NoCommit(pNdb) == 0); - - // Delete 10 records - CHECK(hugoOps.pkDeleteRecord(pNdb, 5, 10) == 0); - CHECK(hugoOps.execute_NoCommit(pNdb) == 0); - - CHECK(hugoOps.execute_Commit(pNdb) == 0); - CHECK(hugoOps.closeTransaction(pNdb) == 0); - - // Check record's are deleted - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 5, true, 10) == 0); - CHECK(hugoOps.execute_Commit(pNdb) == 626); - - }while(false); - - hugoOps.closeTransaction(pNdb); - - return result; -} - -int runRollbackNothing(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - HugoOperations hugoOps(*ctx->getTab()); - Ndb* pNdb = GETNDB(step); - - do{ - // Delete record 5 - 15 - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkDeleteRecord(pNdb, 5, 10) == 0); - // Rollback - CHECK(hugoOps.execute_Rollback(pNdb) == 0); - CHECK(hugoOps.closeTransaction(pNdb) == 0); - - // Check records are not deleted - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, 5, true, 10) == 0); - CHECK(hugoOps.execute_Commit(pNdb) == 0); - CHECK(hugoOps.closeTransaction(pNdb) == 0); - - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.execute_Rollback(pNdb) == 0); - - }while(false); - - hugoOps.closeTransaction(pNdb); - - return result; -} - -int runMassiveRollback(NDBT_Context* ctx, NDBT_Step* step){ - - NdbRestarter restarter; - const int records = 4 * restarter.getNumDbNodes(); - - HugoTransactions hugoTrans(*ctx->getTab()); - if (hugoTrans.loadTable(GETNDB(step), records) != 0){ - return NDBT_FAILED; - } - - int result = NDBT_OK; - HugoOperations hugoOps(*ctx->getTab()); - Ndb* pNdb = GETNDB(step); - - const Uint32 OPS_PER_TRANS = 256; - const Uint32 OPS_TOTAL = 4096; - - for(int row = 0; row < records; row++){ - CHECK(hugoOps.startTransaction(pNdb) == 0); - for(int i = 0; igetTab()); - if (hugoTrans.loadTable(GETNDB(step), 1) != 0){ - return NDBT_FAILED; - } - - int result = NDBT_OK; - HugoOperations hugoOps(*ctx->getTab()); - Ndb* pNdb = GETNDB(step); - - const Uint32 OPS_TOTAL = 4096; - const Uint32 LOOPS = 10; - - for(int loop = 0; loopgetNdb() + +int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ + + int records = ctx->getNumRecords(); + int batchSize = ctx->getProperty("BatchSize", 1); + int transactions = (records / 100) + 1; + int operations = (records / transactions) + 1; + + HugoAsynchTransactions hugoTrans(*ctx->getTab()); + if (hugoTrans.loadTableAsynch(GETNDB(step), records, batchSize, + transactions, operations) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runInsert(NDBT_Context* ctx, NDBT_Step* step){ + + int records = ctx->getNumRecords(); + int batchSize = ctx->getProperty("BatchSize", 1); + int transactions = (records / 100) + 1; + int operations = (records / transactions) + 1; + + HugoAsynchTransactions hugoTrans(*ctx->getTab()); + // Insert records, dont allow any + // errors(except temporary) while inserting + if (hugoTrans.loadTableAsynch(GETNDB(step), records, batchSize, + transactions, operations) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runVerifyInsert(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + int batchSize = ctx->getProperty("BatchSize", 1); + int transactions = (records / 100) + 1; + int operations = (records / transactions) + 1; + + HugoAsynchTransactions hugoTrans(*ctx->getTab()); + if (hugoTrans.pkDelRecordsAsynch(GETNDB(step), records, batchSize, + transactions, operations) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + int batchSize = ctx->getProperty("BatchSize", 1); + int transactions = (records / 100) + 1; + int operations = (records / transactions) + 1; + + HugoAsynchTransactions hugoTrans(*ctx->getTab()); + if (hugoTrans.pkDelRecordsAsynch(GETNDB(step), records, batchSize, + transactions, operations) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runPkDelete(NDBT_Context* ctx, NDBT_Step* step){ + + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + int batchSize = ctx->getProperty("BatchSize", 1); + int transactions = (records / 100) + 1; + int operations = (records / transactions) + 1; + + int i = 0; + HugoAsynchTransactions hugoTrans(*ctx->getTab()); + while (igetNumLoops(); + int records = ctx->getNumRecords(); + int batchSize = ctx->getProperty("BatchSize", 1); + int transactions = (records / 100) + 1; + int operations = (records / transactions) + 1; + + int i = 0; + HugoAsynchTransactions hugoTrans(*ctx->getTab()); + while (igetNumLoops(); + int records = ctx->getNumRecords(); + int batchSize = ctx->getProperty("BatchSize", 1); + int transactions = (records / 100) + 1; + int operations = (records / transactions) + 1; + + int i = 0; + HugoAsynchTransactions hugoTrans(*ctx->getTab()); + while (i + +#include +#include +#include +#include +#include +#include +#include + +struct Opt { + bool m_core; + const char* m_table; + Opt() : + m_core(false), + m_table("TB1") + { + } +}; + +static Opt opt; + +static void printusage() +{ + Opt d; + ndbout + << "usage: testBlobs [options]" << endl + << "-core dump core on error - default " << d.m_core << endl + ; +} + +static Ndb* myNdb = 0; +static NdbDictionary::Dictionary* myDic = 0; +static NdbConnection* myCon = 0; +static NdbOperation* myOp = 0; +static NdbBlob* myBlob = 0; + +static void +fatal(const char* fmt, ...) +{ + va_list ap; + char buf[200]; + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + ndbout << "fatal: " << buf << endl; + if (myNdb != 0 && myNdb->getNdbError().code != 0) + ndbout << "ndb - " << myNdb->getNdbError() << endl; + if (myDic != 0 && myDic->getNdbError().code != 0) + ndbout << "dic - " << myDic->getNdbError() << endl; + if (opt.m_core) + abort(); + NDBT_ProgramExit(NDBT_FAILED); + exit(1); +} + +static void +dropBlobsTable() +{ + NdbDictionary::Table tab(NDB_BLOB_TABLE_NAME); + if (myDic->dropTable(tab) == -1) + if (myDic->getNdbError().code != 709) + fatal("dropTable"); +} + +static void +createBlobsTable() +{ + NdbDictionary::Table tab(NDB_BLOB_TABLE_NAME); + // col 0 + NdbDictionary::Column col0("BLOBID"); + col0.setPrimaryKey(true); + col0.setType(NdbDictionary::Column::Bigunsigned); + tab.addColumn(col0); + // col 1 + NdbDictionary::Column col1("DATA"); + col1.setPrimaryKey(false); + col1.setType(NdbDictionary::Column::Binary); + col1.setLength(NDB_BLOB_PIECE_SIZE); + tab.addColumn(col1); + // create + if (myDic->createTable(tab) == -1) + fatal("createTable"); +} + +static void +dropTable() +{ + NdbDictionary::Table tab(opt.m_table); + if (myDic->dropTable(tab) == -1) + if (myDic->getNdbError().code != 709) + fatal("dropTable"); +} + +static void +createTable() +{ + NdbDictionary::Table tab(opt.m_table); + // col 0 + NdbDictionary::Column col0("A"); + col0.setPrimaryKey(true); + col0.setType(NdbDictionary::Column::Unsigned); + tab.addColumn(col0); + // col 1 + NdbDictionary::Column col1("B"); + col1.setPrimaryKey(false); + col1.setType(NdbDictionary::Column::Blob); + tab.addColumn(col1); + // create + if (myDic->createTable(tab) == -1) + fatal("createTable"); +} + +static void +insertData(Uint32 key) +{ +} + +static void +insertTuples() +{ + for (Uint32 key = 0; key <= 99; key++) { + if ((myCon = myNdb->startTransaction()) == 0) + fatal("startTransaction"); + if ((myOp = myCon->getNdbOperation(opt.m_table)) == 0) + fatal("getNdbOperation"); + if (myOp->insertTuple() == -1) + fatal("insertTuple"); + if (myOp->setValue((unsigned)0, key) == -1) + fatal("setValue %u", (unsigned)key); + if ((myBlob = myOp->setBlob(1)) == 0) + fatal("setBlob"); + if (myCon->execute(NoCommit) == -1) + fatal("execute NoCommit"); + insertData(key); + if (myCon->execute(Commit) == -1) + fatal("execute Commit"); + myNdb->closeTransaction(myCon); + myOp = 0; + myBlob = 0; + myCon = 0; + } +} + +static void +testMain() +{ + myNdb = new Ndb("TEST_DB"); + if (myNdb->init() != 0) + fatal("init"); + if (myNdb->waitUntilReady() < 0) + fatal("waitUntilReady"); + myDic = myNdb->getDictionary(); + dropBlobsTable(); + createBlobsTable(); // until moved to Ndbcntr + dropTable(); + createTable(); + insertTuples(); +} + +NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535) +{ + while (++argv, --argc > 0) { + const char* arg = argv[0]; + if (strcmp(arg, "-core") == 0) { + opt.m_core = true; + continue; + } + } + testMain(); + return NDBT_ProgramExit(NDBT_OK); +} + +// vim: set sw=4: diff --git a/ndb/test/ndbapi/testBlobs/Makefile b/ndb/test/ndbapi/testBlobs/Makefile deleted file mode 100644 index cc5bb629c17..00000000000 --- a/ndb/test/ndbapi/testBlobs/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -include .defs.mk - -TYPE = ndbapitest - -BIN_TARGET = testBlobs - -SOURCES = testBlobs.cpp - -include $(NDB_TOP)/Epilogue.mk - -CCFLAGS_LOC += -I$(NDB_TOP)/include/kernel diff --git a/ndb/test/ndbapi/testBlobs/testBlobs.cpp b/ndb/test/ndbapi/testBlobs/testBlobs.cpp deleted file mode 100644 index 9f959702402..00000000000 --- a/ndb/test/ndbapi/testBlobs/testBlobs.cpp +++ /dev/null @@ -1,195 +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 */ - -/* - * testBlobs - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -struct Opt { - bool m_core; - const char* m_table; - Opt() : - m_core(false), - m_table("TB1") - { - } -}; - -static Opt opt; - -static void printusage() -{ - Opt d; - ndbout - << "usage: testBlobs [options]" << endl - << "-core dump core on error - default " << d.m_core << endl - ; -} - -static Ndb* myNdb = 0; -static NdbDictionary::Dictionary* myDic = 0; -static NdbConnection* myCon = 0; -static NdbOperation* myOp = 0; -static NdbBlob* myBlob = 0; - -static void -fatal(const char* fmt, ...) -{ - va_list ap; - char buf[200]; - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - ndbout << "fatal: " << buf << endl; - if (myNdb != 0 && myNdb->getNdbError().code != 0) - ndbout << "ndb - " << myNdb->getNdbError() << endl; - if (myDic != 0 && myDic->getNdbError().code != 0) - ndbout << "dic - " << myDic->getNdbError() << endl; - if (opt.m_core) - abort(); - NDBT_ProgramExit(NDBT_FAILED); - exit(1); -} - -static void -dropBlobsTable() -{ - NdbDictionary::Table tab(NDB_BLOB_TABLE_NAME); - if (myDic->dropTable(tab) == -1) - if (myDic->getNdbError().code != 709) - fatal("dropTable"); -} - -static void -createBlobsTable() -{ - NdbDictionary::Table tab(NDB_BLOB_TABLE_NAME); - // col 0 - NdbDictionary::Column col0("BLOBID"); - col0.setPrimaryKey(true); - col0.setType(NdbDictionary::Column::Bigunsigned); - tab.addColumn(col0); - // col 1 - NdbDictionary::Column col1("DATA"); - col1.setPrimaryKey(false); - col1.setType(NdbDictionary::Column::Binary); - col1.setLength(NDB_BLOB_PIECE_SIZE); - tab.addColumn(col1); - // create - if (myDic->createTable(tab) == -1) - fatal("createTable"); -} - -static void -dropTable() -{ - NdbDictionary::Table tab(opt.m_table); - if (myDic->dropTable(tab) == -1) - if (myDic->getNdbError().code != 709) - fatal("dropTable"); -} - -static void -createTable() -{ - NdbDictionary::Table tab(opt.m_table); - // col 0 - NdbDictionary::Column col0("A"); - col0.setPrimaryKey(true); - col0.setType(NdbDictionary::Column::Unsigned); - tab.addColumn(col0); - // col 1 - NdbDictionary::Column col1("B"); - col1.setPrimaryKey(false); - col1.setType(NdbDictionary::Column::Blob); - tab.addColumn(col1); - // create - if (myDic->createTable(tab) == -1) - fatal("createTable"); -} - -static void -insertData(Uint32 key) -{ -} - -static void -insertTuples() -{ - for (Uint32 key = 0; key <= 99; key++) { - if ((myCon = myNdb->startTransaction()) == 0) - fatal("startTransaction"); - if ((myOp = myCon->getNdbOperation(opt.m_table)) == 0) - fatal("getNdbOperation"); - if (myOp->insertTuple() == -1) - fatal("insertTuple"); - if (myOp->setValue((unsigned)0, key) == -1) - fatal("setValue %u", (unsigned)key); - if ((myBlob = myOp->setBlob(1)) == 0) - fatal("setBlob"); - if (myCon->execute(NoCommit) == -1) - fatal("execute NoCommit"); - insertData(key); - if (myCon->execute(Commit) == -1) - fatal("execute Commit"); - myNdb->closeTransaction(myCon); - myOp = 0; - myBlob = 0; - myCon = 0; - } -} - -static void -testMain() -{ - myNdb = new Ndb("TEST_DB"); - if (myNdb->init() != 0) - fatal("init"); - if (myNdb->waitUntilReady() < 0) - fatal("waitUntilReady"); - myDic = myNdb->getDictionary(); - dropBlobsTable(); - createBlobsTable(); // until moved to Ndbcntr - dropTable(); - createTable(); - insertTuples(); -} - -NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535) -{ - while (++argv, --argc > 0) { - const char* arg = argv[0]; - if (strcmp(arg, "-core") == 0) { - opt.m_core = true; - continue; - } - } - testMain(); - return NDBT_ProgramExit(NDBT_OK); -} - -// vim: set sw=4: diff --git a/ndb/test/ndbapi/testDataBuffers.cpp b/ndb/test/ndbapi/testDataBuffers.cpp new file mode 100644 index 00000000000..b8e0fef6cef --- /dev/null +++ b/ndb/test/ndbapi/testDataBuffers.cpp @@ -0,0 +1,616 @@ +/* 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 */ + +/* + * testDataBuffers + * + * Test getValue() of byte arrays: + * - using application buffers of different alignments and sizes + * - using NdbApi allocated small (<32) and big (>=32) buffers + * + * Verifies fixes to tickets 189 and 206. + * + * Options: see printusage() below. + * + * Creates tables TB00 to TB15 + */ + +#include + +#include +#include +#include +#include + +// limits +static int const MaxAttr = 64; +static int const MaxOper = 1000; +static int const MaxSize = 10000; +static int const MaxOff = 64; // max offset to add to data buffer +static int const MaxData = MaxSize + MaxOff + 100; + +// options +static int attrcnt = 25; +static int existok = 0; +static bool kontinue = false; +static int loopcnt = 1; +static int opercnt = 100; // also does this many scans +static int randomizer = 171317; +static int sizelim = 500; +static int xverbose = 0; + +static void printusage() { + ndbout + << "usage: testDataBuffers options [default/max]" + << endl + << "NOTE: too large combinations result in NDB error" + << endl + << "-a N number of attributes (including the key) [25/64]" + << endl + << "-e no error if table exists (assumed to have same structure)" + << endl + << "-k on error continue with next test case" + << endl + << "-l N number of loops to run, 0 means infinite [1]" + << endl + << "-o N number of operations (rows in each table) [100/1000]" + << endl + << "-r N source of randomness (big number (prime)) [171317]" + << endl + << "-s N array size limit (rounded up in some tests) [500/10000]" + << endl + << "-x extremely verbose" + << endl + << "Tables: TB00 .. TB15" + << endl + ; +} + +static Ndb* ndb = 0; +static NdbSchemaCon* tcon = 0; +static NdbSchemaOp* top = 0; +static NdbConnection* con = 0; +static NdbOperation* op = 0; + +static int +ndberror(char const* fmt, ...) +{ + va_list ap; + char buf[200]; + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + ndbout << buf << " --" << endl; + if (ndb) + ndbout << "ndb : " << ndb->getNdbError() << endl; + if (tcon) + ndbout << "tcon: " << tcon->getNdbError() << endl; + if (top) + ndbout << "top : " << top->getNdbError() << endl; + if (con) + ndbout << "con : " << con->getNdbError() << endl; + if (op) + ndbout << "op : " << op->getNdbError() << endl; + return -1; +} + +static int +chkerror(char const* fmt, ...) +{ + va_list ap; + char buf[200]; + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + ndbout << "*** check failed: " << buf << " ***" << endl; + return -1; +} + +// alignment of addresses and data sizes + +static bool isAligned(unsigned x) +{ + return ((x & 3) == 0); +} +static bool isAligned(char* p) +{ + return isAligned(unsigned(p)); +} +static unsigned toAligned(unsigned x) +{ + while (! isAligned(x)) + x++; + return x; +} +static char* toAligned(char* p) +{ + while (! isAligned(p)) + p++; + return p; +} + +// byte value for key k column i byte j +static int byteVal(int k, int i, int j) +{ + return '0' + (k + i + j) % 10; +} + +// tables + +static char tab[20] = ""; + +static struct col { + char aAttrName[20]; + AttrType aAttrType; + int aAttrSize; + int aArraySize; + KeyType aTupleKey; + bool nullable; + NdbRecAttr* aRa; + char* buf; + int bufsiz; + char data[MaxData]; +} ccol[MaxAttr]; + +static int key = 0; + +// independent test bits +static bool alignAddr; // align our buffer addresses to 4x +static bool alignSize; // align data sizes to 4x +static bool useBuf; // use our buffers for output +static bool noRandom; // do not randomize sizes and offsets +static int testbits = 4; + +static int +makeSize(int i) +{ + int n; + if (noRandom) + n = i; + else + n = i * randomizer; + n %= sizelim; + if (n <= 0) + n = 1; + if (alignSize) + n = toAligned(n); + return n; +} + +static int +makeOff(int k) +{ + int n; + if (alignAddr) + n = 0; + else if (noRandom) + n = k; + else + n = k * randomizer; + n %= MaxOff; + if (n < 0) + n = -n; + return n; +} + +static int +testcase(int flag) +{ + ndbout << "--- case " << flag << " ---" << endl; + sprintf(tab, "TB%02d", flag); + + alignAddr = ! (flag & 1); + ndbout << (alignAddr ? "align addresses" : "mis-align addresses") << endl; + alignSize = ! (flag & 2); + ndbout << (alignSize ? "align data sizes" : "mis-align data sizes") << endl; + useBuf = ! (flag & 4); + ndbout << (useBuf ? "use our buffers" : "use ndbapi buffers") << endl; + noRandom = ! (flag & 8); + ndbout << (noRandom ? "simple sizes" : "randomize sizes") << endl; + + int smax = 0, stot = 0; + if (xverbose) + ndbout << "- define table " << tab << endl; + for (int i = 0; i < attrcnt; i++) { + col& c = ccol[i]; + memset(&c, 0, sizeof(c)); + sprintf(c.aAttrName, "C%d", i); + if (i == 0) { + c.aAttrType = UnSigned; + c.aAttrSize = 32; + c.aArraySize = 1; + c.aTupleKey = TupleKey; + c.nullable = false; + } else { + c.aAttrType = String; + c.aAttrSize = 8; + c.aArraySize = makeSize(i); + if (smax < c.aArraySize) + smax = c.aArraySize; + stot += c.aArraySize; + c.aTupleKey = NoKey; + c.nullable = true; + if (xverbose) + ndbout << "-- column " << i << " size=" << c.aArraySize << endl; + } + c.buf = toAligned(c.data); + c.bufsiz = sizeof(c.data) - (c.buf - c.data); + } + ndbout << "tab=" << tab << " cols=" << attrcnt + << " size max=" << smax << " tot=" << stot << endl; + + ndb = new Ndb("TEST_DB"); + if (ndb->init() != 0) + return ndberror("init"); + if (ndb->waitUntilReady(30) < 0) + return ndberror("waitUntilReady"); + + if ((tcon = ndb->startSchemaTransaction()) == 0) + return ndberror("startSchemaTransaction"); + if ((top = tcon->getNdbSchemaOp()) == 0) + return ndberror("getNdbSchemaOp"); + if (top->createTable(tab) < 0) + return ndberror("createTable"); + for (int i = 0; i < attrcnt; i++) { + col& c = ccol[i]; + if (top->createAttribute( + c.aAttrName, + c.aTupleKey, + c.aAttrSize, + c.aArraySize, + c.aAttrType, + MMBased, + c.nullable + ) < 0) + return ndberror("createAttribute col=%d", i); + } + if (tcon->execute() < 0) { + if (! (tcon->getNdbError().code == 721 && existok)) + return ndberror("execute"); + ndbout << "using " << tab << endl; + } else { + ndbout << "created " << tab << endl; + } + top = 0; + tcon = 0; + + if (xverbose) + ndbout << "- delete" << endl; + int delcnt = 0; + for (key = 0; key < opercnt; key++) { + if ((con = ndb->startTransaction()) == 0) + return ndberror("startTransaction key=%d", key); + if ((op = con->getNdbOperation(tab)) == 0) + return ndberror("getNdbOperation key=%d", key); + if (op->deleteTuple() < 0) + return ndberror("deleteTuple key=%d", key); + for (int i = 0; i < attrcnt; i++) { + col& c = ccol[i]; + if (i == 0) { + if (op->equal(c.aAttrName, (char*)&key, sizeof(key)) < 0) + return ndberror("equal key=%d", key); + } else { + } + } + if (con->execute(Commit) < 0) { + if (con->getNdbError().code != 626) + return ndberror("execute key=%d", key); + } else { + delcnt++; + } + ndb->closeTransaction(con); + } + con = 0; + op = 0; + ndbout << "deleted " << delcnt << endl; + + if (xverbose) + ndbout << "- insert" << endl; + for (key = 0; key < opercnt; key++) { + int off = makeOff(key); + if ((con = ndb->startTransaction()) == 0) + return ndberror("startTransaction key=%d", key); + if ((op = con->getNdbOperation(tab)) == 0) + return ndberror("getNdbOperation key=%d", key); + if (op->insertTuple() < 0) + return ndberror("insertTuple key=%d", key); + for (int i = 0; i < attrcnt; i++) { + col& c = ccol[i]; + if (i == 0) { + if (op->equal(c.aAttrName, (char*)&key, sizeof(key)) < 0) + return ndberror("equal key=%d", key); + } else { + memset(c.buf, 'A', c.bufsiz); + for (int j = 0; j < c.aArraySize; j++) + c.buf[j + off] = byteVal(key, i, j); + if (op->setValue(c.aAttrName, c.buf + off, c.aArraySize) < 0) + return ndberror("setValue key=%d col=%d", key, i); + } + } + if (con->execute(Commit) < 0) + return ndberror("execute key=%d", key); + ndb->closeTransaction(con); + } + con = 0; + op = 0; + ndbout << "inserted " << key << endl; + + if (xverbose) + ndbout << "- select" << endl; + for (key = 0; key < opercnt; key++) { + int off = makeOff(key); + if (xverbose) + ndbout << "-- key " << key << " off=" << off << endl; + if ((con = ndb->startTransaction()) == 0) + return ndberror("startTransaction key=%d", key); + if ((op = con->getNdbOperation(tab)) == 0) + return ndberror("getNdbOperation key=%d", key); + if (op->readTuple() < 0) + return ndberror("readTuple key=%d", key); + for (int i = 0; i < attrcnt; i++) { + col& c = ccol[i]; + if (i == 0) { + if (op->equal(c.aAttrName, (char*)&key, sizeof(key)) < 0) + return ndberror("equal key=%d", key); + } else { + if (xverbose) { + char tmp[20]; + if (useBuf) + sprintf(tmp, "0x%x", int(c.buf + off)); + else + strcpy(tmp, "ndbapi"); + ndbout << "--- column " << i << " addr=" << tmp << endl; + } + memset(c.buf, 'B', c.bufsiz); + if (useBuf) { + if (op->getValue(c.aAttrName, c.buf + off) < 0) + return ndberror("getValue key=%d col=%d", key, i); + } else { + if ((c.aRa = op->getValue(c.aAttrName)) == 0) + return ndberror("getValue key=%d col=%d", key, i); + } + } + } + if (con->execute(Commit) != 0) + return ndberror("execute key=%d", key); + for (int i = 0; i < attrcnt; i++) { + col& c = ccol[i]; + if (i == 0) { + } else if (useBuf) { + for (int j = 0; j < off; j++) { + if (c.buf[j] != 'B') { + return chkerror("mismatch before key=%d col=%d pos=%d ok=%02x bad=%02x", + key, i, j, 'B', c.buf[j]); + } + } + for (int j = 0; j < c.aArraySize; j++) { + if (c.buf[j + off] != byteVal(key, i, j)) { + return chkerror("mismatch key=%d col=%d pos=%d ok=%02x bad=%02x", + key, i, j, byteVal(key, i, j), c.buf[j]); + } + } + for (int j = c.aArraySize + off; j < c.bufsiz; j++) { + if (c.buf[j] != 'B') { + return chkerror("mismatch after key=%d col=%d pos=%d ok=%02x bad=%02x", + key, i, j, 'B', c.buf[j]); + } + } + } else { + char* buf = c.aRa->aRef(); + if (buf == 0) + return ndberror("null aRef key=%d col%d", key, i); + for (int j = 0; j < c.aArraySize; j++) { + if (buf[j] != byteVal(key, i, j)) { + return chkerror("mismatch key=%d col=%d pos=%d ok=%02x bad=%02x", + key, i, j, byteVal(key, i, j), buf[j]); + } + } + } + } + ndb->closeTransaction(con); + } + con = 0; + op = 0; + ndbout << "selected " << key << endl; + + if (xverbose) + ndbout << "- scan" << endl; + char found[MaxOper]; + for (int k = 0; k < opercnt; k++) + found[k] = 0; + for (key = 0; key < opercnt; key++) { + int off = makeOff(key); + if (xverbose) + ndbout << "-- key " << key << " off=" << off << endl; + int newkey = 0; + if ((con = ndb->startTransaction()) == 0) + return ndberror("startTransaction key=%d", key); + if ((op = con->getNdbOperation(tab)) == 0) + return ndberror("getNdbOperation key=%d", key); + if (op->openScanRead(1) < 0) + return ndberror("openScanRead key=%d", key); + { + col& c = ccol[0]; + if (op->load_const_u32(1, key) < 0) + return ndberror("load_const_u32"); + if (op->read_attr(c.aAttrName, 2) < 0) + return ndberror("read_attr"); + if (op->branch_eq(1, 2, 0) < 0) + return ndberror("branch_eq"); + if (op->interpret_exit_nok() < 0) + return ndberror("interpret_exit_nok"); + if (op->def_label(0) < 0) + return ndberror("def_label"); + if (op->interpret_exit_ok() < 0) + return ndberror("interpret_exit_ok"); + } + for (int i = 0; i < attrcnt; i++) { + col& c = ccol[i]; + if (i == 0) { + if (op->getValue(c.aAttrName, (char*)&newkey) < 0) + return ndberror("getValue key=%d col=%d", key, i); + } else { + if (xverbose) { + char tmp[20]; + if (useBuf) + sprintf(tmp, "0x%x", int(c.buf + off)); + else + strcpy(tmp, "ndbapi"); + ndbout << "--- column " << i << " addr=" << tmp << endl; + } + memset(c.buf, 'C', c.bufsiz); + if (useBuf) { + if (op->getValue(c.aAttrName, c.buf + off) < 0) + return ndberror("getValue key=%d col=%d", key, i); + } else { + if ((c.aRa = op->getValue(c.aAttrName)) == 0) + return ndberror("getValue key=%d col=%d", key, i); + } + } + } + if (con->executeScan() < 0) + return ndberror("executeScan key=%d", key); + int ret, cnt = 0; + while ((ret = con->nextScanResult()) == 0) { + if (key != newkey) + return ndberror("unexpected key=%d newkey=%d", key, newkey); + for (int i = 1; i < attrcnt; i++) { + col& c = ccol[i]; + if (useBuf) { + for (int j = 0; j < off; j++) { + if (c.buf[j] != 'C') { + return chkerror("mismatch before key=%d col=%d pos=%d ok=%02x bad=%02x", + key, i, j, 'C', c.buf[j]); + } + } + for (int j = 0; j < c.aArraySize; j++) { + if (c.buf[j + off] != byteVal(key, i, j)) { + return chkerror("mismatch key=%d col=%d pos=%d ok=%02x bad=%02x", + key, i, j, byteVal(key, i, j), c.buf[j]); + } + } + for (int j = c.aArraySize + off; j < c.bufsiz; j++) { + if (c.buf[j] != 'C') { + return chkerror("mismatch after key=%d col=%d pos=%d ok=%02x bad=%02x", + key, i, j, 'C', c.buf[j]); + } + } + } else { + char* buf = c.aRa->aRef(); + if (buf == 0) + return ndberror("null aRef key=%d col%d", key, i); + for (int j = 0; j < c.aArraySize; j++) { + if (buf[j] != byteVal(key, i, j)) { + return chkerror("mismatch key=%d col=%d pos=%d ok=%02x bad=%02x", + key, i, j, byteVal(key, i, j), buf[j]); + } + } + } + } + cnt++; + } + if (ret < 0) + return ndberror("nextScanResult key=%d", key); + if (cnt != 1) + return ndberror("scan key=%d found %d", key, cnt); + found[key] = 1; + ndb->closeTransaction(con); + } + con = 0; + op = 0; + for (int k = 0; k < opercnt; k++) + if (! found[k]) + return ndberror("key %d not found", k); + ndbout << "scanned " << key << endl; + + ndb = 0; + ndbout << "done" << endl; + return 0; +} + +NDB_COMMAND(testDataBuffers, "testDataBuffers", "testDataBuffers", "testDataBuffers", 65535) +{ + while (++argv, --argc > 0) { + char const* p = argv[0]; + if (*p++ != '-' || strlen(p) != 1) + goto wrongargs; + switch (*p) { + case 'a': + if (++argv, --argc > 0) { + attrcnt = atoi(argv[0]); + if (1 <= attrcnt && attrcnt <= MaxAttr) + break; + } + goto wrongargs; + case 'e': + existok = 1; + break; + case 'k': + kontinue = true; + break; + case 'l': + if (++argv, --argc > 0) { + loopcnt = atoi(argv[0]); + if (0 <= loopcnt) + break; + } + goto wrongargs; + case 'o': + if (++argv, --argc > 0) { + opercnt = atoi(argv[0]); + if (0 <= opercnt && opercnt <= MaxOper) + break; + } + goto wrongargs; + case 'r': + if (++argv, --argc > 0) { + randomizer = atoi(argv[0]); + if (1 <= randomizer) + break; + } + goto wrongargs; + case 's': + if (++argv, --argc > 0) { + sizelim = atoi(argv[0]); + if (1 <= sizelim && sizelim <= MaxSize) + break; + } + goto wrongargs; + case 'x': + xverbose = 1; + break; + default: + wrongargs: + printusage(); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + } + unsigned ok = true; + for (int i = 1; 0 == loopcnt || i <= loopcnt; i++) { + ndbout << "=== loop " << i << " ===" << endl; + for (int flag = 0; flag < (1<=32) buffers - * - * Verifies fixes to tickets 189 and 206. - * - * Options: see printusage() below. - * - * Creates tables TB00 to TB15 - */ - -#include - -#include -#include -#include -#include - -// limits -static int const MaxAttr = 64; -static int const MaxOper = 1000; -static int const MaxSize = 10000; -static int const MaxOff = 64; // max offset to add to data buffer -static int const MaxData = MaxSize + MaxOff + 100; - -// options -static int attrcnt = 25; -static int existok = 0; -static bool kontinue = false; -static int loopcnt = 1; -static int opercnt = 100; // also does this many scans -static int randomizer = 171317; -static int sizelim = 500; -static int xverbose = 0; - -static void printusage() { - ndbout - << "usage: testDataBuffers options [default/max]" - << endl - << "NOTE: too large combinations result in NDB error" - << endl - << "-a N number of attributes (including the key) [25/64]" - << endl - << "-e no error if table exists (assumed to have same structure)" - << endl - << "-k on error continue with next test case" - << endl - << "-l N number of loops to run, 0 means infinite [1]" - << endl - << "-o N number of operations (rows in each table) [100/1000]" - << endl - << "-r N source of randomness (big number (prime)) [171317]" - << endl - << "-s N array size limit (rounded up in some tests) [500/10000]" - << endl - << "-x extremely verbose" - << endl - << "Tables: TB00 .. TB15" - << endl - ; -} - -static Ndb* ndb = 0; -static NdbSchemaCon* tcon = 0; -static NdbSchemaOp* top = 0; -static NdbConnection* con = 0; -static NdbOperation* op = 0; - -static int -ndberror(char const* fmt, ...) -{ - va_list ap; - char buf[200]; - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - ndbout << buf << " --" << endl; - if (ndb) - ndbout << "ndb : " << ndb->getNdbError() << endl; - if (tcon) - ndbout << "tcon: " << tcon->getNdbError() << endl; - if (top) - ndbout << "top : " << top->getNdbError() << endl; - if (con) - ndbout << "con : " << con->getNdbError() << endl; - if (op) - ndbout << "op : " << op->getNdbError() << endl; - return -1; -} - -static int -chkerror(char const* fmt, ...) -{ - va_list ap; - char buf[200]; - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - ndbout << "*** check failed: " << buf << " ***" << endl; - return -1; -} - -// alignment of addresses and data sizes - -static bool isAligned(unsigned x) -{ - return ((x & 3) == 0); -} -static bool isAligned(char* p) -{ - return isAligned(unsigned(p)); -} -static unsigned toAligned(unsigned x) -{ - while (! isAligned(x)) - x++; - return x; -} -static char* toAligned(char* p) -{ - while (! isAligned(p)) - p++; - return p; -} - -// byte value for key k column i byte j -static int byteVal(int k, int i, int j) -{ - return '0' + (k + i + j) % 10; -} - -// tables - -static char tab[20] = ""; - -static struct col { - char aAttrName[20]; - AttrType aAttrType; - int aAttrSize; - int aArraySize; - KeyType aTupleKey; - bool nullable; - NdbRecAttr* aRa; - char* buf; - int bufsiz; - char data[MaxData]; -} ccol[MaxAttr]; - -static int key = 0; - -// independent test bits -static bool alignAddr; // align our buffer addresses to 4x -static bool alignSize; // align data sizes to 4x -static bool useBuf; // use our buffers for output -static bool noRandom; // do not randomize sizes and offsets -static int testbits = 4; - -static int -makeSize(int i) -{ - int n; - if (noRandom) - n = i; - else - n = i * randomizer; - n %= sizelim; - if (n <= 0) - n = 1; - if (alignSize) - n = toAligned(n); - return n; -} - -static int -makeOff(int k) -{ - int n; - if (alignAddr) - n = 0; - else if (noRandom) - n = k; - else - n = k * randomizer; - n %= MaxOff; - if (n < 0) - n = -n; - return n; -} - -static int -testcase(int flag) -{ - ndbout << "--- case " << flag << " ---" << endl; - sprintf(tab, "TB%02d", flag); - - alignAddr = ! (flag & 1); - ndbout << (alignAddr ? "align addresses" : "mis-align addresses") << endl; - alignSize = ! (flag & 2); - ndbout << (alignSize ? "align data sizes" : "mis-align data sizes") << endl; - useBuf = ! (flag & 4); - ndbout << (useBuf ? "use our buffers" : "use ndbapi buffers") << endl; - noRandom = ! (flag & 8); - ndbout << (noRandom ? "simple sizes" : "randomize sizes") << endl; - - int smax = 0, stot = 0; - if (xverbose) - ndbout << "- define table " << tab << endl; - for (int i = 0; i < attrcnt; i++) { - col& c = ccol[i]; - memset(&c, 0, sizeof(c)); - sprintf(c.aAttrName, "C%d", i); - if (i == 0) { - c.aAttrType = UnSigned; - c.aAttrSize = 32; - c.aArraySize = 1; - c.aTupleKey = TupleKey; - c.nullable = false; - } else { - c.aAttrType = String; - c.aAttrSize = 8; - c.aArraySize = makeSize(i); - if (smax < c.aArraySize) - smax = c.aArraySize; - stot += c.aArraySize; - c.aTupleKey = NoKey; - c.nullable = true; - if (xverbose) - ndbout << "-- column " << i << " size=" << c.aArraySize << endl; - } - c.buf = toAligned(c.data); - c.bufsiz = sizeof(c.data) - (c.buf - c.data); - } - ndbout << "tab=" << tab << " cols=" << attrcnt - << " size max=" << smax << " tot=" << stot << endl; - - ndb = new Ndb("TEST_DB"); - if (ndb->init() != 0) - return ndberror("init"); - if (ndb->waitUntilReady(30) < 0) - return ndberror("waitUntilReady"); - - if ((tcon = ndb->startSchemaTransaction()) == 0) - return ndberror("startSchemaTransaction"); - if ((top = tcon->getNdbSchemaOp()) == 0) - return ndberror("getNdbSchemaOp"); - if (top->createTable(tab) < 0) - return ndberror("createTable"); - for (int i = 0; i < attrcnt; i++) { - col& c = ccol[i]; - if (top->createAttribute( - c.aAttrName, - c.aTupleKey, - c.aAttrSize, - c.aArraySize, - c.aAttrType, - MMBased, - c.nullable - ) < 0) - return ndberror("createAttribute col=%d", i); - } - if (tcon->execute() < 0) { - if (! (tcon->getNdbError().code == 721 && existok)) - return ndberror("execute"); - ndbout << "using " << tab << endl; - } else { - ndbout << "created " << tab << endl; - } - top = 0; - tcon = 0; - - if (xverbose) - ndbout << "- delete" << endl; - int delcnt = 0; - for (key = 0; key < opercnt; key++) { - if ((con = ndb->startTransaction()) == 0) - return ndberror("startTransaction key=%d", key); - if ((op = con->getNdbOperation(tab)) == 0) - return ndberror("getNdbOperation key=%d", key); - if (op->deleteTuple() < 0) - return ndberror("deleteTuple key=%d", key); - for (int i = 0; i < attrcnt; i++) { - col& c = ccol[i]; - if (i == 0) { - if (op->equal(c.aAttrName, (char*)&key, sizeof(key)) < 0) - return ndberror("equal key=%d", key); - } else { - } - } - if (con->execute(Commit) < 0) { - if (con->getNdbError().code != 626) - return ndberror("execute key=%d", key); - } else { - delcnt++; - } - ndb->closeTransaction(con); - } - con = 0; - op = 0; - ndbout << "deleted " << delcnt << endl; - - if (xverbose) - ndbout << "- insert" << endl; - for (key = 0; key < opercnt; key++) { - int off = makeOff(key); - if ((con = ndb->startTransaction()) == 0) - return ndberror("startTransaction key=%d", key); - if ((op = con->getNdbOperation(tab)) == 0) - return ndberror("getNdbOperation key=%d", key); - if (op->insertTuple() < 0) - return ndberror("insertTuple key=%d", key); - for (int i = 0; i < attrcnt; i++) { - col& c = ccol[i]; - if (i == 0) { - if (op->equal(c.aAttrName, (char*)&key, sizeof(key)) < 0) - return ndberror("equal key=%d", key); - } else { - memset(c.buf, 'A', c.bufsiz); - for (int j = 0; j < c.aArraySize; j++) - c.buf[j + off] = byteVal(key, i, j); - if (op->setValue(c.aAttrName, c.buf + off, c.aArraySize) < 0) - return ndberror("setValue key=%d col=%d", key, i); - } - } - if (con->execute(Commit) < 0) - return ndberror("execute key=%d", key); - ndb->closeTransaction(con); - } - con = 0; - op = 0; - ndbout << "inserted " << key << endl; - - if (xverbose) - ndbout << "- select" << endl; - for (key = 0; key < opercnt; key++) { - int off = makeOff(key); - if (xverbose) - ndbout << "-- key " << key << " off=" << off << endl; - if ((con = ndb->startTransaction()) == 0) - return ndberror("startTransaction key=%d", key); - if ((op = con->getNdbOperation(tab)) == 0) - return ndberror("getNdbOperation key=%d", key); - if (op->readTuple() < 0) - return ndberror("readTuple key=%d", key); - for (int i = 0; i < attrcnt; i++) { - col& c = ccol[i]; - if (i == 0) { - if (op->equal(c.aAttrName, (char*)&key, sizeof(key)) < 0) - return ndberror("equal key=%d", key); - } else { - if (xverbose) { - char tmp[20]; - if (useBuf) - sprintf(tmp, "0x%x", int(c.buf + off)); - else - strcpy(tmp, "ndbapi"); - ndbout << "--- column " << i << " addr=" << tmp << endl; - } - memset(c.buf, 'B', c.bufsiz); - if (useBuf) { - if (op->getValue(c.aAttrName, c.buf + off) < 0) - return ndberror("getValue key=%d col=%d", key, i); - } else { - if ((c.aRa = op->getValue(c.aAttrName)) == 0) - return ndberror("getValue key=%d col=%d", key, i); - } - } - } - if (con->execute(Commit) != 0) - return ndberror("execute key=%d", key); - for (int i = 0; i < attrcnt; i++) { - col& c = ccol[i]; - if (i == 0) { - } else if (useBuf) { - for (int j = 0; j < off; j++) { - if (c.buf[j] != 'B') { - return chkerror("mismatch before key=%d col=%d pos=%d ok=%02x bad=%02x", - key, i, j, 'B', c.buf[j]); - } - } - for (int j = 0; j < c.aArraySize; j++) { - if (c.buf[j + off] != byteVal(key, i, j)) { - return chkerror("mismatch key=%d col=%d pos=%d ok=%02x bad=%02x", - key, i, j, byteVal(key, i, j), c.buf[j]); - } - } - for (int j = c.aArraySize + off; j < c.bufsiz; j++) { - if (c.buf[j] != 'B') { - return chkerror("mismatch after key=%d col=%d pos=%d ok=%02x bad=%02x", - key, i, j, 'B', c.buf[j]); - } - } - } else { - char* buf = c.aRa->aRef(); - if (buf == 0) - return ndberror("null aRef key=%d col%d", key, i); - for (int j = 0; j < c.aArraySize; j++) { - if (buf[j] != byteVal(key, i, j)) { - return chkerror("mismatch key=%d col=%d pos=%d ok=%02x bad=%02x", - key, i, j, byteVal(key, i, j), buf[j]); - } - } - } - } - ndb->closeTransaction(con); - } - con = 0; - op = 0; - ndbout << "selected " << key << endl; - - if (xverbose) - ndbout << "- scan" << endl; - char found[MaxOper]; - for (int k = 0; k < opercnt; k++) - found[k] = 0; - for (key = 0; key < opercnt; key++) { - int off = makeOff(key); - if (xverbose) - ndbout << "-- key " << key << " off=" << off << endl; - int newkey = 0; - if ((con = ndb->startTransaction()) == 0) - return ndberror("startTransaction key=%d", key); - if ((op = con->getNdbOperation(tab)) == 0) - return ndberror("getNdbOperation key=%d", key); - if (op->openScanRead(1) < 0) - return ndberror("openScanRead key=%d", key); - { - col& c = ccol[0]; - if (op->load_const_u32(1, key) < 0) - return ndberror("load_const_u32"); - if (op->read_attr(c.aAttrName, 2) < 0) - return ndberror("read_attr"); - if (op->branch_eq(1, 2, 0) < 0) - return ndberror("branch_eq"); - if (op->interpret_exit_nok() < 0) - return ndberror("interpret_exit_nok"); - if (op->def_label(0) < 0) - return ndberror("def_label"); - if (op->interpret_exit_ok() < 0) - return ndberror("interpret_exit_ok"); - } - for (int i = 0; i < attrcnt; i++) { - col& c = ccol[i]; - if (i == 0) { - if (op->getValue(c.aAttrName, (char*)&newkey) < 0) - return ndberror("getValue key=%d col=%d", key, i); - } else { - if (xverbose) { - char tmp[20]; - if (useBuf) - sprintf(tmp, "0x%x", int(c.buf + off)); - else - strcpy(tmp, "ndbapi"); - ndbout << "--- column " << i << " addr=" << tmp << endl; - } - memset(c.buf, 'C', c.bufsiz); - if (useBuf) { - if (op->getValue(c.aAttrName, c.buf + off) < 0) - return ndberror("getValue key=%d col=%d", key, i); - } else { - if ((c.aRa = op->getValue(c.aAttrName)) == 0) - return ndberror("getValue key=%d col=%d", key, i); - } - } - } - if (con->executeScan() < 0) - return ndberror("executeScan key=%d", key); - int ret, cnt = 0; - while ((ret = con->nextScanResult()) == 0) { - if (key != newkey) - return ndberror("unexpected key=%d newkey=%d", key, newkey); - for (int i = 1; i < attrcnt; i++) { - col& c = ccol[i]; - if (useBuf) { - for (int j = 0; j < off; j++) { - if (c.buf[j] != 'C') { - return chkerror("mismatch before key=%d col=%d pos=%d ok=%02x bad=%02x", - key, i, j, 'C', c.buf[j]); - } - } - for (int j = 0; j < c.aArraySize; j++) { - if (c.buf[j + off] != byteVal(key, i, j)) { - return chkerror("mismatch key=%d col=%d pos=%d ok=%02x bad=%02x", - key, i, j, byteVal(key, i, j), c.buf[j]); - } - } - for (int j = c.aArraySize + off; j < c.bufsiz; j++) { - if (c.buf[j] != 'C') { - return chkerror("mismatch after key=%d col=%d pos=%d ok=%02x bad=%02x", - key, i, j, 'C', c.buf[j]); - } - } - } else { - char* buf = c.aRa->aRef(); - if (buf == 0) - return ndberror("null aRef key=%d col%d", key, i); - for (int j = 0; j < c.aArraySize; j++) { - if (buf[j] != byteVal(key, i, j)) { - return chkerror("mismatch key=%d col=%d pos=%d ok=%02x bad=%02x", - key, i, j, byteVal(key, i, j), buf[j]); - } - } - } - } - cnt++; - } - if (ret < 0) - return ndberror("nextScanResult key=%d", key); - if (cnt != 1) - return ndberror("scan key=%d found %d", key, cnt); - found[key] = 1; - ndb->closeTransaction(con); - } - con = 0; - op = 0; - for (int k = 0; k < opercnt; k++) - if (! found[k]) - return ndberror("key %d not found", k); - ndbout << "scanned " << key << endl; - - ndb = 0; - ndbout << "done" << endl; - return 0; -} - -NDB_COMMAND(testDataBuffers, "testDataBuffers", "testDataBuffers", "testDataBuffers", 65535) -{ - while (++argv, --argc > 0) { - char const* p = argv[0]; - if (*p++ != '-' || strlen(p) != 1) - goto wrongargs; - switch (*p) { - case 'a': - if (++argv, --argc > 0) { - attrcnt = atoi(argv[0]); - if (1 <= attrcnt && attrcnt <= MaxAttr) - break; - } - goto wrongargs; - case 'e': - existok = 1; - break; - case 'k': - kontinue = true; - break; - case 'l': - if (++argv, --argc > 0) { - loopcnt = atoi(argv[0]); - if (0 <= loopcnt) - break; - } - goto wrongargs; - case 'o': - if (++argv, --argc > 0) { - opercnt = atoi(argv[0]); - if (0 <= opercnt && opercnt <= MaxOper) - break; - } - goto wrongargs; - case 'r': - if (++argv, --argc > 0) { - randomizer = atoi(argv[0]); - if (1 <= randomizer) - break; - } - goto wrongargs; - case 's': - if (++argv, --argc > 0) { - sizelim = atoi(argv[0]); - if (1 <= sizelim && sizelim <= MaxSize) - break; - } - goto wrongargs; - case 'x': - xverbose = 1; - break; - default: - wrongargs: - printusage(); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - } - unsigned ok = true; - for (int i = 1; 0 == loopcnt || i <= loopcnt; i++) { - ndbout << "=== loop " << i << " ===" << endl; - for (int flag = 0; flag < (1< +#include +#include +#include +#include +#include +#include +#include <../../include/kernel/ndb_limits.h> +#include +#include + +#define CHECK(b) if (!(b)) { \ + g_err << "ERR: "<< step->getName() \ + << " failed on line " << __LINE__ << endl; \ + result = NDBT_FAILED; \ + break; } + +#define CHECK2(b, c) if (!(b)) { \ + g_err << "ERR: "<< step->getName() \ + << " failed on line " << __LINE__ << ": " << c << endl; \ + result = NDBT_FAILED; \ + goto end; } + +int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + int records = ctx->getNumRecords(); + HugoTransactions hugoTrans(*ctx->getTab()); + if (hugoTrans.loadTable(pNdb, records) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + + +int runCreateInvalidTables(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; + + char failTabName[256]; + + for (int i = 0; i < 10; i++){ + snprintf(failTabName, 256, "F%d", i); + + const NdbDictionary::Table* pFailTab = NDBT_Tables::getTable(failTabName); + if (pFailTab != NULL){ + ndbout << "|- " << failTabName << endl; + + // Try to create table in db + if (pFailTab->createTableInDb(pNdb) == 0){ + ndbout << failTabName << " created, this was not expected"<< endl; + result = NDBT_FAILED; + } + + // Verify that table is not in db + const NdbDictionary::Table* pTab2 = + NDBT_Table::discoverTableFromDb(pNdb, failTabName) ; + if (pTab2 != NULL){ + ndbout << failTabName << " was found in DB, this was not expected"<< endl; + result = NDBT_FAILED; + if (pFailTab->equal(*pTab2) == true){ + ndbout << "It was equal" << endl; + } else { + ndbout << "It was not equal" << endl; + } + int records = 1000; + HugoTransactions hugoTrans(*pTab2); + if (hugoTrans.loadTable(pNdb, records) != 0){ + ndbout << "It can NOT be loaded" << endl; + } else{ + ndbout << "It can be loaded" << endl; + + UtilTransactions utilTrans(*pTab2); + if (utilTrans.clearTable(pNdb, records, 64) != 0){ + ndbout << "It can NOT be cleared" << endl; + } else{ + ndbout << "It can be cleared" << endl; + } + } + + if (pNdb->getDictionary()->dropTable(pTab2->getName()) == -1){ + ndbout << "It can NOT be dropped" << endl; + } else { + ndbout << "It can be dropped" << endl; + } + } + } + } + return result; +} + +int runCreateTheTable(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + const NdbDictionary::Table* pTab = ctx->getTab(); + + // Try to create table in db + if (pTab->createTableInDb(pNdb) != 0){ + return NDBT_FAILED; + } + + // Verify that table is in db + const NdbDictionary::Table* pTab2 = + NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); + if (pTab2 == NULL){ + ndbout << pTab->getName() << " was not found in DB"<< endl; + return NDBT_FAILED; + } + ctx->setTab(pTab2); + + return NDBT_OK; +} + +int runCreateTableWhenDbIsFull(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; + const char* tabName = "TRANSACTION"; //Use a util table + + const NdbDictionary::Table* pTab = NDBT_Tables::getTable(tabName); + if (pTab != NULL){ + ndbout << "|- " << tabName << endl; + + // Verify that table is not in db + if (NDBT_Table::discoverTableFromDb(pNdb, tabName) != NULL){ + ndbout << tabName << " was found in DB"<< endl; + return NDBT_FAILED; + } + + // Try to create table in db + if (pTab->createTableInDb(pNdb) == 0){ + result = NDBT_FAILED; + } + + // Verify that table is in db + if (NDBT_Table::discoverTableFromDb(pNdb, tabName) != NULL){ + ndbout << tabName << " was found in DB"<< endl; + result = NDBT_FAILED; + } + } + + return result; +} + +int runDropTableWhenDbIsFull(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; + const char* tabName = "TRANSACTION"; //Use a util table + + const NdbDictionary::Table* pTab = NDBT_Table::discoverTableFromDb(pNdb, tabName); + if (pTab != NULL){ + ndbout << "|- TRANSACTION" << endl; + + // Try to drop table in db + if (pNdb->getDictionary()->dropTable(pTab->getName()) == -1){ + result = NDBT_FAILED; + } + + // Verify that table is not in db + if (NDBT_Table::discoverTableFromDb(pNdb, tabName) != NULL){ + ndbout << tabName << " was found in DB"<< endl; + result = NDBT_FAILED; + } + } + + return result; + +} + + +int runCreateAndDrop(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + int loops = ctx->getNumLoops(); + int i = 0; + + const NdbDictionary::Table* pTab = ctx->getTab(); + ndbout << "|- " << pTab->getName() << endl; + + while (i < loops){ + + ndbout << i << ": "; + // Try to create table in db + if (pTab->createTableInDb(pNdb) != 0){ + return NDBT_FAILED; + } + + // Verify that table is in db + const NdbDictionary::Table* pTab2 = + NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); + if (pTab2 == NULL){ + ndbout << pTab->getName() << " was not found in DB"<< endl; + return NDBT_FAILED; + } + + if (pNdb->getDictionary()->dropTable(pTab2->getName())){ + ndbout << "Failed to drop "<getName()<<" in db" << endl; + return NDBT_FAILED; + } + + // Verify that table is not in db + const NdbDictionary::Table* pTab3 = + NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); + if (pTab3 != NULL){ + ndbout << pTab3->getName() << " was found in DB"<< endl; + return NDBT_FAILED; + } + i++; + } + + return NDBT_OK; +} + +int runCreateAndDropWithData(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + int i = 0; + + NdbRestarter restarter; + int val = DumpStateOrd::DihMinTimeBetweenLCP; + if(restarter.dumpStateAllNodes(&val, 1) != 0){ + int result; + do { CHECK(0); } while (0); + g_err << "Unable to change timebetween LCP" << endl; + return NDBT_FAILED; + } + + const NdbDictionary::Table* pTab = ctx->getTab(); + ndbout << "|- " << pTab->getName() << endl; + + while (i < loops){ + ndbout << i << ": "; + // Try to create table in db + if (pTab->createTableInDb(pNdb) != 0){ + return NDBT_FAILED; + } + + // Verify that table is in db + const NdbDictionary::Table* pTab2 = + NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); + if (pTab2 == NULL){ + ndbout << pTab->getName() << " was not found in DB"<< endl; + return NDBT_FAILED; + } + + HugoTransactions hugoTrans(*pTab2); + if (hugoTrans.loadTable(pNdb, records) != 0){ + return NDBT_FAILED; + } + + int count = 0; + UtilTransactions utilTrans(*pTab2); + if (utilTrans.selectCount(pNdb, 64, &count) != 0){ + return NDBT_FAILED; + } + if (count != records){ + ndbout << count <<" != "<getDictionary()->dropTable(pTab2->getName()) != 0){ + ndbout << "Failed to drop "<getName()<<" in db" << endl; + return NDBT_FAILED; + } + + // Verify that table is not in db + const NdbDictionary::Table* pTab3 = + NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); + if (pTab3 != NULL){ + ndbout << pTab3->getName() << " was found in DB"<< endl; + return NDBT_FAILED; + } + + + i++; + } + + return NDBT_OK; +} + +int runFillTable(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + HugoTransactions hugoTrans(*ctx->getTab()); + if (hugoTrans.fillTable(pNdb) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + int records = ctx->getNumRecords(); + + UtilTransactions utilTrans(*ctx->getTab()); + if (utilTrans.clearTable(pNdb, records) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runCreateAndDropDuring(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int loops = ctx->getNumLoops(); + int i = 0; + + const NdbDictionary::Table* pTab = ctx->getTab(); + ndbout << "|- " << pTab->getName() << endl; + + while (i < loops && result == NDBT_OK){ + ndbout << i << ": " << endl; + // Try to create table in db + + Ndb* pNdb = GETNDB(step); + g_debug << "Creating table" << endl; + + if (pTab->createTableInDb(pNdb) != 0){ + g_err << "createTableInDb failed" << endl; + result = NDBT_FAILED; + continue; + } + + g_debug << "Verifying creation of table" << endl; + + // Verify that table is in db + const NdbDictionary::Table* pTab2 = + NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); + if (pTab2 == NULL){ + g_err << pTab->getName() << " was not found in DB"<< endl; + result = NDBT_FAILED; + continue; + } + + NdbSleep_MilliSleep(3000); + + g_debug << "Dropping table" << endl; + + + if (pNdb->getDictionary()->dropTable(pTab2->getName()) != 0){ + g_err << "Failed to drop "<getName()<<" in db" << endl; + result = NDBT_FAILED; + continue; + } + + g_debug << "Verifying dropping of table" << endl; + + // Verify that table is not in db + const NdbDictionary::Table* pTab3 = + NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); + if (pTab3 != NULL){ + g_err << pTab3->getName() << " was found in DB"<< endl; + result = NDBT_FAILED; + continue; + } + i++; + } + ctx->stopTest(); + + return result; +} + + +int runUseTableUntilStopped(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + + const NdbDictionary::Table* pTab = ctx->getTab(); + + while (ctx->isTestStopped() == false) { + // g_info << i++ << ": "; + + + // Delete and recreate Ndb object + // Otherwise you always get Invalid Schema Version + // It would be a nice feature to remove this two lines + //step->tearDown(); + //step->setUp(); + + Ndb* pNdb = GETNDB(step); + + const NdbDictionary::Table* pTab2 = + NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); + if (pTab2 == NULL) + continue; + + int res; + HugoTransactions hugoTrans(*pTab2); + if ((res = hugoTrans.loadTable(pNdb, records)) != 0){ + NdbError err = pNdb->getNdbError(res); + if(err.classification == NdbError::SchemaError){ + pNdb->getDictionary()->invalidateTable(pTab->getName()); + } + continue; + } + + UtilTransactions utilTrans(*pTab2); + if ((res = utilTrans.clearTable(pNdb, records)) != 0){ + NdbError err = pNdb->getNdbError(res); + if(err.classification == NdbError::SchemaError){ + pNdb->getDictionary()->invalidateTable(pTab->getName()); + } + continue; + } + } + g_info << endl; + return NDBT_OK; +} + + +int runCreateMaxTables(NDBT_Context* ctx, NDBT_Step* step){ + int failures = 0; + char tabName[256]; + int numTables = ctx->getProperty("tables", 1000); + Ndb* pNdb = GETNDB(step); + + for (int i = 0; i < numTables && failures < 5; i++){ + snprintf(tabName, 256, "MAXTAB%d", i); + + if (pNdb->waitUntilReady(30) != 0){ + // Db is not ready, return with failure + return NDBT_FAILED; + } + + const NdbDictionary::Table* pTab = ctx->getTab(); + ndbout << "|- " << tabName << endl; + + // Set new name for T1 + NdbDictionary::Table newTab(* pTab); + newTab.setName(tabName); + + // Try to create table in db + if (newTab.createTableInDb(pNdb) != 0){ + ndbout << tabName << " coult not be created"<< endl; + failures++; + continue; + } + + // Verify that table exists in db + const NdbDictionary::Table* pTab3 = + NDBT_Table::discoverTableFromDb(pNdb, tabName) ; + if (pTab3 == NULL){ + ndbout << tabName << " was not found in DB"<< endl; + failures++; + continue; + } + + if (pTab->equal(*pTab3) == false){ + ndbout << "It was not equal" << endl; + failures++; + } + + int records = 1000; + HugoTransactions hugoTrans(*pTab3); + if (hugoTrans.loadTable(pNdb, records) != 0){ + ndbout << "It can NOT be loaded" << endl; + } else{ + ndbout << "It can be loaded" << endl; + + UtilTransactions utilTrans(*pTab3); + if (utilTrans.clearTable(pNdb, records, 64) != 0){ + ndbout << "It can NOT be cleared" << endl; + } else{ + ndbout << "It can be cleared" << endl; + } + } + + } + if (pNdb->waitUntilReady(30) != 0){ + // Db is not ready, return with failure + return NDBT_FAILED; + } + // HURRAAA! + return NDBT_OK; +} + +int runDropMaxTables(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + char tabName[256]; + int numTables = ctx->getProperty("tables", 1000); + Ndb* pNdb = GETNDB(step); + + for (int i = 0; i < numTables; i++){ + snprintf(tabName, 256, "MAXTAB%d", i); + + if (pNdb->waitUntilReady(30) != 0){ + // Db is not ready, return with failure + return NDBT_FAILED; + } + + // Verify that table exists in db + const NdbDictionary::Table* pTab3 = + NDBT_Table::discoverTableFromDb(pNdb, tabName) ; + if (pTab3 == NULL){ + ndbout << tabName << " was not found in DB"<< endl; + continue; + } + + + // Try to drop table in db + if (pNdb->getDictionary()->dropTable(pTab3->getName()) != 0){ + ndbout << tabName << " coult not be dropped"<< endl; + result = NDBT_FAILED; + } + + } + return result; +} + +int runTestFragmentTypes(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + int fragTtype = ctx->getProperty("FragmentType"); + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; + NdbRestarter restarter; + + // enum FragmentType { + // Unknown = 0, + // Single = 1, ///< Only one fragment + // All = 2, ///< Default value. One fragment per node group + // AllLarge = 3 ///< Sixten fragments per node group. + // }; + + if (pNdb->waitUntilReady(30) != 0){ + // Db is not ready, return with failure + return NDBT_FAILED; + } + + const NdbDictionary::Table* pTab = ctx->getTab(); + + NdbDictionary::Table newTab(* pTab); + // Set fragment type for table + newTab.setFragmentType((NdbDictionary::Object::FragmentType)fragTtype); + + // Try to create table in db + if (newTab.createTableInDb(pNdb) != 0){ + ndbout << newTab.getName() << " could not be created" + << ", fragmentType = "<getName()) ; + if (pTab3 == NULL){ + ndbout << pTab->getName() << " was not found in DB"<< endl; + return NDBT_FAILED; + + } + + if (pTab3->getFragmentType() != fragTtype){ + ndbout << pTab->getName() << " fragmentType error "<< endl; + result = NDBT_FAILED; + goto drop_the_tab; + } + + if (newTab.equal(*pTab3) == false){ + ndbout << "It was not equal" << endl; + result = NDBT_FAILED; + goto drop_the_tab; + } + + do { + + HugoTransactions hugoTrans(*pTab3); + UtilTransactions utilTrans(*pTab3); + int count; + CHECK(hugoTrans.loadTable(pNdb, records) == 0); + CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == records); + CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); + CHECK(hugoTrans.scanUpdateRecords(pNdb, records) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == (records/2)); + + // restart all + ndbout << "Restarting cluster" << endl; + CHECK(restarter.restartAll() == 0); + int timeout = 120; + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(pNdb->waitUntilReady(timeout) == 0); + + // Verify content + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == (records/2)); + + CHECK(utilTrans.clearTable(pNdb, records) == 0); + CHECK(hugoTrans.loadTable(pNdb, records) == 0); + CHECK(utilTrans.clearTable(pNdb, records) == 0); + CHECK(hugoTrans.loadTable(pNdb, records) == 0); + CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); + CHECK(utilTrans.clearTable(pNdb, records, 64) == 0); + + } while(false); + + drop_the_tab: + + // Try to drop table in db + if (pNdb->getDictionary()->dropTable(pTab3->getName()) != 0){ + ndbout << pTab3->getName() << " could not be dropped"<< endl; + result = NDBT_FAILED; + } + + return result; +} + + +int runTestTemporaryTables(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + Ndb* pNdb = GETNDB(step); + int i = 0; + NdbRestarter restarter; + + const NdbDictionary::Table* pTab = ctx->getTab(); + ndbout << "|- " << pTab->getName() << endl; + + NdbDictionary::Table newTab(* pTab); + // Set table as temporary + newTab.setStoredTable(false); + + // Try to create table in db + if (newTab.createTableInDb(pNdb) != 0){ + return NDBT_FAILED; + } + + // Verify that table is in db + const NdbDictionary::Table* pTab2 = + NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); + if (pTab2 == NULL){ + ndbout << pTab->getName() << " was not found in DB"<< endl; + return NDBT_FAILED; + } + + if (pTab2->getStoredTable() != false){ + ndbout << pTab->getName() << " was not temporary in DB"<< endl; + result = NDBT_FAILED; + goto drop_the_tab; + } + + + while (i < loops && result == NDBT_OK){ + ndbout << i << ": "; + + HugoTransactions hugoTrans(*pTab2); + CHECK(hugoTrans.loadTable(pNdb, records) == 0); + + int count = 0; + UtilTransactions utilTrans(*pTab2); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == records); + + // restart all + ndbout << "Restarting cluster" << endl; + CHECK(restarter.restartAll() == 0); + int timeout = 120; + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(pNdb->waitUntilReady(timeout) == 0); + + ndbout << "Verifying records..." << endl; + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == 0); + + i++; + } + + drop_the_tab: + + + if (pNdb->getDictionary()->dropTable(pTab2->getName()) != 0){ + ndbout << "Failed to drop "<getName()<<" in db" << endl; + result = NDBT_FAILED; + } + + // Verify that table is not in db + const NdbDictionary::Table* pTab3 = + NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); + if (pTab3 != NULL){ + ndbout << pTab3->getName() << " was found in DB"<< endl; + result = NDBT_FAILED; + } + + return result; +} + +int runPkSizes(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + char tabName[256]; + int minPkSize = 1; + ndbout << "minPkSize=" < max) + records = max; + ndbout << "records =" << records << endl; + + if (pNdb->waitUntilReady(30) != 0){ + // Db is not ready, return with failure + return NDBT_FAILED; + } + + ndbout << "|- " << tabName << endl; + + if (NDBT_Tables::createTable(pNdb, tabName) != 0){ + ndbout << tabName << " could not be created"<< endl; + return NDBT_FAILED; + } + + // Verify that table exists in db + const NdbDictionary::Table* pTab3 = + NDBT_Table::discoverTableFromDb(pNdb, tabName) ; + if (pTab3 == NULL){ + g_err << tabName << " was not found in DB"<< endl; + return NDBT_FAILED; + } + + // ndbout << *pTab3 << endl; + + if (pTab3->equal(*NDBT_Tables::getTable(tabName)) == false){ + g_err << "It was not equal" << endl; + return NDBT_FAILED; + } + + do { + // Do it all + HugoTransactions hugoTrans(*pTab3); + UtilTransactions utilTrans(*pTab3); + int count; + CHECK(hugoTrans.loadTable(pNdb, records) == 0); + CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == records); + CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); + CHECK(hugoTrans.scanUpdateRecords(pNdb, records) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == (records/2)); + CHECK(utilTrans.clearTable(pNdb, records) == 0); + +#if 0 + // Fill table + CHECK(hugoTrans.fillTable(pNdb) == 0); + CHECK(utilTrans.clearTable2(pNdb, records) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == 0); +#endif + } while(false); + + // Drop table + if (pNdb->getDictionary()->dropTable(pTab3->getName()) != 0){ + ndbout << "Failed to drop "<getName()<<" in db" << endl; + return NDBT_FAILED; + } + } + return result; +} + +int runStoreFrm(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + const NdbDictionary::Table* pTab = ctx->getTab(); + int result = NDBT_OK; + int loops = ctx->getNumLoops(); + + for (int l = 0; l < loops && result == NDBT_OK ; l++){ + + Uint32 dataLen = (Uint32)myRandom48(MAX_FRM_DATA_SIZE); + // size_t dataLen = 10; + unsigned char data[MAX_FRM_DATA_SIZE]; + + char start = l + 248; + for(Uint32 i = 0; i < dataLen; i++){ + data[i] = start; + start++; + } +#if 0 + ndbout << "dataLen="<getName()); + if (pTab2 == NULL){ + g_err << pTab->getName() << " was not found in DB"<< endl; + result = NDBT_FAILED; + continue; + } + + const void* pData2 = pTab2->getFrmData(); + Uint32 resultLen = pTab2->getFrmLength(); + if (dataLen != resultLen){ + g_err << "Length of data failure" << endl + << " expected = " << dataLen << endl + << " got = " << resultLen << endl; + result = NDBT_FAILED; + } + + // Verfiy the frm data + if (memcmp(pData, pData2, resultLen) != 0){ + g_err << "Wrong data recieved" << endl; + for (size_t i = 0; i < dataLen; i++){ + unsigned char c = ((unsigned char*)pData2)[i]; + g_err << hex << c << ", "; + } + g_err << endl; + result = NDBT_FAILED; + } + + if (pNdb->getDictionary()->dropTable(pTab2->getName()) != 0){ + g_err << "It can NOT be dropped" << endl; + result = NDBT_FAILED; + } + } + + return result; +} + +int runStoreFrmError(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + const NdbDictionary::Table* pTab = ctx->getTab(); + int result = NDBT_OK; + int loops = ctx->getNumLoops(); + + for (int l = 0; l < loops && result == NDBT_OK ; l++){ + + const Uint32 dataLen = MAX_FRM_DATA_SIZE + 10; + unsigned char data[dataLen]; + + char start = l + 248; + for(Uint32 i = 0; i < dataLen; i++){ + data[i] = start; + start++; + } +#if 0 + ndbout << "dataLen="<getName()); + if (pTab2 != NULL){ + g_err << pTab->getName() << " was found in DB"<< endl; + result = NDBT_FAILED; + if (pNdb->getDictionary()->dropTable(pTab2->getName()) != 0){ + g_err << "It can NOT be dropped" << endl; + result = NDBT_FAILED; + } + + continue; + } + + } + + return result; +} + +int verifyTablesAreEqual(const NdbDictionary::Table* pTab, const NdbDictionary::Table* pTab2){ + // Verify that getPrimaryKey only returned true for primary keys + for (int i = 0; i < pTab2->getNoOfColumns(); i++){ + const NdbDictionary::Column* col = pTab->getColumn(i); + const NdbDictionary::Column* col2 = pTab2->getColumn(i); + if (col->getPrimaryKey() != col2->getPrimaryKey()){ + g_err << "col->getPrimaryKey() != col2->getPrimaryKey()" << endl; + return NDBT_FAILED; + } + } + + if (!pTab->equal(*pTab2)){ + g_err << "equal failed" << endl; + g_info << *pTab; + g_info << *pTab2; + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runGetPrimaryKey(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + const NdbDictionary::Table* pTab = ctx->getTab(); + ndbout << "|- " << pTab->getName() << endl; + g_info << *pTab; + // Try to create table in db + if (pTab->createTableInDb(pNdb) != 0){ + return NDBT_FAILED; + } + + const NdbDictionary::Table* pTab2 = + NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); + if (pTab2 == NULL){ + ndbout << pTab->getName() << " was not found in DB"<< endl; + return NDBT_FAILED; + } + + int result = NDBT_OK; + if (verifyTablesAreEqual(pTab, pTab2) != NDBT_OK) + result = NDBT_FAILED; + + +#if 0 + // Create an index on the table and see what + // the function returns now + char name[200]; + sprintf(name, "%s_X007", pTab->getName()); + NDBT_Index* pInd = new NDBT_Index(name); + pInd->setTable(pTab->getName()); + pInd->setType(NdbDictionary::Index::UniqueHashIndex); + // pInd->setLogging(false); + for (int i = 0; i < 2; i++){ + const NDBT_Attribute* pAttr = pTab->getAttribute(i); + pInd->addAttribute(*pAttr); + } + g_info << "Create index:" << endl << *pInd; + if (pInd->createIndexInDb(pNdb, false) != 0){ + result = NDBT_FAILED; + } + delete pInd; + + const NdbDictionary::Table* pTab3 = + NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); + if (pTab3 == NULL){ + ndbout << pTab->getName() << " was not found in DB"<< endl; + return NDBT_FAILED; + } + + if (verifyTablesAreEqual(pTab, pTab3) != NDBT_OK) + result = NDBT_FAILED; + if (verifyTablesAreEqual(pTab2, pTab3) != NDBT_OK) + result = NDBT_FAILED; +#endif + +#if 0 + if (pTab2->getDictionary()->dropTable(pNdb) != 0){ + ndbout << "Failed to drop "<getName()<<" in db" << endl; + return NDBT_FAILED; + } + + // Verify that table is not in db + const NdbDictionary::Table* pTab4 = + NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); + if (pTab4 != NULL){ + ndbout << pTab4->getName() << " was found in DB"<< endl; + return NDBT_FAILED; + } +#endif + + return result; +} + +int +NF_codes[] = { + 14000 + ,14001 + //,14002 +}; + +int +runNF1(NDBT_Context* ctx, NDBT_Step* step){ + NdbRestarter restarter; + if(restarter.getNumDbNodes() < 2) + return NDBT_OK; + + myRandom48Init(NdbTick_CurrentMillisecond()); + + Ndb* pNdb = GETNDB(step); + const NdbDictionary::Table* pTab = ctx->getTab(); + + NdbDictionary::Dictionary* dict = pNdb->getDictionary(); + dict->dropTable(pTab->getName()); + + int result = NDBT_OK; + + /** + * Need to run LCP at high rate otherwise + * packed replicas become "to many" + */ + int val = DumpStateOrd::DihMinTimeBetweenLCP; + if(restarter.dumpStateAllNodes(&val, 1) != 0){ + do { CHECK(0); } while(0); + g_err << "Failed to set LCP to min value" << endl; + return NDBT_FAILED; + } + + const int loops = ctx->getNumLoops(); + for (int l = 0; l < loops && result == NDBT_OK ; l++){ + const int sz = sizeof(NF_codes)/sizeof(NF_codes[0]); + for(int i = 0; icreateTable(* pTab) == 0, + "failed to create table"); + + CHECK2(restarter.waitNodesNoStart(&nodeId, 1) == 0, + "waitNodesNoStart failed"); + + if(myRandom48(100) > 50){ + CHECK2(restarter.startNodes(&nodeId, 1) == 0, + "failed to start node"); + + CHECK2(restarter.waitClusterStarted() == 0, + "waitClusterStarted failed"); + + CHECK2(dict->dropTable(pTab->getName()) == 0, + "drop table failed"); + } else { + CHECK2(dict->dropTable(pTab->getName()) == 0, + "drop table failed"); + + CHECK2(restarter.startNodes(&nodeId, 1) == 0, + "failed to start node"); + + CHECK2(restarter.waitClusterStarted() == 0, + "waitClusterStarted failed"); + } + + CHECK2(restarter.dumpStateOneNode(nodeId, &val, 1) == 0, + "Failed to set LCP to min value"); + } + } + end: + dict->dropTable(pTab->getName()); + + return result; +} + +#define APIERROR(error) \ + { g_err << "Error in " << __FILE__ << ", line:" << __LINE__ << ", code:" \ + << error.code << ", msg: " << error.message << "." << endl; \ + } + +int +runCreateAutoincrementTable(NDBT_Context* ctx, NDBT_Step* step){ + + Uint32 startvalues[5] = {256-2, 0, 256*256-2, ~0, 256*256*256-2}; + + int ret = NDBT_OK; + + for (int jj = 0; jj < 5 && ret == NDBT_OK; jj++) { + char tabname[] = "AUTOINCTAB"; + Uint32 startvalue = startvalues[jj]; + + NdbDictionary::Table myTable; + NdbDictionary::Column myColumn; + + Ndb* myNdb = GETNDB(step); + NdbDictionary::Dictionary* myDict = myNdb->getDictionary(); + + + if (myDict->getTable(tabname) != NULL) { + g_err << "NDB already has example table: " << tabname << endl; + APIERROR(myNdb->getNdbError()); + return NDBT_FAILED; + } + + myTable.setName(tabname); + + myColumn.setName("ATTR1"); + myColumn.setPrimaryKey(true); + myColumn.setType(NdbDictionary::Column::Unsigned); + myColumn.setLength(1); + myColumn.setNullable(false); + myColumn.setAutoIncrement(true); + if (startvalue != ~0) // check that default value starts with 1 + myColumn.setAutoIncrementInitialValue(startvalue); + myTable.addColumn(myColumn); + + if (myDict->createTable(myTable) == -1) { + g_err << "Failed to create table " << tabname << endl; + APIERROR(myNdb->getNdbError()); + return NDBT_FAILED; + } + + + if (startvalue == ~0) // check that default value starts with 1 + startvalue = 1; + + for (int i = 0; i < 16; i++) { + + Uint64 value = myNdb->getAutoIncrementValue(tabname, 1); + + if (value != (startvalue+i)) { + g_err << "value = " << value << " expected " << startvalue+i << endl;; + APIERROR(myNdb->getNdbError()); + // ret = NDBT_FAILED; + // break; + } + } + + if (myDict->dropTable(tabname) == -1) { + g_err << "Failed to drop table " << tabname << endl; + APIERROR(myNdb->getNdbError()); + ret = NDBT_FAILED; + } + } + + return ret; +} + +int +runTableRename(NDBT_Context* ctx, NDBT_Step* step){ + + int result = NDBT_OK; + + Ndb* pNdb = GETNDB(step); + NdbDictionary::Dictionary* dict = pNdb->getDictionary(); + int records = ctx->getNumRecords(); + const int loops = ctx->getNumLoops(); + + ndbout << "|- " << ctx->getTab()->getName() << endl; + + for (int l = 0; l < loops && result == NDBT_OK ; l++){ + const NdbDictionary::Table* pTab = ctx->getTab(); + + // Try to create table in db + if (pTab->createTableInDb(pNdb) != 0){ + return NDBT_FAILED; + } + + // Verify that table is in db + const NdbDictionary::Table* pTab2 = + NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); + if (pTab2 == NULL){ + ndbout << pTab->getName() << " was not found in DB"<< endl; + return NDBT_FAILED; + } + ctx->setTab(pTab2); + + // Load table + HugoTransactions hugoTrans(*ctx->getTab()); + if (hugoTrans.loadTable(pNdb, records) != 0){ + return NDBT_FAILED; + } + + // Rename table + BaseString pTabName(pTab->getName()); + BaseString pTabNewName(pTabName); + pTabNewName.append("xx"); + + const NdbDictionary::Table * oldTable = dict->getTable(pTabName.c_str()); + if (oldTable) { + NdbDictionary::Table newTable = dict->getTableForAlteration(pTabName.c_str()); + newTable.setName(pTabNewName.c_str()); + CHECK2(dict->alterTable(newTable) == 0, + "TableRename failed"); + } + else { + result = NDBT_FAILED; + } + + // Verify table contents + NdbDictionary::Table pNewTab(pTabNewName.c_str()); + + UtilTransactions utilTrans(pNewTab); + if (utilTrans.clearTable(pNdb, records) != 0){ + continue; + } + + // Drop table + dict->dropTable(pNewTab.getName()); + } + end: + + return result; +} + +int +runTableRenameNF(NDBT_Context* ctx, NDBT_Step* step){ + NdbRestarter restarter; + if(restarter.getNumDbNodes() < 2) + return NDBT_OK; + + int result = NDBT_OK; + + Ndb* pNdb = GETNDB(step); + NdbDictionary::Dictionary* dict = pNdb->getDictionary(); + int records = ctx->getNumRecords(); + const int loops = ctx->getNumLoops(); + + ndbout << "|- " << ctx->getTab()->getName() << endl; + + for (int l = 0; l < loops && result == NDBT_OK ; l++){ + const NdbDictionary::Table* pTab = ctx->getTab(); + + // Try to create table in db + if (pTab->createTableInDb(pNdb) != 0){ + return NDBT_FAILED; + } + + // Verify that table is in db + const NdbDictionary::Table* pTab2 = + NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); + if (pTab2 == NULL){ + ndbout << pTab->getName() << " was not found in DB"<< endl; + return NDBT_FAILED; + } + ctx->setTab(pTab2); + + // Load table + HugoTransactions hugoTrans(*ctx->getTab()); + if (hugoTrans.loadTable(pNdb, records) != 0){ + return NDBT_FAILED; + } + + BaseString pTabName(pTab->getName()); + BaseString pTabNewName(pTabName); + pTabNewName.append("xx"); + + const NdbDictionary::Table * oldTable = dict->getTable(pTabName.c_str()); + if (oldTable) { + NdbDictionary::Table newTable = dict->getTableForAlteration(pTabName.c_str()); + newTable.setName(pTabNewName.c_str()); + CHECK2(dict->alterTable(newTable) == 0, + "TableRename failed"); + } + else { + result = NDBT_FAILED; + } + + // Restart one node at a time + + /** + * Need to run LCP at high rate otherwise + * packed replicas become "to many" + */ + int val = DumpStateOrd::DihMinTimeBetweenLCP; + if(restarter.dumpStateAllNodes(&val, 1) != 0){ + do { CHECK(0); } while(0); + g_err << "Failed to set LCP to min value" << endl; + return NDBT_FAILED; + } + + const int numNodes = restarter.getNumDbNodes(); + for(int i = 0; idropTable(pTabNewName.c_str()); + } + end: + return result; +} + +int +runTableRenameSR(NDBT_Context* ctx, NDBT_Step* step){ + NdbRestarter restarter; + if(restarter.getNumDbNodes() < 2) + return NDBT_OK; + + int result = NDBT_OK; + + Ndb* pNdb = GETNDB(step); + NdbDictionary::Dictionary* dict = pNdb->getDictionary(); + int records = ctx->getNumRecords(); + const int loops = ctx->getNumLoops(); + + ndbout << "|- " << ctx->getTab()->getName() << endl; + + for (int l = 0; l < loops && result == NDBT_OK ; l++){ + // Rename table + const NdbDictionary::Table* pTab = ctx->getTab(); + + // Try to create table in db + if (pTab->createTableInDb(pNdb) != 0){ + return NDBT_FAILED; + } + + // Verify that table is in db + const NdbDictionary::Table* pTab2 = + NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); + if (pTab2 == NULL){ + ndbout << pTab->getName() << " was not found in DB"<< endl; + return NDBT_FAILED; + } + ctx->setTab(pTab2); + + // Load table + HugoTransactions hugoTrans(*ctx->getTab()); + if (hugoTrans.loadTable(pNdb, records) != 0){ + return NDBT_FAILED; + } + + BaseString pTabName(pTab->getName()); + BaseString pTabNewName(pTabName); + pTabNewName.append("xx"); + + const NdbDictionary::Table * oldTable = dict->getTable(pTabName.c_str()); + if (oldTable) { + NdbDictionary::Table newTable = dict->getTableForAlteration(pTabName.c_str()); + newTable.setName(pTabNewName.c_str()); + CHECK2(dict->alterTable(newTable) == 0, + "TableRename failed"); + } + else { + result = NDBT_FAILED; + } + + // Restart cluster + + /** + * Need to run LCP at high rate otherwise + * packed replicas become "to many" + */ + int val = DumpStateOrd::DihMinTimeBetweenLCP; + if(restarter.dumpStateAllNodes(&val, 1) != 0){ + do { CHECK(0); } while(0); + g_err << "Failed to set LCP to min value" << endl; + return NDBT_FAILED; + } + + CHECK2(restarter.restartAll() == 0, + "failed to set restartOneDbNode"); + + CHECK2(restarter.waitClusterStarted() == 0, + "waitClusterStarted failed"); + + // Verify table contents + NdbDictionary::Table pNewTab(pTabNewName.c_str()); + + UtilTransactions utilTrans(pNewTab); + if (utilTrans.clearTable(pNdb, records) != 0){ + continue; + } + + // Drop table + dict->dropTable(pTabNewName.c_str()); + } + end: + return result; +} + +static void +f(const NdbDictionary::Column * col){ + if(col == 0){ + abort(); + } +} + +int +runTestDictionaryPerf(NDBT_Context* ctx, NDBT_Step* step){ + Vector cols; + Vector tabs; + + Ndb* pNdb = GETNDB(step); + + const Uint32 count = NDBT_Tables::getNumTables(); + for (int i=0; i < count; i++){ + const NdbDictionary::Table * tab = NDBT_Tables::getTable(i); + pNdb->getDictionary()->createTable(* tab); + + const NdbDictionary::Table * tab2 = pNdb->getDictionary()->getTable(tab->getName()); + + for(size_t j = 0; jgetNoOfColumns(); j++){ + cols.push_back((char*)tab2); + cols.push_back(strdup(tab->getColumn(j)->getName())); + } + } + + const Uint32 times = 10000000; + + ndbout_c("%d tables and %d columns", + NDBT_Tables::getNumTables(), cols.size()/2); + + char ** tcols = cols.getBase(); + + srand(time(0)); + Uint32 size = cols.size() / 2; + char ** columns = &cols[0]; + Uint64 start = NdbTick_CurrentMillisecond(); + for(int i = 0; igetColumn(col); + f(column); + } + Uint64 stop = NdbTick_CurrentMillisecond(); + stop -= start; + + Uint64 per = stop; + per *= 1000; + per /= times; + + ndbout_c("%d random getColumn(name) in %Ld ms -> %d us/get", + times, stop, per); + + return NDBT_OK; +} + +NDBT_TESTSUITE(testDict); +TESTCASE("CreateAndDrop", + "Try to create and drop the table loop number of times\n"){ + INITIALIZER(runCreateAndDrop); +} +TESTCASE("CreateAndDropWithData", + "Try to create and drop the table when it's filled with data\n" + "do this loop number of times\n"){ + INITIALIZER(runCreateAndDropWithData); +} +TESTCASE("CreateAndDropDuring", + "Try to create and drop the table when other thread is using it\n" + "do this loop number of times\n"){ + STEP(runCreateAndDropDuring); + STEP(runUseTableUntilStopped); +} +TESTCASE("CreateInvalidTables", + "Try to create the invalid tables we have defined\n"){ + INITIALIZER(runCreateInvalidTables); +} +TESTCASE("CreateTableWhenDbIsFull", + "Try to create a new table when db already is full\n"){ + INITIALIZER(runCreateTheTable); + INITIALIZER(runFillTable); + INITIALIZER(runCreateTableWhenDbIsFull); + INITIALIZER(runDropTableWhenDbIsFull); + FINALIZER(runClearTable); +} +TESTCASE("FragmentTypeSingle", + "Create the table with fragment type Single\n"){ + TC_PROPERTY("FragmentType", 1); + INITIALIZER(runTestFragmentTypes); +} +TESTCASE("FragmentTypeAll", + "Create the table with fragment type All\n"){ + TC_PROPERTY("FragmentType", 2); + INITIALIZER(runTestFragmentTypes); +} +TESTCASE("FragmentTypeAllLarge", + "Create the table with fragment type AllLarge\n"){ + TC_PROPERTY("FragmentType", 3); + INITIALIZER(runTestFragmentTypes); +} +TESTCASE("TemporaryTables", + "Create the table as temporary and make sure it doesn't\n" + "contain any data when system is restarted\n"){ + INITIALIZER(runTestTemporaryTables); +} +TESTCASE("CreateMaxTables", + "Create tables until db says that it can't create any more\n"){ + TC_PROPERTY("tables", 1000); + INITIALIZER(runCreateMaxTables); + FINALIZER(runDropMaxTables); +} +TESTCASE("PkSizes", + "Create tables with all different primary key sizes.\n"\ + "Test all data operations insert, update, delete etc.\n"\ + "Drop table."){ + INITIALIZER(runPkSizes); +} +TESTCASE("StoreFrm", + "Test that a frm file can be properly stored as part of the\n" + "data in Dict."){ + INITIALIZER(runStoreFrm); +} +TESTCASE("GetPrimaryKey", + "Test the function NdbDictionary::Column::getPrimaryKey\n" + "It should return true only if the column is part of \n" + "the primary key in the table"){ + INITIALIZER(runGetPrimaryKey); +} +TESTCASE("StoreFrmError", + "Test that a frm file with too long length can't be stored."){ + INITIALIZER(runStoreFrmError); +} +TESTCASE("NF1", + "Test that create table can handle NF (not master)"){ + INITIALIZER(runNF1); +} +TESTCASE("TableRename", + "Test basic table rename"){ + INITIALIZER(runTableRename); +} +TESTCASE("TableRenameNF", + "Test that table rename can handle node failure"){ + INITIALIZER(runTableRenameNF); +} +TESTCASE("TableRenameSR", + "Test that table rename can handle system restart"){ + INITIALIZER(runTableRenameSR); +} +TESTCASE("DictionaryPerf", + ""){ + INITIALIZER(runTestDictionaryPerf); +} +NDBT_TESTSUITE_END(testDict); + +int main(int argc, const char** argv){ + // Tables should not be auto created + testDict.setCreateTable(false); + myRandom48Init(NdbTick_CurrentMillisecond()); + return testDict.execute(argc, argv); +} + + diff --git a/ndb/test/ndbapi/testDict/Makefile b/ndb/test/ndbapi/testDict/Makefile deleted file mode 100644 index 75d493c3424..00000000000 --- a/ndb/test/ndbapi/testDict/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -include .defs.mk - -TYPE = ndbapitest - -BIN_TARGET = testDict - -SOURCES = testDict.cpp - -CFLAGS_testDict.cpp := -I$(call fixpath,$(NDB_TOP)/include/kernel) - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/testDict/testDict.cpp b/ndb/test/ndbapi/testDict/testDict.cpp deleted file mode 100644 index 06614690b8d..00000000000 --- a/ndb/test/ndbapi/testDict/testDict.cpp +++ /dev/null @@ -1,1578 +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 */ - -#include -#include -#include -#include -#include -#include -#include -#include <../../include/kernel/ndb_limits.h> -#include -#include - -#define CHECK(b) if (!(b)) { \ - g_err << "ERR: "<< step->getName() \ - << " failed on line " << __LINE__ << endl; \ - result = NDBT_FAILED; \ - break; } - -#define CHECK2(b, c) if (!(b)) { \ - g_err << "ERR: "<< step->getName() \ - << " failed on line " << __LINE__ << ": " << c << endl; \ - result = NDBT_FAILED; \ - goto end; } - -int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ - Ndb* pNdb = GETNDB(step); - int records = ctx->getNumRecords(); - HugoTransactions hugoTrans(*ctx->getTab()); - if (hugoTrans.loadTable(pNdb, records) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - - -int runCreateInvalidTables(NDBT_Context* ctx, NDBT_Step* step){ - Ndb* pNdb = GETNDB(step); - int result = NDBT_OK; - - char failTabName[256]; - - for (int i = 0; i < 10; i++){ - snprintf(failTabName, 256, "F%d", i); - - const NdbDictionary::Table* pFailTab = NDBT_Tables::getTable(failTabName); - if (pFailTab != NULL){ - ndbout << "|- " << failTabName << endl; - - // Try to create table in db - if (pFailTab->createTableInDb(pNdb) == 0){ - ndbout << failTabName << " created, this was not expected"<< endl; - result = NDBT_FAILED; - } - - // Verify that table is not in db - const NdbDictionary::Table* pTab2 = - NDBT_Table::discoverTableFromDb(pNdb, failTabName) ; - if (pTab2 != NULL){ - ndbout << failTabName << " was found in DB, this was not expected"<< endl; - result = NDBT_FAILED; - if (pFailTab->equal(*pTab2) == true){ - ndbout << "It was equal" << endl; - } else { - ndbout << "It was not equal" << endl; - } - int records = 1000; - HugoTransactions hugoTrans(*pTab2); - if (hugoTrans.loadTable(pNdb, records) != 0){ - ndbout << "It can NOT be loaded" << endl; - } else{ - ndbout << "It can be loaded" << endl; - - UtilTransactions utilTrans(*pTab2); - if (utilTrans.clearTable(pNdb, records, 64) != 0){ - ndbout << "It can NOT be cleared" << endl; - } else{ - ndbout << "It can be cleared" << endl; - } - } - - if (pNdb->getDictionary()->dropTable(pTab2->getName()) == -1){ - ndbout << "It can NOT be dropped" << endl; - } else { - ndbout << "It can be dropped" << endl; - } - } - } - } - return result; -} - -int runCreateTheTable(NDBT_Context* ctx, NDBT_Step* step){ - Ndb* pNdb = GETNDB(step); - const NdbDictionary::Table* pTab = ctx->getTab(); - - // Try to create table in db - if (pTab->createTableInDb(pNdb) != 0){ - return NDBT_FAILED; - } - - // Verify that table is in db - const NdbDictionary::Table* pTab2 = - NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); - if (pTab2 == NULL){ - ndbout << pTab->getName() << " was not found in DB"<< endl; - return NDBT_FAILED; - } - ctx->setTab(pTab2); - - return NDBT_OK; -} - -int runCreateTableWhenDbIsFull(NDBT_Context* ctx, NDBT_Step* step){ - Ndb* pNdb = GETNDB(step); - int result = NDBT_OK; - const char* tabName = "TRANSACTION"; //Use a util table - - const NdbDictionary::Table* pTab = NDBT_Tables::getTable(tabName); - if (pTab != NULL){ - ndbout << "|- " << tabName << endl; - - // Verify that table is not in db - if (NDBT_Table::discoverTableFromDb(pNdb, tabName) != NULL){ - ndbout << tabName << " was found in DB"<< endl; - return NDBT_FAILED; - } - - // Try to create table in db - if (pTab->createTableInDb(pNdb) == 0){ - result = NDBT_FAILED; - } - - // Verify that table is in db - if (NDBT_Table::discoverTableFromDb(pNdb, tabName) != NULL){ - ndbout << tabName << " was found in DB"<< endl; - result = NDBT_FAILED; - } - } - - return result; -} - -int runDropTableWhenDbIsFull(NDBT_Context* ctx, NDBT_Step* step){ - Ndb* pNdb = GETNDB(step); - int result = NDBT_OK; - const char* tabName = "TRANSACTION"; //Use a util table - - const NdbDictionary::Table* pTab = NDBT_Table::discoverTableFromDb(pNdb, tabName); - if (pTab != NULL){ - ndbout << "|- TRANSACTION" << endl; - - // Try to drop table in db - if (pNdb->getDictionary()->dropTable(pTab->getName()) == -1){ - result = NDBT_FAILED; - } - - // Verify that table is not in db - if (NDBT_Table::discoverTableFromDb(pNdb, tabName) != NULL){ - ndbout << tabName << " was found in DB"<< endl; - result = NDBT_FAILED; - } - } - - return result; - -} - - -int runCreateAndDrop(NDBT_Context* ctx, NDBT_Step* step){ - Ndb* pNdb = GETNDB(step); - int loops = ctx->getNumLoops(); - int i = 0; - - const NdbDictionary::Table* pTab = ctx->getTab(); - ndbout << "|- " << pTab->getName() << endl; - - while (i < loops){ - - ndbout << i << ": "; - // Try to create table in db - if (pTab->createTableInDb(pNdb) != 0){ - return NDBT_FAILED; - } - - // Verify that table is in db - const NdbDictionary::Table* pTab2 = - NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); - if (pTab2 == NULL){ - ndbout << pTab->getName() << " was not found in DB"<< endl; - return NDBT_FAILED; - } - - if (pNdb->getDictionary()->dropTable(pTab2->getName())){ - ndbout << "Failed to drop "<getName()<<" in db" << endl; - return NDBT_FAILED; - } - - // Verify that table is not in db - const NdbDictionary::Table* pTab3 = - NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); - if (pTab3 != NULL){ - ndbout << pTab3->getName() << " was found in DB"<< endl; - return NDBT_FAILED; - } - i++; - } - - return NDBT_OK; -} - -int runCreateAndDropWithData(NDBT_Context* ctx, NDBT_Step* step){ - Ndb* pNdb = GETNDB(step); - int loops = ctx->getNumLoops(); - int records = ctx->getNumRecords(); - int i = 0; - - NdbRestarter restarter; - int val = DumpStateOrd::DihMinTimeBetweenLCP; - if(restarter.dumpStateAllNodes(&val, 1) != 0){ - int result; - do { CHECK(0); } while (0); - g_err << "Unable to change timebetween LCP" << endl; - return NDBT_FAILED; - } - - const NdbDictionary::Table* pTab = ctx->getTab(); - ndbout << "|- " << pTab->getName() << endl; - - while (i < loops){ - ndbout << i << ": "; - // Try to create table in db - if (pTab->createTableInDb(pNdb) != 0){ - return NDBT_FAILED; - } - - // Verify that table is in db - const NdbDictionary::Table* pTab2 = - NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); - if (pTab2 == NULL){ - ndbout << pTab->getName() << " was not found in DB"<< endl; - return NDBT_FAILED; - } - - HugoTransactions hugoTrans(*pTab2); - if (hugoTrans.loadTable(pNdb, records) != 0){ - return NDBT_FAILED; - } - - int count = 0; - UtilTransactions utilTrans(*pTab2); - if (utilTrans.selectCount(pNdb, 64, &count) != 0){ - return NDBT_FAILED; - } - if (count != records){ - ndbout << count <<" != "<getDictionary()->dropTable(pTab2->getName()) != 0){ - ndbout << "Failed to drop "<getName()<<" in db" << endl; - return NDBT_FAILED; - } - - // Verify that table is not in db - const NdbDictionary::Table* pTab3 = - NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); - if (pTab3 != NULL){ - ndbout << pTab3->getName() << " was found in DB"<< endl; - return NDBT_FAILED; - } - - - i++; - } - - return NDBT_OK; -} - -int runFillTable(NDBT_Context* ctx, NDBT_Step* step){ - Ndb* pNdb = GETNDB(step); - HugoTransactions hugoTrans(*ctx->getTab()); - if (hugoTrans.fillTable(pNdb) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ - Ndb* pNdb = GETNDB(step); - int records = ctx->getNumRecords(); - - UtilTransactions utilTrans(*ctx->getTab()); - if (utilTrans.clearTable(pNdb, records) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runCreateAndDropDuring(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - int loops = ctx->getNumLoops(); - int i = 0; - - const NdbDictionary::Table* pTab = ctx->getTab(); - ndbout << "|- " << pTab->getName() << endl; - - while (i < loops && result == NDBT_OK){ - ndbout << i << ": " << endl; - // Try to create table in db - - Ndb* pNdb = GETNDB(step); - g_debug << "Creating table" << endl; - - if (pTab->createTableInDb(pNdb) != 0){ - g_err << "createTableInDb failed" << endl; - result = NDBT_FAILED; - continue; - } - - g_debug << "Verifying creation of table" << endl; - - // Verify that table is in db - const NdbDictionary::Table* pTab2 = - NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); - if (pTab2 == NULL){ - g_err << pTab->getName() << " was not found in DB"<< endl; - result = NDBT_FAILED; - continue; - } - - NdbSleep_MilliSleep(3000); - - g_debug << "Dropping table" << endl; - - - if (pNdb->getDictionary()->dropTable(pTab2->getName()) != 0){ - g_err << "Failed to drop "<getName()<<" in db" << endl; - result = NDBT_FAILED; - continue; - } - - g_debug << "Verifying dropping of table" << endl; - - // Verify that table is not in db - const NdbDictionary::Table* pTab3 = - NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); - if (pTab3 != NULL){ - g_err << pTab3->getName() << " was found in DB"<< endl; - result = NDBT_FAILED; - continue; - } - i++; - } - ctx->stopTest(); - - return result; -} - - -int runUseTableUntilStopped(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - - const NdbDictionary::Table* pTab = ctx->getTab(); - - while (ctx->isTestStopped() == false) { - // g_info << i++ << ": "; - - - // Delete and recreate Ndb object - // Otherwise you always get Invalid Schema Version - // It would be a nice feature to remove this two lines - //step->tearDown(); - //step->setUp(); - - Ndb* pNdb = GETNDB(step); - - const NdbDictionary::Table* pTab2 = - NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); - if (pTab2 == NULL) - continue; - - int res; - HugoTransactions hugoTrans(*pTab2); - if ((res = hugoTrans.loadTable(pNdb, records)) != 0){ - NdbError err = pNdb->getNdbError(res); - if(err.classification == NdbError::SchemaError){ - pNdb->getDictionary()->invalidateTable(pTab->getName()); - } - continue; - } - - UtilTransactions utilTrans(*pTab2); - if ((res = utilTrans.clearTable(pNdb, records)) != 0){ - NdbError err = pNdb->getNdbError(res); - if(err.classification == NdbError::SchemaError){ - pNdb->getDictionary()->invalidateTable(pTab->getName()); - } - continue; - } - } - g_info << endl; - return NDBT_OK; -} - - -int runCreateMaxTables(NDBT_Context* ctx, NDBT_Step* step){ - int failures = 0; - char tabName[256]; - int numTables = ctx->getProperty("tables", 1000); - Ndb* pNdb = GETNDB(step); - - for (int i = 0; i < numTables && failures < 5; i++){ - snprintf(tabName, 256, "MAXTAB%d", i); - - if (pNdb->waitUntilReady(30) != 0){ - // Db is not ready, return with failure - return NDBT_FAILED; - } - - const NdbDictionary::Table* pTab = ctx->getTab(); - ndbout << "|- " << tabName << endl; - - // Set new name for T1 - NdbDictionary::Table newTab(* pTab); - newTab.setName(tabName); - - // Try to create table in db - if (newTab.createTableInDb(pNdb) != 0){ - ndbout << tabName << " coult not be created"<< endl; - failures++; - continue; - } - - // Verify that table exists in db - const NdbDictionary::Table* pTab3 = - NDBT_Table::discoverTableFromDb(pNdb, tabName) ; - if (pTab3 == NULL){ - ndbout << tabName << " was not found in DB"<< endl; - failures++; - continue; - } - - if (pTab->equal(*pTab3) == false){ - ndbout << "It was not equal" << endl; - failures++; - } - - int records = 1000; - HugoTransactions hugoTrans(*pTab3); - if (hugoTrans.loadTable(pNdb, records) != 0){ - ndbout << "It can NOT be loaded" << endl; - } else{ - ndbout << "It can be loaded" << endl; - - UtilTransactions utilTrans(*pTab3); - if (utilTrans.clearTable(pNdb, records, 64) != 0){ - ndbout << "It can NOT be cleared" << endl; - } else{ - ndbout << "It can be cleared" << endl; - } - } - - } - if (pNdb->waitUntilReady(30) != 0){ - // Db is not ready, return with failure - return NDBT_FAILED; - } - // HURRAAA! - return NDBT_OK; -} - -int runDropMaxTables(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - char tabName[256]; - int numTables = ctx->getProperty("tables", 1000); - Ndb* pNdb = GETNDB(step); - - for (int i = 0; i < numTables; i++){ - snprintf(tabName, 256, "MAXTAB%d", i); - - if (pNdb->waitUntilReady(30) != 0){ - // Db is not ready, return with failure - return NDBT_FAILED; - } - - // Verify that table exists in db - const NdbDictionary::Table* pTab3 = - NDBT_Table::discoverTableFromDb(pNdb, tabName) ; - if (pTab3 == NULL){ - ndbout << tabName << " was not found in DB"<< endl; - continue; - } - - - // Try to drop table in db - if (pNdb->getDictionary()->dropTable(pTab3->getName()) != 0){ - ndbout << tabName << " coult not be dropped"<< endl; - result = NDBT_FAILED; - } - - } - return result; -} - -int runTestFragmentTypes(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - int fragTtype = ctx->getProperty("FragmentType"); - Ndb* pNdb = GETNDB(step); - int result = NDBT_OK; - NdbRestarter restarter; - - // enum FragmentType { - // Unknown = 0, - // Single = 1, ///< Only one fragment - // All = 2, ///< Default value. One fragment per node group - // AllLarge = 3 ///< Sixten fragments per node group. - // }; - - if (pNdb->waitUntilReady(30) != 0){ - // Db is not ready, return with failure - return NDBT_FAILED; - } - - const NdbDictionary::Table* pTab = ctx->getTab(); - - NdbDictionary::Table newTab(* pTab); - // Set fragment type for table - newTab.setFragmentType((NdbDictionary::Object::FragmentType)fragTtype); - - // Try to create table in db - if (newTab.createTableInDb(pNdb) != 0){ - ndbout << newTab.getName() << " could not be created" - << ", fragmentType = "<getName()) ; - if (pTab3 == NULL){ - ndbout << pTab->getName() << " was not found in DB"<< endl; - return NDBT_FAILED; - - } - - if (pTab3->getFragmentType() != fragTtype){ - ndbout << pTab->getName() << " fragmentType error "<< endl; - result = NDBT_FAILED; - goto drop_the_tab; - } - - if (newTab.equal(*pTab3) == false){ - ndbout << "It was not equal" << endl; - result = NDBT_FAILED; - goto drop_the_tab; - } - - do { - - HugoTransactions hugoTrans(*pTab3); - UtilTransactions utilTrans(*pTab3); - int count; - CHECK(hugoTrans.loadTable(pNdb, records) == 0); - CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == records); - CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); - CHECK(hugoTrans.scanUpdateRecords(pNdb, records) == 0); - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == (records/2)); - - // restart all - ndbout << "Restarting cluster" << endl; - CHECK(restarter.restartAll() == 0); - int timeout = 120; - CHECK(restarter.waitClusterStarted(timeout) == 0); - CHECK(pNdb->waitUntilReady(timeout) == 0); - - // Verify content - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == (records/2)); - - CHECK(utilTrans.clearTable(pNdb, records) == 0); - CHECK(hugoTrans.loadTable(pNdb, records) == 0); - CHECK(utilTrans.clearTable(pNdb, records) == 0); - CHECK(hugoTrans.loadTable(pNdb, records) == 0); - CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); - CHECK(utilTrans.clearTable(pNdb, records, 64) == 0); - - } while(false); - - drop_the_tab: - - // Try to drop table in db - if (pNdb->getDictionary()->dropTable(pTab3->getName()) != 0){ - ndbout << pTab3->getName() << " could not be dropped"<< endl; - result = NDBT_FAILED; - } - - return result; -} - - -int runTestTemporaryTables(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - int loops = ctx->getNumLoops(); - int records = ctx->getNumRecords(); - Ndb* pNdb = GETNDB(step); - int i = 0; - NdbRestarter restarter; - - const NdbDictionary::Table* pTab = ctx->getTab(); - ndbout << "|- " << pTab->getName() << endl; - - NdbDictionary::Table newTab(* pTab); - // Set table as temporary - newTab.setStoredTable(false); - - // Try to create table in db - if (newTab.createTableInDb(pNdb) != 0){ - return NDBT_FAILED; - } - - // Verify that table is in db - const NdbDictionary::Table* pTab2 = - NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); - if (pTab2 == NULL){ - ndbout << pTab->getName() << " was not found in DB"<< endl; - return NDBT_FAILED; - } - - if (pTab2->getStoredTable() != false){ - ndbout << pTab->getName() << " was not temporary in DB"<< endl; - result = NDBT_FAILED; - goto drop_the_tab; - } - - - while (i < loops && result == NDBT_OK){ - ndbout << i << ": "; - - HugoTransactions hugoTrans(*pTab2); - CHECK(hugoTrans.loadTable(pNdb, records) == 0); - - int count = 0; - UtilTransactions utilTrans(*pTab2); - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == records); - - // restart all - ndbout << "Restarting cluster" << endl; - CHECK(restarter.restartAll() == 0); - int timeout = 120; - CHECK(restarter.waitClusterStarted(timeout) == 0); - CHECK(pNdb->waitUntilReady(timeout) == 0); - - ndbout << "Verifying records..." << endl; - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == 0); - - i++; - } - - drop_the_tab: - - - if (pNdb->getDictionary()->dropTable(pTab2->getName()) != 0){ - ndbout << "Failed to drop "<getName()<<" in db" << endl; - result = NDBT_FAILED; - } - - // Verify that table is not in db - const NdbDictionary::Table* pTab3 = - NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); - if (pTab3 != NULL){ - ndbout << pTab3->getName() << " was found in DB"<< endl; - result = NDBT_FAILED; - } - - return result; -} - -int runPkSizes(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - char tabName[256]; - int minPkSize = 1; - ndbout << "minPkSize=" < max) - records = max; - ndbout << "records =" << records << endl; - - if (pNdb->waitUntilReady(30) != 0){ - // Db is not ready, return with failure - return NDBT_FAILED; - } - - ndbout << "|- " << tabName << endl; - - if (NDBT_Tables::createTable(pNdb, tabName) != 0){ - ndbout << tabName << " could not be created"<< endl; - return NDBT_FAILED; - } - - // Verify that table exists in db - const NdbDictionary::Table* pTab3 = - NDBT_Table::discoverTableFromDb(pNdb, tabName) ; - if (pTab3 == NULL){ - g_err << tabName << " was not found in DB"<< endl; - return NDBT_FAILED; - } - - // ndbout << *pTab3 << endl; - - if (pTab3->equal(*NDBT_Tables::getTable(tabName)) == false){ - g_err << "It was not equal" << endl; - return NDBT_FAILED; - } - - do { - // Do it all - HugoTransactions hugoTrans(*pTab3); - UtilTransactions utilTrans(*pTab3); - int count; - CHECK(hugoTrans.loadTable(pNdb, records) == 0); - CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == records); - CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); - CHECK(hugoTrans.scanUpdateRecords(pNdb, records) == 0); - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == (records/2)); - CHECK(utilTrans.clearTable(pNdb, records) == 0); - -#if 0 - // Fill table - CHECK(hugoTrans.fillTable(pNdb) == 0); - CHECK(utilTrans.clearTable2(pNdb, records) == 0); - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == 0); -#endif - } while(false); - - // Drop table - if (pNdb->getDictionary()->dropTable(pTab3->getName()) != 0){ - ndbout << "Failed to drop "<getName()<<" in db" << endl; - return NDBT_FAILED; - } - } - return result; -} - -int runStoreFrm(NDBT_Context* ctx, NDBT_Step* step){ - Ndb* pNdb = GETNDB(step); - const NdbDictionary::Table* pTab = ctx->getTab(); - int result = NDBT_OK; - int loops = ctx->getNumLoops(); - - for (int l = 0; l < loops && result == NDBT_OK ; l++){ - - Uint32 dataLen = (Uint32)myRandom48(MAX_FRM_DATA_SIZE); - // size_t dataLen = 10; - unsigned char data[MAX_FRM_DATA_SIZE]; - - char start = l + 248; - for(Uint32 i = 0; i < dataLen; i++){ - data[i] = start; - start++; - } -#if 0 - ndbout << "dataLen="<getName()); - if (pTab2 == NULL){ - g_err << pTab->getName() << " was not found in DB"<< endl; - result = NDBT_FAILED; - continue; - } - - const void* pData2 = pTab2->getFrmData(); - Uint32 resultLen = pTab2->getFrmLength(); - if (dataLen != resultLen){ - g_err << "Length of data failure" << endl - << " expected = " << dataLen << endl - << " got = " << resultLen << endl; - result = NDBT_FAILED; - } - - // Verfiy the frm data - if (memcmp(pData, pData2, resultLen) != 0){ - g_err << "Wrong data recieved" << endl; - for (size_t i = 0; i < dataLen; i++){ - unsigned char c = ((unsigned char*)pData2)[i]; - g_err << hex << c << ", "; - } - g_err << endl; - result = NDBT_FAILED; - } - - if (pNdb->getDictionary()->dropTable(pTab2->getName()) != 0){ - g_err << "It can NOT be dropped" << endl; - result = NDBT_FAILED; - } - } - - return result; -} - -int runStoreFrmError(NDBT_Context* ctx, NDBT_Step* step){ - Ndb* pNdb = GETNDB(step); - const NdbDictionary::Table* pTab = ctx->getTab(); - int result = NDBT_OK; - int loops = ctx->getNumLoops(); - - for (int l = 0; l < loops && result == NDBT_OK ; l++){ - - const Uint32 dataLen = MAX_FRM_DATA_SIZE + 10; - unsigned char data[dataLen]; - - char start = l + 248; - for(Uint32 i = 0; i < dataLen; i++){ - data[i] = start; - start++; - } -#if 0 - ndbout << "dataLen="<getName()); - if (pTab2 != NULL){ - g_err << pTab->getName() << " was found in DB"<< endl; - result = NDBT_FAILED; - if (pNdb->getDictionary()->dropTable(pTab2->getName()) != 0){ - g_err << "It can NOT be dropped" << endl; - result = NDBT_FAILED; - } - - continue; - } - - } - - return result; -} - -int verifyTablesAreEqual(const NdbDictionary::Table* pTab, const NdbDictionary::Table* pTab2){ - // Verify that getPrimaryKey only returned true for primary keys - for (int i = 0; i < pTab2->getNoOfColumns(); i++){ - const NdbDictionary::Column* col = pTab->getColumn(i); - const NdbDictionary::Column* col2 = pTab2->getColumn(i); - if (col->getPrimaryKey() != col2->getPrimaryKey()){ - g_err << "col->getPrimaryKey() != col2->getPrimaryKey()" << endl; - return NDBT_FAILED; - } - } - - if (!pTab->equal(*pTab2)){ - g_err << "equal failed" << endl; - g_info << *pTab; - g_info << *pTab2; - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runGetPrimaryKey(NDBT_Context* ctx, NDBT_Step* step){ - Ndb* pNdb = GETNDB(step); - const NdbDictionary::Table* pTab = ctx->getTab(); - ndbout << "|- " << pTab->getName() << endl; - g_info << *pTab; - // Try to create table in db - if (pTab->createTableInDb(pNdb) != 0){ - return NDBT_FAILED; - } - - const NdbDictionary::Table* pTab2 = - NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); - if (pTab2 == NULL){ - ndbout << pTab->getName() << " was not found in DB"<< endl; - return NDBT_FAILED; - } - - int result = NDBT_OK; - if (verifyTablesAreEqual(pTab, pTab2) != NDBT_OK) - result = NDBT_FAILED; - - -#if 0 - // Create an index on the table and see what - // the function returns now - char name[200]; - sprintf(name, "%s_X007", pTab->getName()); - NDBT_Index* pInd = new NDBT_Index(name); - pInd->setTable(pTab->getName()); - pInd->setType(NdbDictionary::Index::UniqueHashIndex); - // pInd->setLogging(false); - for (int i = 0; i < 2; i++){ - const NDBT_Attribute* pAttr = pTab->getAttribute(i); - pInd->addAttribute(*pAttr); - } - g_info << "Create index:" << endl << *pInd; - if (pInd->createIndexInDb(pNdb, false) != 0){ - result = NDBT_FAILED; - } - delete pInd; - - const NdbDictionary::Table* pTab3 = - NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); - if (pTab3 == NULL){ - ndbout << pTab->getName() << " was not found in DB"<< endl; - return NDBT_FAILED; - } - - if (verifyTablesAreEqual(pTab, pTab3) != NDBT_OK) - result = NDBT_FAILED; - if (verifyTablesAreEqual(pTab2, pTab3) != NDBT_OK) - result = NDBT_FAILED; -#endif - -#if 0 - if (pTab2->getDictionary()->dropTable(pNdb) != 0){ - ndbout << "Failed to drop "<getName()<<" in db" << endl; - return NDBT_FAILED; - } - - // Verify that table is not in db - const NdbDictionary::Table* pTab4 = - NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); - if (pTab4 != NULL){ - ndbout << pTab4->getName() << " was found in DB"<< endl; - return NDBT_FAILED; - } -#endif - - return result; -} - -int -NF_codes[] = { - 14000 - ,14001 - //,14002 -}; - -int -runNF1(NDBT_Context* ctx, NDBT_Step* step){ - NdbRestarter restarter; - if(restarter.getNumDbNodes() < 2) - return NDBT_OK; - - myRandom48Init(NdbTick_CurrentMillisecond()); - - Ndb* pNdb = GETNDB(step); - const NdbDictionary::Table* pTab = ctx->getTab(); - - NdbDictionary::Dictionary* dict = pNdb->getDictionary(); - dict->dropTable(pTab->getName()); - - int result = NDBT_OK; - - /** - * Need to run LCP at high rate otherwise - * packed replicas become "to many" - */ - int val = DumpStateOrd::DihMinTimeBetweenLCP; - if(restarter.dumpStateAllNodes(&val, 1) != 0){ - do { CHECK(0); } while(0); - g_err << "Failed to set LCP to min value" << endl; - return NDBT_FAILED; - } - - const int loops = ctx->getNumLoops(); - for (int l = 0; l < loops && result == NDBT_OK ; l++){ - const int sz = sizeof(NF_codes)/sizeof(NF_codes[0]); - for(int i = 0; icreateTable(* pTab) == 0, - "failed to create table"); - - CHECK2(restarter.waitNodesNoStart(&nodeId, 1) == 0, - "waitNodesNoStart failed"); - - if(myRandom48(100) > 50){ - CHECK2(restarter.startNodes(&nodeId, 1) == 0, - "failed to start node"); - - CHECK2(restarter.waitClusterStarted() == 0, - "waitClusterStarted failed"); - - CHECK2(dict->dropTable(pTab->getName()) == 0, - "drop table failed"); - } else { - CHECK2(dict->dropTable(pTab->getName()) == 0, - "drop table failed"); - - CHECK2(restarter.startNodes(&nodeId, 1) == 0, - "failed to start node"); - - CHECK2(restarter.waitClusterStarted() == 0, - "waitClusterStarted failed"); - } - - CHECK2(restarter.dumpStateOneNode(nodeId, &val, 1) == 0, - "Failed to set LCP to min value"); - } - } - end: - dict->dropTable(pTab->getName()); - - return result; -} - -#define APIERROR(error) \ - { g_err << "Error in " << __FILE__ << ", line:" << __LINE__ << ", code:" \ - << error.code << ", msg: " << error.message << "." << endl; \ - } - -int -runCreateAutoincrementTable(NDBT_Context* ctx, NDBT_Step* step){ - - Uint32 startvalues[5] = {256-2, 0, 256*256-2, ~0, 256*256*256-2}; - - int ret = NDBT_OK; - - for (int jj = 0; jj < 5 && ret == NDBT_OK; jj++) { - char tabname[] = "AUTOINCTAB"; - Uint32 startvalue = startvalues[jj]; - - NdbDictionary::Table myTable; - NdbDictionary::Column myColumn; - - Ndb* myNdb = GETNDB(step); - NdbDictionary::Dictionary* myDict = myNdb->getDictionary(); - - - if (myDict->getTable(tabname) != NULL) { - g_err << "NDB already has example table: " << tabname << endl; - APIERROR(myNdb->getNdbError()); - return NDBT_FAILED; - } - - myTable.setName(tabname); - - myColumn.setName("ATTR1"); - myColumn.setPrimaryKey(true); - myColumn.setType(NdbDictionary::Column::Unsigned); - myColumn.setLength(1); - myColumn.setNullable(false); - myColumn.setAutoIncrement(true); - if (startvalue != ~0) // check that default value starts with 1 - myColumn.setAutoIncrementInitialValue(startvalue); - myTable.addColumn(myColumn); - - if (myDict->createTable(myTable) == -1) { - g_err << "Failed to create table " << tabname << endl; - APIERROR(myNdb->getNdbError()); - return NDBT_FAILED; - } - - - if (startvalue == ~0) // check that default value starts with 1 - startvalue = 1; - - for (int i = 0; i < 16; i++) { - - Uint64 value = myNdb->getAutoIncrementValue(tabname, 1); - - if (value != (startvalue+i)) { - g_err << "value = " << value << " expected " << startvalue+i << endl;; - APIERROR(myNdb->getNdbError()); - // ret = NDBT_FAILED; - // break; - } - } - - if (myDict->dropTable(tabname) == -1) { - g_err << "Failed to drop table " << tabname << endl; - APIERROR(myNdb->getNdbError()); - ret = NDBT_FAILED; - } - } - - return ret; -} - -int -runTableRename(NDBT_Context* ctx, NDBT_Step* step){ - - int result = NDBT_OK; - - Ndb* pNdb = GETNDB(step); - NdbDictionary::Dictionary* dict = pNdb->getDictionary(); - int records = ctx->getNumRecords(); - const int loops = ctx->getNumLoops(); - - ndbout << "|- " << ctx->getTab()->getName() << endl; - - for (int l = 0; l < loops && result == NDBT_OK ; l++){ - const NdbDictionary::Table* pTab = ctx->getTab(); - - // Try to create table in db - if (pTab->createTableInDb(pNdb) != 0){ - return NDBT_FAILED; - } - - // Verify that table is in db - const NdbDictionary::Table* pTab2 = - NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); - if (pTab2 == NULL){ - ndbout << pTab->getName() << " was not found in DB"<< endl; - return NDBT_FAILED; - } - ctx->setTab(pTab2); - - // Load table - HugoTransactions hugoTrans(*ctx->getTab()); - if (hugoTrans.loadTable(pNdb, records) != 0){ - return NDBT_FAILED; - } - - // Rename table - BaseString pTabName(pTab->getName()); - BaseString pTabNewName(pTabName); - pTabNewName.append("xx"); - - const NdbDictionary::Table * oldTable = dict->getTable(pTabName.c_str()); - if (oldTable) { - NdbDictionary::Table newTable = dict->getTableForAlteration(pTabName.c_str()); - newTable.setName(pTabNewName.c_str()); - CHECK2(dict->alterTable(newTable) == 0, - "TableRename failed"); - } - else { - result = NDBT_FAILED; - } - - // Verify table contents - NdbDictionary::Table pNewTab(pTabNewName.c_str()); - - UtilTransactions utilTrans(pNewTab); - if (utilTrans.clearTable(pNdb, records) != 0){ - continue; - } - - // Drop table - dict->dropTable(pNewTab.getName()); - } - end: - - return result; -} - -int -runTableRenameNF(NDBT_Context* ctx, NDBT_Step* step){ - NdbRestarter restarter; - if(restarter.getNumDbNodes() < 2) - return NDBT_OK; - - int result = NDBT_OK; - - Ndb* pNdb = GETNDB(step); - NdbDictionary::Dictionary* dict = pNdb->getDictionary(); - int records = ctx->getNumRecords(); - const int loops = ctx->getNumLoops(); - - ndbout << "|- " << ctx->getTab()->getName() << endl; - - for (int l = 0; l < loops && result == NDBT_OK ; l++){ - const NdbDictionary::Table* pTab = ctx->getTab(); - - // Try to create table in db - if (pTab->createTableInDb(pNdb) != 0){ - return NDBT_FAILED; - } - - // Verify that table is in db - const NdbDictionary::Table* pTab2 = - NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); - if (pTab2 == NULL){ - ndbout << pTab->getName() << " was not found in DB"<< endl; - return NDBT_FAILED; - } - ctx->setTab(pTab2); - - // Load table - HugoTransactions hugoTrans(*ctx->getTab()); - if (hugoTrans.loadTable(pNdb, records) != 0){ - return NDBT_FAILED; - } - - BaseString pTabName(pTab->getName()); - BaseString pTabNewName(pTabName); - pTabNewName.append("xx"); - - const NdbDictionary::Table * oldTable = dict->getTable(pTabName.c_str()); - if (oldTable) { - NdbDictionary::Table newTable = dict->getTableForAlteration(pTabName.c_str()); - newTable.setName(pTabNewName.c_str()); - CHECK2(dict->alterTable(newTable) == 0, - "TableRename failed"); - } - else { - result = NDBT_FAILED; - } - - // Restart one node at a time - - /** - * Need to run LCP at high rate otherwise - * packed replicas become "to many" - */ - int val = DumpStateOrd::DihMinTimeBetweenLCP; - if(restarter.dumpStateAllNodes(&val, 1) != 0){ - do { CHECK(0); } while(0); - g_err << "Failed to set LCP to min value" << endl; - return NDBT_FAILED; - } - - const int numNodes = restarter.getNumDbNodes(); - for(int i = 0; idropTable(pTabNewName.c_str()); - } - end: - return result; -} - -int -runTableRenameSR(NDBT_Context* ctx, NDBT_Step* step){ - NdbRestarter restarter; - if(restarter.getNumDbNodes() < 2) - return NDBT_OK; - - int result = NDBT_OK; - - Ndb* pNdb = GETNDB(step); - NdbDictionary::Dictionary* dict = pNdb->getDictionary(); - int records = ctx->getNumRecords(); - const int loops = ctx->getNumLoops(); - - ndbout << "|- " << ctx->getTab()->getName() << endl; - - for (int l = 0; l < loops && result == NDBT_OK ; l++){ - // Rename table - const NdbDictionary::Table* pTab = ctx->getTab(); - - // Try to create table in db - if (pTab->createTableInDb(pNdb) != 0){ - return NDBT_FAILED; - } - - // Verify that table is in db - const NdbDictionary::Table* pTab2 = - NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); - if (pTab2 == NULL){ - ndbout << pTab->getName() << " was not found in DB"<< endl; - return NDBT_FAILED; - } - ctx->setTab(pTab2); - - // Load table - HugoTransactions hugoTrans(*ctx->getTab()); - if (hugoTrans.loadTable(pNdb, records) != 0){ - return NDBT_FAILED; - } - - BaseString pTabName(pTab->getName()); - BaseString pTabNewName(pTabName); - pTabNewName.append("xx"); - - const NdbDictionary::Table * oldTable = dict->getTable(pTabName.c_str()); - if (oldTable) { - NdbDictionary::Table newTable = dict->getTableForAlteration(pTabName.c_str()); - newTable.setName(pTabNewName.c_str()); - CHECK2(dict->alterTable(newTable) == 0, - "TableRename failed"); - } - else { - result = NDBT_FAILED; - } - - // Restart cluster - - /** - * Need to run LCP at high rate otherwise - * packed replicas become "to many" - */ - int val = DumpStateOrd::DihMinTimeBetweenLCP; - if(restarter.dumpStateAllNodes(&val, 1) != 0){ - do { CHECK(0); } while(0); - g_err << "Failed to set LCP to min value" << endl; - return NDBT_FAILED; - } - - CHECK2(restarter.restartAll() == 0, - "failed to set restartOneDbNode"); - - CHECK2(restarter.waitClusterStarted() == 0, - "waitClusterStarted failed"); - - // Verify table contents - NdbDictionary::Table pNewTab(pTabNewName.c_str()); - - UtilTransactions utilTrans(pNewTab); - if (utilTrans.clearTable(pNdb, records) != 0){ - continue; - } - - // Drop table - dict->dropTable(pTabNewName.c_str()); - } - end: - return result; -} - -static void -f(const NdbDictionary::Column * col){ - if(col == 0){ - abort(); - } -} - -int -runTestDictionaryPerf(NDBT_Context* ctx, NDBT_Step* step){ - Vector cols; - Vector tabs; - - Ndb* pNdb = GETNDB(step); - - const Uint32 count = NDBT_Tables::getNumTables(); - for (int i=0; i < count; i++){ - const NdbDictionary::Table * tab = NDBT_Tables::getTable(i); - pNdb->getDictionary()->createTable(* tab); - - const NdbDictionary::Table * tab2 = pNdb->getDictionary()->getTable(tab->getName()); - - for(size_t j = 0; jgetNoOfColumns(); j++){ - cols.push_back((char*)tab2); - cols.push_back(strdup(tab->getColumn(j)->getName())); - } - } - - const Uint32 times = 10000000; - - ndbout_c("%d tables and %d columns", - NDBT_Tables::getNumTables(), cols.size()/2); - - char ** tcols = cols.getBase(); - - srand(time(0)); - Uint32 size = cols.size() / 2; - char ** columns = &cols[0]; - Uint64 start = NdbTick_CurrentMillisecond(); - for(int i = 0; igetColumn(col); - f(column); - } - Uint64 stop = NdbTick_CurrentMillisecond(); - stop -= start; - - Uint64 per = stop; - per *= 1000; - per /= times; - - ndbout_c("%d random getColumn(name) in %Ld ms -> %d us/get", - times, stop, per); - - return NDBT_OK; -} - -NDBT_TESTSUITE(testDict); -TESTCASE("CreateAndDrop", - "Try to create and drop the table loop number of times\n"){ - INITIALIZER(runCreateAndDrop); -} -TESTCASE("CreateAndDropWithData", - "Try to create and drop the table when it's filled with data\n" - "do this loop number of times\n"){ - INITIALIZER(runCreateAndDropWithData); -} -TESTCASE("CreateAndDropDuring", - "Try to create and drop the table when other thread is using it\n" - "do this loop number of times\n"){ - STEP(runCreateAndDropDuring); - STEP(runUseTableUntilStopped); -} -TESTCASE("CreateInvalidTables", - "Try to create the invalid tables we have defined\n"){ - INITIALIZER(runCreateInvalidTables); -} -TESTCASE("CreateTableWhenDbIsFull", - "Try to create a new table when db already is full\n"){ - INITIALIZER(runCreateTheTable); - INITIALIZER(runFillTable); - INITIALIZER(runCreateTableWhenDbIsFull); - INITIALIZER(runDropTableWhenDbIsFull); - FINALIZER(runClearTable); -} -TESTCASE("FragmentTypeSingle", - "Create the table with fragment type Single\n"){ - TC_PROPERTY("FragmentType", 1); - INITIALIZER(runTestFragmentTypes); -} -TESTCASE("FragmentTypeAll", - "Create the table with fragment type All\n"){ - TC_PROPERTY("FragmentType", 2); - INITIALIZER(runTestFragmentTypes); -} -TESTCASE("FragmentTypeAllLarge", - "Create the table with fragment type AllLarge\n"){ - TC_PROPERTY("FragmentType", 3); - INITIALIZER(runTestFragmentTypes); -} -TESTCASE("TemporaryTables", - "Create the table as temporary and make sure it doesn't\n" - "contain any data when system is restarted\n"){ - INITIALIZER(runTestTemporaryTables); -} -TESTCASE("CreateMaxTables", - "Create tables until db says that it can't create any more\n"){ - TC_PROPERTY("tables", 1000); - INITIALIZER(runCreateMaxTables); - FINALIZER(runDropMaxTables); -} -TESTCASE("PkSizes", - "Create tables with all different primary key sizes.\n"\ - "Test all data operations insert, update, delete etc.\n"\ - "Drop table."){ - INITIALIZER(runPkSizes); -} -TESTCASE("StoreFrm", - "Test that a frm file can be properly stored as part of the\n" - "data in Dict."){ - INITIALIZER(runStoreFrm); -} -TESTCASE("GetPrimaryKey", - "Test the function NdbDictionary::Column::getPrimaryKey\n" - "It should return true only if the column is part of \n" - "the primary key in the table"){ - INITIALIZER(runGetPrimaryKey); -} -TESTCASE("StoreFrmError", - "Test that a frm file with too long length can't be stored."){ - INITIALIZER(runStoreFrmError); -} -TESTCASE("NF1", - "Test that create table can handle NF (not master)"){ - INITIALIZER(runNF1); -} -TESTCASE("TableRename", - "Test basic table rename"){ - INITIALIZER(runTableRename); -} -TESTCASE("TableRenameNF", - "Test that table rename can handle node failure"){ - INITIALIZER(runTableRenameNF); -} -TESTCASE("TableRenameSR", - "Test that table rename can handle system restart"){ - INITIALIZER(runTableRenameSR); -} -TESTCASE("DictionaryPerf", - ""){ - INITIALIZER(runTestDictionaryPerf); -} -NDBT_TESTSUITE_END(testDict); - -int main(int argc, const char** argv){ - // Tables should not be auto created - testDict.setCreateTable(false); - myRandom48Init(NdbTick_CurrentMillisecond()); - return testDict.execute(argc, argv); -} - - diff --git a/ndb/test/ndbapi/testGrep.cpp b/ndb/test/ndbapi/testGrep.cpp new file mode 100644 index 00000000000..4b870f6f9a9 --- /dev/null +++ b/ndb/test/ndbapi/testGrep.cpp @@ -0,0 +1,540 @@ +/* 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 */ + +#include +#include +#include +#include +#include + + +#define CHECK(b) if (!(b)) { \ + g_err << "ERR: "<< step->getName() \ + << " failed on line " << __LINE__ << endl; \ + result = NDBT_FAILED; \ + continue; } + + +int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ + + int records = ctx->getNumRecords(); + HugoTransactions hugoTrans(*ctx->getTab()); + if (hugoTrans.loadTable(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runPkUpdate(NDBT_Context* ctx, NDBT_Step* step){ + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + int batchSize = ctx->getProperty("BatchSize", 1); + int i = 0; + HugoTransactions hugoTrans(*ctx->getTab()); + while (igetTab(); + pNdb->getDictionary()->dropTable(tab->getName()); + + if (restarter.restartAll(true) != 0) + return NDBT_FAILED; + + return NDBT_OK; +} + +int runRestarter(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int loops = ctx->getNumLoops(); + NdbRestarter restarter; + int i = 0; + int lastId = 0; + + if (restarter.getNumDbNodes() < 2){ + ctx->stopTest(); + return NDBT_OK; + } + + if(restarter.waitClusterStarted(60) != 0){ + g_err << "Cluster failed to start" << endl; + return NDBT_FAILED; + } + + loops *= restarter.getNumDbNodes(); + while(iisTestStopped()){ + + int id = lastId % restarter.getNumDbNodes(); + int nodeId = restarter.getDbNodeId(id); + ndbout << "Restart node " << nodeId << endl; + if(restarter.restartOneDbNode(nodeId) != 0){ + g_err << "Failed to restartNextDbNode" << endl; + result = NDBT_FAILED; + break; + } + + if(restarter.waitClusterStarted(60) != 0){ + g_err << "Cluster failed to start" << endl; + result = NDBT_FAILED; + break; + } + + NdbSleep_SecSleep(1); + + lastId++; + i++; + } + + ctx->stopTest(); + + return result; +} + +int runCheckAllNodesStarted(NDBT_Context* ctx, NDBT_Step* step){ + NdbRestarter restarter; + + if(restarter.waitClusterStarted(1) != 0){ + g_err << "All nodes was not started " << endl; + return NDBT_FAILED; + } + + return NDBT_OK; +} + + +bool testMaster = true; +bool testSlave = false; + +int setMaster(NDBT_Context* ctx, NDBT_Step* step){ + testMaster = true; + testSlave = false; + return NDBT_OK; +} +int setMasterAsSlave(NDBT_Context* ctx, NDBT_Step* step){ + testMaster = true; + testSlave = true; + return NDBT_OK; +} +int setSlave(NDBT_Context* ctx, NDBT_Step* step){ + testMaster = false; + testSlave = true; + return NDBT_OK; +} + +int runAbort(NDBT_Context* ctx, NDBT_Step* step){ + + + NdbGrep grep(GETNDB(step)->getNodeId()+1); + NdbRestarter restarter; + + if (restarter.getNumDbNodes() < 2){ + ctx->stopTest(); + return NDBT_OK; + } + + if(restarter.waitClusterStarted(60) != 0){ + g_err << "Cluster failed to start" << endl; + return NDBT_FAILED; + } + + if (testMaster) { + if (testSlave) { + if (grep.NFMasterAsSlave(restarter) == -1){ + return NDBT_FAILED; + } + } else { + if (grep.NFMaster(restarter) == -1){ + return NDBT_FAILED; + } + } + } else { + if (grep.NFSlave(restarter) == -1){ + return NDBT_FAILED; + } + } + + return NDBT_OK; +} + +int runFail(NDBT_Context* ctx, NDBT_Step* step){ + NdbGrep grep(GETNDB(step)->getNodeId()+1); + + NdbRestarter restarter; + + if (restarter.getNumDbNodes() < 2){ + ctx->stopTest(); + return NDBT_OK; + } + + if(restarter.waitClusterStarted(60) != 0){ + g_err << "Cluster failed to start" << endl; + return NDBT_FAILED; + } + + if (testMaster) { + if (testSlave) { + if (grep.FailMasterAsSlave(restarter) == -1){ + return NDBT_FAILED; + } + } else { + if (grep.FailMaster(restarter) == -1){ + return NDBT_FAILED; + } + } + } else { + if (grep.FailSlave(restarter) == -1){ + return NDBT_FAILED; + } + } + + return NDBT_OK; +} + +int runGrepBasic(NDBT_Context* ctx, NDBT_Step* step){ + NdbGrep grep(GETNDB(step)->getNodeId()+1); + unsigned grepId = 0; + + if (grep.start() == -1){ + return NDBT_FAILED; + } + ndbout << "Started grep " << grepId << endl; + ctx->setProperty("GrepId", grepId); + + return NDBT_OK; +} + + + + +int runVerifyBasic(NDBT_Context* ctx, NDBT_Step* step){ + NdbGrep grep(GETNDB(step)->getNodeId()+1, ctx->getRemoteMgm()); + ndbout_c("no of nodes %d" ,grep.getNumDbNodes()); + int result; + if ((result = grep.verify(ctx)) == -1){ + return NDBT_FAILED; + } + return result; +} + + + +int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + + UtilTransactions utilTrans(*ctx->getTab()); + if (utilTrans.clearTable2(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + + +#include "../bank/Bank.hpp" + +int runCreateBank(NDBT_Context* ctx, NDBT_Step* step){ + Bank bank; + int overWriteExisting = true; + if (bank.createAndLoadBank(overWriteExisting) != NDBT_OK) + return NDBT_FAILED; + return NDBT_OK; +} + +int runBankTimer(NDBT_Context* ctx, NDBT_Step* step){ + Bank bank; + int wait = 30; // Max seconds between each "day" + int yield = 1; // Loops before bank returns + + while (ctx->isTestStopped() == false) { + bank.performIncreaseTime(wait, yield); + } + return NDBT_OK; +} + +int runBankTransactions(NDBT_Context* ctx, NDBT_Step* step){ + Bank bank; + int wait = 10; // Max ms between each transaction + int yield = 100; // Loops before bank returns + + while (ctx->isTestStopped() == false) { + bank.performTransactions(wait, yield); + } + return NDBT_OK; +} + +int runBankGL(NDBT_Context* ctx, NDBT_Step* step){ + Bank bank; + int yield = 20; // Loops before bank returns + int result = NDBT_OK; + + while (ctx->isTestStopped() == false) { + if (bank.performMakeGLs(yield) != NDBT_OK){ + ndbout << "bank.performMakeGLs FAILED" << endl; + result = NDBT_FAILED; + } + } + return NDBT_OK; +} + +int runBankSum(NDBT_Context* ctx, NDBT_Step* step){ + Bank bank; + int wait = 2000; // Max ms between each sum of accounts + int yield = 1; // Loops before bank returns + int result = NDBT_OK; + + while (ctx->isTestStopped() == false) { + if (bank.performSumAccounts(wait, yield) != NDBT_OK){ + ndbout << "bank.performSumAccounts FAILED" << endl; + result = NDBT_FAILED; + } + } + return result ; +} + +int runDropBank(NDBT_Context* ctx, NDBT_Step* step){ + Bank bank; + if (bank.dropBank() != NDBT_OK) + return NDBT_FAILED; + return NDBT_OK; +} + +int runGrepBank(NDBT_Context* ctx, NDBT_Step* step){ + int loops = ctx->getNumLoops(); + int l = 0; + int maxSleep = 30; // Max seconds between each grep + Ndb* pNdb = GETNDB(step); + NdbGrep grep(GETNDB(step)->getNodeId()+1); + unsigned minGrepId = ~0; + unsigned maxGrepId = 0; + unsigned grepId = 0; + int result = NDBT_OK; + + while (l < loops && result != NDBT_FAILED){ + + if (pNdb->waitUntilReady() != 0){ + result = NDBT_FAILED; + continue; + } + + // Sleep for a while + NdbSleep_SecSleep(maxSleep); + + // Perform grep + if (grep.start() != 0){ + ndbout << "grep.start failed" << endl; + result = NDBT_FAILED; + continue; + } + ndbout << "Started grep " << grepId << endl; + + // Remember min and max grepid + if (grepId < minGrepId) + minGrepId = grepId; + + if (grepId > maxGrepId) + maxGrepId = grepId; + + ndbout << " maxGrepId = " << maxGrepId + << ", minGrepId = " << minGrepId << endl; + ctx->setProperty("MinGrepId", minGrepId); + ctx->setProperty("MaxGrepId", maxGrepId); + + l++; + } + + ctx->stopTest(); + + return result; +} +/* +int runRestoreBankAndVerify(NDBT_Context* ctx, NDBT_Step* step){ + NdbRestarter restarter; + NdbGrep grep(GETNDB(step)->getNodeId()+1); + unsigned minGrepId = ctx->getProperty("MinGrepId"); + unsigned maxGrepId = ctx->getProperty("MaxGrepId"); + unsigned grepId = minGrepId; + int result = NDBT_OK; + int errSumAccounts = 0; + int errValidateGL = 0; + + ndbout << " maxGrepId = " << maxGrepId << endl; + ndbout << " minGrepId = " << minGrepId << endl; + + while (grepId <= maxGrepId){ + + // TEMPORARY FIX + // To erase all tables from cache(s) + // To be removed, maybe replaced by ndb.invalidate(); + { + Bank bank; + + if (bank.dropBank() != NDBT_OK){ + result = NDBT_FAILED; + break; + } + } + // END TEMPORARY FIX + + ndbout << "Performing initial restart" << endl; + if (restarter.restartAll(true) != 0) + return NDBT_FAILED; + + if (restarter.waitClusterStarted() != 0) + return NDBT_FAILED; + + ndbout << "Restoring grep " << grepId << endl; + if (grep.restore(grepId) == -1){ + return NDBT_FAILED; + } + ndbout << "Grep " << grepId << " restored" << endl; + + // Let bank verify + Bank bank; + + int wait = 0; + int yield = 1; + if (bank.performSumAccounts(wait, yield) != 0){ + ndbout << "bank.performSumAccounts FAILED" << endl; + ndbout << " grepId = " << grepId << endl << endl; + result = NDBT_FAILED; + errSumAccounts++; + } + + if (bank.performValidateAllGLs() != 0){ + ndbout << "bank.performValidateAllGLs FAILED" << endl; + ndbout << " grepId = " << grepId << endl << endl; + result = NDBT_FAILED; + errValidateGL++; + } + + grepId++; + } + + if (result != NDBT_OK){ + ndbout << "Verification of grep failed" << endl + << " errValidateGL="< -#include -#include -#include -#include - - -#define CHECK(b) if (!(b)) { \ - g_err << "ERR: "<< step->getName() \ - << " failed on line " << __LINE__ << endl; \ - result = NDBT_FAILED; \ - continue; } - - -int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ - - int records = ctx->getNumRecords(); - HugoTransactions hugoTrans(*ctx->getTab()); - if (hugoTrans.loadTable(GETNDB(step), records) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runPkUpdate(NDBT_Context* ctx, NDBT_Step* step){ - int loops = ctx->getNumLoops(); - int records = ctx->getNumRecords(); - int batchSize = ctx->getProperty("BatchSize", 1); - int i = 0; - HugoTransactions hugoTrans(*ctx->getTab()); - while (igetTab(); - pNdb->getDictionary()->dropTable(tab->getName()); - - if (restarter.restartAll(true) != 0) - return NDBT_FAILED; - - return NDBT_OK; -} - -int runRestarter(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - int loops = ctx->getNumLoops(); - NdbRestarter restarter; - int i = 0; - int lastId = 0; - - if (restarter.getNumDbNodes() < 2){ - ctx->stopTest(); - return NDBT_OK; - } - - if(restarter.waitClusterStarted(60) != 0){ - g_err << "Cluster failed to start" << endl; - return NDBT_FAILED; - } - - loops *= restarter.getNumDbNodes(); - while(iisTestStopped()){ - - int id = lastId % restarter.getNumDbNodes(); - int nodeId = restarter.getDbNodeId(id); - ndbout << "Restart node " << nodeId << endl; - if(restarter.restartOneDbNode(nodeId) != 0){ - g_err << "Failed to restartNextDbNode" << endl; - result = NDBT_FAILED; - break; - } - - if(restarter.waitClusterStarted(60) != 0){ - g_err << "Cluster failed to start" << endl; - result = NDBT_FAILED; - break; - } - - NdbSleep_SecSleep(1); - - lastId++; - i++; - } - - ctx->stopTest(); - - return result; -} - -int runCheckAllNodesStarted(NDBT_Context* ctx, NDBT_Step* step){ - NdbRestarter restarter; - - if(restarter.waitClusterStarted(1) != 0){ - g_err << "All nodes was not started " << endl; - return NDBT_FAILED; - } - - return NDBT_OK; -} - - -bool testMaster = true; -bool testSlave = false; - -int setMaster(NDBT_Context* ctx, NDBT_Step* step){ - testMaster = true; - testSlave = false; - return NDBT_OK; -} -int setMasterAsSlave(NDBT_Context* ctx, NDBT_Step* step){ - testMaster = true; - testSlave = true; - return NDBT_OK; -} -int setSlave(NDBT_Context* ctx, NDBT_Step* step){ - testMaster = false; - testSlave = true; - return NDBT_OK; -} - -int runAbort(NDBT_Context* ctx, NDBT_Step* step){ - - - NdbGrep grep(GETNDB(step)->getNodeId()+1); - NdbRestarter restarter; - - if (restarter.getNumDbNodes() < 2){ - ctx->stopTest(); - return NDBT_OK; - } - - if(restarter.waitClusterStarted(60) != 0){ - g_err << "Cluster failed to start" << endl; - return NDBT_FAILED; - } - - if (testMaster) { - if (testSlave) { - if (grep.NFMasterAsSlave(restarter) == -1){ - return NDBT_FAILED; - } - } else { - if (grep.NFMaster(restarter) == -1){ - return NDBT_FAILED; - } - } - } else { - if (grep.NFSlave(restarter) == -1){ - return NDBT_FAILED; - } - } - - return NDBT_OK; -} - -int runFail(NDBT_Context* ctx, NDBT_Step* step){ - NdbGrep grep(GETNDB(step)->getNodeId()+1); - - NdbRestarter restarter; - - if (restarter.getNumDbNodes() < 2){ - ctx->stopTest(); - return NDBT_OK; - } - - if(restarter.waitClusterStarted(60) != 0){ - g_err << "Cluster failed to start" << endl; - return NDBT_FAILED; - } - - if (testMaster) { - if (testSlave) { - if (grep.FailMasterAsSlave(restarter) == -1){ - return NDBT_FAILED; - } - } else { - if (grep.FailMaster(restarter) == -1){ - return NDBT_FAILED; - } - } - } else { - if (grep.FailSlave(restarter) == -1){ - return NDBT_FAILED; - } - } - - return NDBT_OK; -} - -int runGrepBasic(NDBT_Context* ctx, NDBT_Step* step){ - NdbGrep grep(GETNDB(step)->getNodeId()+1); - unsigned grepId = 0; - - if (grep.start() == -1){ - return NDBT_FAILED; - } - ndbout << "Started grep " << grepId << endl; - ctx->setProperty("GrepId", grepId); - - return NDBT_OK; -} - - - - -int runVerifyBasic(NDBT_Context* ctx, NDBT_Step* step){ - NdbGrep grep(GETNDB(step)->getNodeId()+1, ctx->getRemoteMgm()); - ndbout_c("no of nodes %d" ,grep.getNumDbNodes()); - int result; - if ((result = grep.verify(ctx)) == -1){ - return NDBT_FAILED; - } - return result; -} - - - -int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - - UtilTransactions utilTrans(*ctx->getTab()); - if (utilTrans.clearTable2(GETNDB(step), records) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - - -#include "../bank/Bank.hpp" - -int runCreateBank(NDBT_Context* ctx, NDBT_Step* step){ - Bank bank; - int overWriteExisting = true; - if (bank.createAndLoadBank(overWriteExisting) != NDBT_OK) - return NDBT_FAILED; - return NDBT_OK; -} - -int runBankTimer(NDBT_Context* ctx, NDBT_Step* step){ - Bank bank; - int wait = 30; // Max seconds between each "day" - int yield = 1; // Loops before bank returns - - while (ctx->isTestStopped() == false) { - bank.performIncreaseTime(wait, yield); - } - return NDBT_OK; -} - -int runBankTransactions(NDBT_Context* ctx, NDBT_Step* step){ - Bank bank; - int wait = 10; // Max ms between each transaction - int yield = 100; // Loops before bank returns - - while (ctx->isTestStopped() == false) { - bank.performTransactions(wait, yield); - } - return NDBT_OK; -} - -int runBankGL(NDBT_Context* ctx, NDBT_Step* step){ - Bank bank; - int yield = 20; // Loops before bank returns - int result = NDBT_OK; - - while (ctx->isTestStopped() == false) { - if (bank.performMakeGLs(yield) != NDBT_OK){ - ndbout << "bank.performMakeGLs FAILED" << endl; - result = NDBT_FAILED; - } - } - return NDBT_OK; -} - -int runBankSum(NDBT_Context* ctx, NDBT_Step* step){ - Bank bank; - int wait = 2000; // Max ms between each sum of accounts - int yield = 1; // Loops before bank returns - int result = NDBT_OK; - - while (ctx->isTestStopped() == false) { - if (bank.performSumAccounts(wait, yield) != NDBT_OK){ - ndbout << "bank.performSumAccounts FAILED" << endl; - result = NDBT_FAILED; - } - } - return result ; -} - -int runDropBank(NDBT_Context* ctx, NDBT_Step* step){ - Bank bank; - if (bank.dropBank() != NDBT_OK) - return NDBT_FAILED; - return NDBT_OK; -} - -int runGrepBank(NDBT_Context* ctx, NDBT_Step* step){ - int loops = ctx->getNumLoops(); - int l = 0; - int maxSleep = 30; // Max seconds between each grep - Ndb* pNdb = GETNDB(step); - NdbGrep grep(GETNDB(step)->getNodeId()+1); - unsigned minGrepId = ~0; - unsigned maxGrepId = 0; - unsigned grepId = 0; - int result = NDBT_OK; - - while (l < loops && result != NDBT_FAILED){ - - if (pNdb->waitUntilReady() != 0){ - result = NDBT_FAILED; - continue; - } - - // Sleep for a while - NdbSleep_SecSleep(maxSleep); - - // Perform grep - if (grep.start() != 0){ - ndbout << "grep.start failed" << endl; - result = NDBT_FAILED; - continue; - } - ndbout << "Started grep " << grepId << endl; - - // Remember min and max grepid - if (grepId < minGrepId) - minGrepId = grepId; - - if (grepId > maxGrepId) - maxGrepId = grepId; - - ndbout << " maxGrepId = " << maxGrepId - << ", minGrepId = " << minGrepId << endl; - ctx->setProperty("MinGrepId", minGrepId); - ctx->setProperty("MaxGrepId", maxGrepId); - - l++; - } - - ctx->stopTest(); - - return result; -} -/* -int runRestoreBankAndVerify(NDBT_Context* ctx, NDBT_Step* step){ - NdbRestarter restarter; - NdbGrep grep(GETNDB(step)->getNodeId()+1); - unsigned minGrepId = ctx->getProperty("MinGrepId"); - unsigned maxGrepId = ctx->getProperty("MaxGrepId"); - unsigned grepId = minGrepId; - int result = NDBT_OK; - int errSumAccounts = 0; - int errValidateGL = 0; - - ndbout << " maxGrepId = " << maxGrepId << endl; - ndbout << " minGrepId = " << minGrepId << endl; - - while (grepId <= maxGrepId){ - - // TEMPORARY FIX - // To erase all tables from cache(s) - // To be removed, maybe replaced by ndb.invalidate(); - { - Bank bank; - - if (bank.dropBank() != NDBT_OK){ - result = NDBT_FAILED; - break; - } - } - // END TEMPORARY FIX - - ndbout << "Performing initial restart" << endl; - if (restarter.restartAll(true) != 0) - return NDBT_FAILED; - - if (restarter.waitClusterStarted() != 0) - return NDBT_FAILED; - - ndbout << "Restoring grep " << grepId << endl; - if (grep.restore(grepId) == -1){ - return NDBT_FAILED; - } - ndbout << "Grep " << grepId << " restored" << endl; - - // Let bank verify - Bank bank; - - int wait = 0; - int yield = 1; - if (bank.performSumAccounts(wait, yield) != 0){ - ndbout << "bank.performSumAccounts FAILED" << endl; - ndbout << " grepId = " << grepId << endl << endl; - result = NDBT_FAILED; - errSumAccounts++; - } - - if (bank.performValidateAllGLs() != 0){ - ndbout << "bank.performValidateAllGLs FAILED" << endl; - ndbout << " grepId = " << grepId << endl << endl; - result = NDBT_FAILED; - errValidateGL++; - } - - grepId++; - } - - if (result != NDBT_OK){ - ndbout << "Verification of grep failed" << endl - << " errValidateGL="< -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - - -#define CHECK(b) if (!(b)) { \ - g_err << "ERR: "<< "getStep" \ - << " failed on line " << __LINE__ << endl; \ - result = NDBT_FAILED; \ - continue; } - -int main(int argc, const char** argv){ - - - const char * connectString = NULL; - const char * table = NULL; - int records = 0; - int _help = 0; - - struct getargs args[] = { - { "connectString", 'c', arg_string, &connectString, - "ConnectString", "nodeid=;host=" }, - { "tableName", 't', arg_string, &table, - "table", "Table" }, - { "records", 'r', arg_integer, &records, "Number of records", "recs"}, - { "usage", '?', arg_flag, &_help, "Print help", "" } - }; - int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; - char desc[] = - "hostname:port\n"\ - "This program will connect to the mgmsrv of a NDB cluster.\n"\ - "It will then wait for all nodes to be started, then restart node(s)\n"\ - "and wait for all to restart inbetween. It will do this \n"\ - "loop number of times\n"; - - if(getarg(args, num_args, argc, argv, &optind) || _help) { - arg_printusage(args, num_args, argv[0], desc); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - ndbout_c("table %s connectStirng %s", table, connectString); - if(connectString == 0) - return NDBT_ProgramExit(NDBT_WRONGARGS); - if(table == 0) - return NDBT_ProgramExit(NDBT_WRONGARGS); - - Ndb::useFullyQualifiedNames(false); - - Ndb * m_ndb = new Ndb(""); - m_ndb->setConnectString(connectString); - Ndb::useFullyQualifiedNames(false); - /** - * @todo Set proper max no of transactions?? needed?? Default 12?? - */ - m_ndb->init(2048); - Ndb::useFullyQualifiedNames(false); - if (m_ndb->waitUntilReady() != 0){ - ndbout_c("NDB Cluster not ready for connections"); - } - - int count = 0; - int result = NDBT_OK; - - - const NdbDictionary::Table * tab = NDBT_Table::discoverTableFromDb( m_ndb, table); -// ndbout << *tab << endl; - - UtilTransactions utilTrans(*tab); - HugoTransactions hugoTrans(*tab); - - do{ - - // Check that there are as many records as we expected - CHECK(utilTrans.selectCount(m_ndb, 64, &count) == 0); - - g_err << "count = " << count; - g_err << " records = " << records; - g_err << endl; - - CHECK(count == records); - - // Read and verify every record - CHECK(hugoTrans.pkReadRecords(m_ndb, records) == 0); - - } while (false); - - - return NDBT_ProgramExit(result); - -} diff --git a/ndb/test/ndbapi/testGrepVerify.cpp b/ndb/test/ndbapi/testGrepVerify.cpp new file mode 100644 index 00000000000..7fd2c19d9f7 --- /dev/null +++ b/ndb/test/ndbapi/testGrepVerify.cpp @@ -0,0 +1,120 @@ +/* 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 */ + + +#include "mgmapi.h" +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + + +#define CHECK(b) if (!(b)) { \ + g_err << "ERR: "<< "getStep" \ + << " failed on line " << __LINE__ << endl; \ + result = NDBT_FAILED; \ + continue; } + +int main(int argc, const char** argv){ + + + const char * connectString = NULL; + const char * table = NULL; + int records = 0; + int _help = 0; + + struct getargs args[] = { + { "connectString", 'c', arg_string, &connectString, + "ConnectString", "nodeid=;host=" }, + { "tableName", 't', arg_string, &table, + "table", "Table" }, + { "records", 'r', arg_integer, &records, "Number of records", "recs"}, + { "usage", '?', arg_flag, &_help, "Print help", "" } + }; + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + char desc[] = + "hostname:port\n"\ + "This program will connect to the mgmsrv of a NDB cluster.\n"\ + "It will then wait for all nodes to be started, then restart node(s)\n"\ + "and wait for all to restart inbetween. It will do this \n"\ + "loop number of times\n"; + + if(getarg(args, num_args, argc, argv, &optind) || _help) { + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + ndbout_c("table %s connectStirng %s", table, connectString); + if(connectString == 0) + return NDBT_ProgramExit(NDBT_WRONGARGS); + if(table == 0) + return NDBT_ProgramExit(NDBT_WRONGARGS); + + Ndb::useFullyQualifiedNames(false); + + Ndb * m_ndb = new Ndb(""); + m_ndb->setConnectString(connectString); + Ndb::useFullyQualifiedNames(false); + /** + * @todo Set proper max no of transactions?? needed?? Default 12?? + */ + m_ndb->init(2048); + Ndb::useFullyQualifiedNames(false); + if (m_ndb->waitUntilReady() != 0){ + ndbout_c("NDB Cluster not ready for connections"); + } + + int count = 0; + int result = NDBT_OK; + + + const NdbDictionary::Table * tab = NDBT_Table::discoverTableFromDb( m_ndb, table); +// ndbout << *tab << endl; + + UtilTransactions utilTrans(*tab); + HugoTransactions hugoTrans(*tab); + + do{ + + // Check that there are as many records as we expected + CHECK(utilTrans.selectCount(m_ndb, 64, &count) == 0); + + g_err << "count = " << count; + g_err << " records = " << records; + g_err << endl; + + CHECK(count == records); + + // Read and verify every record + CHECK(hugoTrans.pkReadRecords(m_ndb, records) == 0); + + } while (false); + + + return NDBT_ProgramExit(result); + +} diff --git a/ndb/test/ndbapi/testIndex.cpp b/ndb/test/ndbapi/testIndex.cpp new file mode 100644 index 00000000000..47db0b3cff7 --- /dev/null +++ b/ndb/test/ndbapi/testIndex.cpp @@ -0,0 +1,1495 @@ +/* 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 */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define CHECK(b) if (!(b)) { \ + g_err << "ERR: "<< step->getName() \ + << " failed on line " << __LINE__ << endl; \ + result = NDBT_FAILED; \ +} + + +struct Attrib { + bool indexCreated; + int numAttribs; + int attribs[1024]; + Attrib(){ + numAttribs = 0; + indexCreated = false; + } +}; +class AttribList { +public: + AttribList(){}; + ~AttribList(){ + for(size_t i = 0; i < attriblist.size(); i++){ + delete attriblist[i]; + } + }; + void buildAttribList(const NdbDictionary::Table* pTab); + Vector attriblist; +}; + +void AttribList::buildAttribList(const NdbDictionary::Table* pTab){ + attriblist.clear(); + + Attrib* attr; + // Build attrib definitions that describes which attributes to build index + // Try to build strange combinations, not just "all" or all PK's + + for(int i = 1; i <= pTab->getNoOfColumns(); i++){ + attr = new Attrib; + attr->numAttribs = i; + for(int a = 0; aattribs[a] = a; + attriblist.push_back(attr); + } + int b = 0; + for(int i = pTab->getNoOfColumns()-1; i > 0; i--){ + attr = new Attrib; + attr->numAttribs = i; + b++; + for(int a = 0; aattribs[a] = a+b; + attriblist.push_back(attr); + } + for(int i = pTab->getNoOfColumns(); i > 0; i--){ + attr = new Attrib; + attr->numAttribs = pTab->getNoOfColumns() - i; + for(int a = 0; agetNoOfColumns() - i; a++) + attr->attribs[a] = pTab->getNoOfColumns()-a-1; + attriblist.push_back(attr); + } + for(int i = 1; i < pTab->getNoOfColumns(); i++){ + attr = new Attrib; + attr->numAttribs = pTab->getNoOfColumns() - i; + for(int a = 0; agetNoOfColumns() - i; a++) + attr->attribs[a] = pTab->getNoOfColumns()-a-1; + attriblist.push_back(attr); + } + for(int i = 1; i < pTab->getNoOfColumns(); i++){ + attr = new Attrib; + attr->numAttribs = 2; + for(int a = 0; a<2; a++){ + attr->attribs[a] = i%pTab->getNoOfColumns(); + } + attriblist.push_back(attr); + } + + // Last + attr = new Attrib; + attr->numAttribs = 1; + attr->attribs[0] = pTab->getNoOfColumns()-1; + attriblist.push_back(attr); + + // Last and first + attr = new Attrib; + attr->numAttribs = 2; + attr->attribs[0] = pTab->getNoOfColumns()-1; + attr->attribs[1] = 0; + attriblist.push_back(attr); + + // First and last + attr = new Attrib; + attr->numAttribs = 2; + attr->attribs[0] = 0; + attr->attribs[1] = pTab->getNoOfColumns()-1; + attriblist.push_back(attr); + +#if 0 + for(size_t i = 0; i < attriblist.size(); i++){ + + ndbout << attriblist[i]->numAttribs << ": " ; + for(int a = 0; a < attriblist[i]->numAttribs; a++) + ndbout << attriblist[i]->attribs[a] << ", "; + ndbout << endl; + } +#endif + +} + +char idxName[255]; +char pkIdxName[255]; + +static const int SKIP_INDEX = 99; + +int create_index(NDBT_Context* ctx, int indxNum, + const NdbDictionary::Table* pTab, + Ndb* pNdb, Attrib* attr, bool logged){ + bool orderedIndex = ctx->getProperty("OrderedIndex", (unsigned)0); + int result = NDBT_OK; + + HugoCalculator calc(*pTab); + + if (attr->numAttribs == 1 && + calc.isUpdateCol(attr->attribs[0]) == true){ + // Don't create index for the Hugo update column + // since it's not unique + return SKIP_INDEX; + } + + // Create index + snprintf(idxName, 255, "IDC%d", indxNum); + if (orderedIndex) + ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "ordered index "<getName()); + if (orderedIndex) + pIdx.setType(NdbDictionary::Index::OrderedIndex); + else + pIdx.setType(NdbDictionary::Index::UniqueHashIndex); + for (int c = 0; c< attr->numAttribs; c++){ + int attrNo = attr->attribs[c]; + pIdx.addIndexColumn(pTab->getColumn(attrNo)->getName()); + ndbout << pTab->getColumn(attrNo)->getName()<<" "; + } + + pIdx.setStoredIndex(logged); + ndbout << ") "; + if (pNdb->getDictionary()->createIndex(pIdx) != 0){ + attr->indexCreated = false; + ndbout << "FAILED!" << endl; + const NdbError err = pNdb->getDictionary()->getNdbError(); + ERR(err); + if(err.classification == NdbError::ApplicationError) + return SKIP_INDEX; + + return NDBT_FAILED; + } else { + ndbout << "OK!" << endl; + attr->indexCreated = true; + } + return result; +} + + +int drop_index(int indxNum, Ndb* pNdb, + const NdbDictionary::Table* pTab, Attrib* attr){ + int result = NDBT_OK; + + if (attr->indexCreated == false) + return NDBT_OK; + + snprintf(idxName, 255, "IDC%d", indxNum); + + // Drop index + ndbout << "Dropping index "<getName() << ") "; + if (pNdb->getDictionary()->dropIndex(idxName, pTab->getName()) != 0){ + ndbout << "FAILED!" << endl; + ERR(pNdb->getDictionary()->getNdbError()); + result = NDBT_FAILED; + } else { + ndbout << "OK!" << endl; + } + return result; +} + +int runCreateIndexes(NDBT_Context* ctx, NDBT_Step* step){ + int loops = ctx->getNumLoops(); + int l = 0; + const NdbDictionary::Table* pTab = ctx->getTab(); + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; + // NOTE If we need to test creating both logged and non logged indexes + // this should be divided into two testcases + // The paramater logged should then be specified + // as a TC_PROPERTY. ex TC_PROPERTY("LoggedIndexes", 1); + // and read into the test step like + bool logged = ctx->getProperty("LoggedIndexes", 1); + + AttribList attrList; + attrList.buildAttribList(pTab); + + + while (l < loops && result == NDBT_OK){ + + for (unsigned int i = 0; i < attrList.attriblist.size(); i++){ + + // Try to create index + if (create_index(ctx, i, pTab, pNdb, attrList.attriblist[i], logged) == NDBT_FAILED) + result = NDBT_FAILED; + } + + // Now drop all indexes that where created + for (unsigned int i = 0; i < attrList.attriblist.size(); i++){ + + // Try to drop index + if (drop_index(i, pNdb, pTab, attrList.attriblist[i]) != NDBT_OK) + result = NDBT_FAILED; + } + + l++; + } + + return result; +} + +int createRandomIndex(NDBT_Context* ctx, NDBT_Step* step){ + const NdbDictionary::Table* pTab = ctx->getTab(); + Ndb* pNdb = GETNDB(step); + bool logged = ctx->getProperty("LoggedIndexes", 1); + + AttribList attrList; + attrList.buildAttribList(pTab); + + int retries = 100; + while(retries > 0){ + const Uint32 i = rand() % attrList.attriblist.size(); + int res = create_index(ctx, i, pTab, pNdb, attrList.attriblist[i], + logged); + if (res == SKIP_INDEX){ + retries--; + continue; + } + + if (res == NDBT_FAILED){ + return NDBT_FAILED; + } + + ctx->setProperty("createRandomIndex", i); + // Now drop all indexes that where created + + return NDBT_OK; + } + + return NDBT_FAILED; +} + +int createRandomIndex_Drop(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + + Uint32 i = ctx->getProperty("createRandomIndex"); + + snprintf(idxName, 255, "IDC%d", i); + + // Drop index + ndbout << "Dropping index " << idxName << " "; + if (pNdb->getDictionary()->dropIndex(idxName, + ctx->getTab()->getName()) != 0){ + ndbout << "FAILED!" << endl; + ERR(pNdb->getDictionary()->getNdbError()); + return NDBT_FAILED; + } else { + ndbout << "OK!" << endl; + } + + return NDBT_OK; +} + +int createPkIndex(NDBT_Context* ctx, NDBT_Step* step){ + bool orderedIndex = ctx->getProperty("OrderedIndex", (unsigned)0); + + const NdbDictionary::Table* pTab = ctx->getTab(); + Ndb* pNdb = GETNDB(step); + + bool logged = ctx->getProperty("LoggedIndexes", 1); + + // Create index + snprintf(pkIdxName, 255, "IDC_PK_%s", pTab->getName()); + if (orderedIndex) + ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "ordered index " + << pkIdxName << " ("; + else + ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "unique index " + << pkIdxName << " ("; + + NdbDictionary::Index pIdx(pkIdxName); + pIdx.setTable(pTab->getName()); + if (orderedIndex) + pIdx.setType(NdbDictionary::Index::OrderedIndex); + else + pIdx.setType(NdbDictionary::Index::UniqueHashIndex); + for (int c = 0; c< pTab->getNoOfColumns(); c++){ + const NdbDictionary::Column * col = pTab->getColumn(c); + if(col->getPrimaryKey()){ + pIdx.addIndexColumn(col->getName()); + ndbout << col->getName() <<" "; + } + } + + pIdx.setStoredIndex(logged); + ndbout << ") "; + if (pNdb->getDictionary()->createIndex(pIdx) != 0){ + ndbout << "FAILED!" << endl; + const NdbError err = pNdb->getDictionary()->getNdbError(); + ERR(err); + return NDBT_FAILED; + } + + ndbout << "OK!" << endl; + return NDBT_OK; +} + +int createPkIndex_Drop(NDBT_Context* ctx, NDBT_Step* step){ + const NdbDictionary::Table* pTab = ctx->getTab(); + Ndb* pNdb = GETNDB(step); + + // Drop index + ndbout << "Dropping index " << pkIdxName << " "; + if (pNdb->getDictionary()->dropIndex(pkIdxName, + pTab->getName()) != 0){ + ndbout << "FAILED!" << endl; + ERR(pNdb->getDictionary()->getNdbError()); + return NDBT_FAILED; + } else { + ndbout << "OK!" << endl; + } + + return NDBT_OK; +} + +int +runVerifyIndex(NDBT_Context* ctx, NDBT_Step* step){ + // Verify that data in index match + // table data + Ndb* pNdb = GETNDB(step); + UtilTransactions utilTrans(*ctx->getTab()); + const int batchSize = ctx->getProperty("BatchSize", 16); + const int parallelism = batchSize > 240 ? 240 : batchSize; + + do { + if (utilTrans.verifyIndex(pNdb, idxName, parallelism, true) != 0){ + g_err << "Inconsistent index" << endl; + return NDBT_FAILED; + } + } while(ctx->isTestStopped() == false); + return NDBT_OK; +} + +int +runTransactions1(NDBT_Context* ctx, NDBT_Step* step){ + // Verify that data in index match + // table data + Ndb* pNdb = GETNDB(step); + HugoTransactions hugoTrans(*ctx->getTab()); + const int batchSize = ctx->getProperty("BatchSize", 50); + + int rows = ctx->getNumRecords(); + while (ctx->isTestStopped() == false) { + if (hugoTrans.pkUpdateRecords(pNdb, rows, batchSize) != 0){ + g_err << "Updated table failed" << endl; + return NDBT_FAILED; + } + if (hugoTrans.scanUpdateRecords(pNdb, rows, batchSize) != 0){ + g_err << "Updated table failed" << endl; + return NDBT_FAILED; + } + } + return NDBT_OK; +} + +int +runTransactions2(NDBT_Context* ctx, NDBT_Step* step){ + // Verify that data in index match + // table data + Ndb* pNdb = GETNDB(step); + HugoTransactions hugoTrans(*ctx->getTab()); + const int batchSize = ctx->getProperty("BatchSize", 50); + + int rows = ctx->getNumRecords(); + while (ctx->isTestStopped() == false) { +#if 1 + if (hugoTrans.indexReadRecords(pNdb, pkIdxName, rows, batchSize) != 0){ + g_err << "Index read failed" << endl; + return NDBT_FAILED; + } +#endif + + if(ctx->isTestStopped()) + break; +#if 1 + if (hugoTrans.indexUpdateRecords(pNdb, pkIdxName, rows, batchSize) != 0){ + g_err << "Index update failed" << endl; + return NDBT_FAILED; + } +#endif + } + return NDBT_OK; +} + +int +runTransactions3(NDBT_Context* ctx, NDBT_Step* step){ + // Verify that data in index match + // table data + Ndb* pNdb = GETNDB(step); + HugoTransactions hugoTrans(*ctx->getTab()); + UtilTransactions utilTrans(*ctx->getTab()); + const int batchSize = ctx->getProperty("BatchSize", 32); + const int parallel = batchSize > 240 ? 240 : batchSize; + + int rows = ctx->getNumRecords(); + while (ctx->isTestStopped() == false) { + if(hugoTrans.loadTable(pNdb, rows, batchSize, false) != 0){ + g_err << "Load table failed" << endl; + return NDBT_FAILED; + } + if(ctx->isTestStopped()) + break; + + if (hugoTrans.pkUpdateRecords(pNdb, rows, batchSize) != 0){ + g_err << "Updated table failed" << endl; + return NDBT_FAILED; + } + + if(ctx->isTestStopped()) + break; + + if (hugoTrans.indexReadRecords(pNdb, pkIdxName, rows, batchSize) != 0){ + g_err << "Index read failed" << endl; + return NDBT_FAILED; + } + + if(ctx->isTestStopped()) + break; + + if (hugoTrans.indexUpdateRecords(pNdb, pkIdxName, rows, batchSize) != 0){ + g_err << "Index update failed" << endl; + return NDBT_FAILED; + } + + if(ctx->isTestStopped()) + break; + + if (hugoTrans.scanUpdateRecords(pNdb, rows, 5, parallel) != 0){ + g_err << "Scan updated table failed" << endl; + return NDBT_FAILED; + } + + if(ctx->isTestStopped()) + break; + + if(utilTrans.clearTable(pNdb, rows, parallel) != 0){ + g_err << "Clear table failed" << endl; + return NDBT_FAILED; + } + if(ctx->isTestStopped()) + break; + + int count = -1; + if(utilTrans.selectCount(pNdb, 64, &count) != 0 || count != 0) + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runRestarts(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int loops = ctx->getNumLoops(); + NDBT_TestCase* pCase = ctx->getCase(); + NdbRestarts restarts; + int i = 0; + int timeout = 240; + + while(iisTestStopped()){ + if(restarts.executeRestart("RestartRandomNodeAbort", timeout) != 0){ + g_err << "Failed to executeRestart(" <getName() <<")" << endl; + result = NDBT_FAILED; + break; + } + i++; + } + ctx->stopTest(); + return result; +} + +int runCreateLoadDropIndex(NDBT_Context* ctx, NDBT_Step* step){ + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + int l = 0; + const NdbDictionary::Table* pTab = ctx->getTab(); + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; + int batchSize = ctx->getProperty("BatchSize", 1); + int parallelism = batchSize > 240? 240: batchSize; + ndbout << "batchSize="<getProperty("LoggedIndexes", 1); + + HugoTransactions hugoTrans(*pTab); + UtilTransactions utilTrans(*pTab); + AttribList attrList; + attrList.buildAttribList(pTab); + + for (unsigned int i = 0; i < attrList.attriblist.size(); i++){ + + while (l < loops && result == NDBT_OK){ + + if ((l % 2) == 0){ + // Create index first and then load + + // Try to create index + if (create_index(ctx, i, pTab, pNdb, attrList.attriblist[i], logged) == NDBT_FAILED){ + result = NDBT_FAILED; + } + + // Load the table with data + ndbout << "Loading data after" << endl; + CHECK(hugoTrans.loadTable(pNdb, records, batchSize) == 0); + + + } else { + // Load table then create index + + // Load the table with data + ndbout << "Loading data before" << endl; + CHECK(hugoTrans.loadTable(pNdb, records, batchSize) == 0); + + // Try to create index + if (create_index(ctx, i, pTab, pNdb, attrList.attriblist[i], logged) == NDBT_FAILED) + result = NDBT_FAILED; + + } + + // Verify that data in index match + // table data + CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0); + + // Do it all... + ndbout <<"Doing it all"<getNumLoops(); + int records = ctx->getNumRecords(); + const NdbDictionary::Table* pTab = ctx->getTab(); + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; + int batchSize = ctx->getProperty("BatchSize", 1); + int parallelism = batchSize > 240? 240: batchSize; + ndbout << "batchSize="<getProperty("LoggedIndexes", 1); + + HugoTransactions hugoTrans(*pTab); + UtilTransactions utilTrans(*pTab); + + AttribList attrList; + attrList.buildAttribList(pTab); + + for (unsigned int i = 0; i < attrList.attriblist.size(); i++){ + + Attrib* attr = attrList.attriblist[i]; + // Create index + if (create_index(ctx, i, pTab, pNdb, attr, logged) == NDBT_OK){ + int l = 1; + while (l <= loops && result == NDBT_OK){ + + CHECK(hugoTrans.loadTable(pNdb, records, batchSize) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0); + CHECK(utilTrans.clearTable(pNdb, records, parallelism) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0); + l++; + } + + // Drop index + if (drop_index(i, pNdb, pTab, attr) != NDBT_OK) + result = NDBT_FAILED; + } + } + + return result; +} +int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + + HugoTransactions hugoTrans(*ctx->getTab()); + int batchSize = ctx->getProperty("BatchSize", 1); + if(hugoTrans.loadTable(GETNDB(step), records, batchSize) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + + +int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + + UtilTransactions utilTrans(*ctx->getTab()); + if (utilTrans.clearTable(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runSystemRestart1(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; + int timeout = 300; + Uint32 loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + int count; + NdbRestarter restarter; + Uint32 i = 1; + + UtilTransactions utilTrans(*ctx->getTab()); + HugoTransactions hugoTrans(*ctx->getTab()); + const char * name = ctx->getTab()->getName(); + while(i<=loops && result != NDBT_FAILED){ + + ndbout << "Loop " << i << "/"<< loops <<" started" << endl; + /* + 1. Load data + 2. Restart cluster and verify records + 3. Update records + 4. Restart cluster and verify records + 5. Delete half of the records + 6. Restart cluster and verify records + 7. Delete all records + 8. Restart cluster and verify records + 9. Insert, update, delete records + 10. Restart cluster and verify records + 11. Insert, update, delete records + 12. Restart cluster with error insert 5020 and verify records + */ + ndbout << "Loading records..." << endl; + CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + + ndbout << "Restarting cluster" << endl; + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(pNdb->waitUntilReady(timeout) == 0); + + ndbout << "Verifying records..." << endl; + CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == records); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + + ndbout << "Updating records..." << endl; + CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + + ndbout << "Restarting cluster..." << endl; + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(pNdb->waitUntilReady(timeout) == 0); + + ndbout << "Verifying records..." << endl; + CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == records); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + + ndbout << "Deleting 50% of records..." << endl; + CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + + ndbout << "Restarting cluster..." << endl; + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(pNdb->waitUntilReady(timeout) == 0); + + ndbout << "Verifying records..." << endl; + CHECK(hugoTrans.scanReadRecords(pNdb, records/2, 0, 64) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == (records/2)); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + + ndbout << "Deleting all records..." << endl; + CHECK(utilTrans.clearTable(pNdb, records/2) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + + ndbout << "Restarting cluster..." << endl; + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(pNdb->waitUntilReady(timeout) == 0); + + ndbout << "Verifying records..." << endl; + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + + ndbout << "Doing it all..." << endl; + CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); + CHECK(hugoTrans.scanUpdateRecords(pNdb, records) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + CHECK(utilTrans.clearTable(pNdb, records) == 0); + CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0); + CHECK(utilTrans.clearTable(pNdb, records) == 0); + CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0); + CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); + CHECK(utilTrans.clearTable(pNdb, records) == 0); + + ndbout << "Restarting cluster..." << endl; + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(pNdb->waitUntilReady(timeout) == 0); + + ndbout << "Verifying records..." << endl; + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == 0); + + ndbout << "Doing it all..." << endl; + CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + CHECK(hugoTrans.scanUpdateRecords(pNdb, records) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + CHECK(utilTrans.clearTable(pNdb, records) == 0); + CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0); + CHECK(utilTrans.clearTable(pNdb, records) == 0); + + ndbout << "Restarting cluster with error insert 5020..." << endl; + CHECK(restarter.restartAll(false, true) == 0); + CHECK(restarter.waitClusterNoStart(timeout) == 0); + CHECK(restarter.insertErrorInAllNodes(5020) == 0); + CHECK(restarter.startAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(pNdb->waitUntilReady(timeout) == 0); + + i++; + } + + ctx->stopTest(); + ndbout << "runSystemRestart1 finished" << endl; + + return result; +} + +#define CHECK2(b, t) if(!b){ g_err << __LINE__ << ": " << t << endl; break;} + +int +runMixed1(NDBT_Context* ctx, NDBT_Step* step){ + // Verify that data in index match + // table data + Ndb* pNdb = GETNDB(step); + HugoOperations hugoOps(*ctx->getTab()); + + + do { + // TC1 + g_err << "pkRead, indexRead, Commit" << endl; + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction"); + CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0) == 0, "indexReadRecords"); + CHECK2(hugoOps.pkReadRecord(pNdb, 0) == 0, "pkReadRecord"); + CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit"); + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction"); + + // TC1 + g_err << "pkRead, indexRead, Commit" << endl; + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction"); + CHECK2(hugoOps.pkReadRecord(pNdb, 0) == 0, "pkReadRecord"); + CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0) == 0, "indexReadRecords"); + CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit"); + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction"); + + + // TC2 + g_err << "pkRead, indexRead, NoCommit, Commit" << endl; + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction"); + CHECK2(hugoOps.pkReadRecord(pNdb, 0) == 0, "pkReadRecord"); + CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0) == 0, + "indexReadRecords"); + CHECK2(hugoOps.execute_NoCommit(pNdb) == 0, "executeNoCommit"); + CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit"); + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction"); + + // TC3 + g_err << "pkRead, pkRead, Commit" << endl; + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction "); + CHECK2(hugoOps.pkReadRecord(pNdb, 0) == 0, "pkReadRecords "); + CHECK2(hugoOps.pkReadRecord(pNdb, 0) == 0, "pkReadRecords "); + CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit"); + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction "); + + // TC4 + g_err << "indexRead, indexRead, Commit" << endl; + + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction "); + CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0) == 0, "indexReadRecords"); + CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0) == 0, "indexReadRecords"); + CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit"); + + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction "); + + return NDBT_OK; + } while(false); + + + hugoOps.closeTransaction(pNdb); + return NDBT_FAILED; +} + +int +runBuildDuring(NDBT_Context* ctx, NDBT_Step* step){ + // Verify that data in index match + // table data + const int Threads = ctx->getProperty("Threads", (Uint32)0); + const int loops = ctx->getNumLoops(); + + for(int i = 0; iisTestStopped()) + break; + +#if 1 + if(createRandomIndex(ctx, step) != NDBT_OK){ + g_err << "Failed to create index" << endl; + return NDBT_FAILED; + } +#endif + + if(ctx->isTestStopped()) + break; + + ctx->setProperty("pause", 1); + int count = 0; + for(int j = 0; count < Threads && !ctx->isTestStopped(); + j = (j+1) % Threads){ + char buf[255]; + sprintf(buf, "Thread%d_paused", j); + int tmp = ctx->getProperty(buf, (Uint32)0); + count += tmp; + } + + if(ctx->isTestStopped()) + break; + +#if 1 + if(createPkIndex_Drop(ctx, step) != NDBT_OK){ + g_err << "Failed to drop index" << endl; + return NDBT_FAILED; + } +#endif + + if(ctx->isTestStopped()) + break; + +#if 1 + if(createRandomIndex_Drop(ctx, step) != NDBT_OK){ + g_err << "Failed to drop index" << endl; + return NDBT_FAILED; + } +#endif + + ctx->setProperty("pause", (Uint32)0); + NdbSleep_SecSleep(2); + } + + ctx->stopTest(); + return NDBT_OK; +} + +static NdbLockable g_lock; +static int threadCounter = 0; + +void +wait_paused(NDBT_Context* ctx, int id){ + if(ctx->getProperty("pause", (Uint32)0) == 1){ + char buf[255]; + sprintf(buf, "Thread%d_paused", id); + ctx->setProperty(buf, 1); + while(!ctx->isTestStopped() && ctx->getProperty("pause", (Uint32)0) == 1){ + NdbSleep_MilliSleep(250); + } + ctx->setProperty(buf, (Uint32)0); + } +} + +int +runTransactions4(NDBT_Context* ctx, NDBT_Step* step){ + + g_lock.lock(); + const int ThreadId = threadCounter++; + g_lock.unlock(); + + // Verify that data in index match + // table data + Ndb* pNdb = GETNDB(step); + HugoTransactions hugoTrans(*ctx->getTab()); + UtilTransactions utilTrans(*ctx->getTab()); + const int batchSize = ctx->getProperty("BatchSize", 32); + const int parallel = batchSize > 240 ? 240 : batchSize; + + int rows = ctx->getNumRecords(); + while (ctx->isTestStopped() == false) { + if(hugoTrans.loadTable(pNdb, rows, batchSize, false) != 0){ + g_err << "Load table failed" << endl; + return NDBT_FAILED; + } + + wait_paused(ctx, ThreadId); + + if(ctx->isTestStopped()) + break; + + if (hugoTrans.pkUpdateRecords(pNdb, rows, batchSize) != 0){ + g_err << "Updated table failed" << endl; + return NDBT_FAILED; + } + + wait_paused(ctx, ThreadId); + + if(ctx->isTestStopped()) + break; + + if (hugoTrans.scanUpdateRecords(pNdb, rows, 5, parallel) != 0){ + g_err << "Scan updated table failed" << endl; + return NDBT_FAILED; + } + + wait_paused(ctx, ThreadId); + + if(ctx->isTestStopped()) + break; + + if(utilTrans.clearTable(pNdb, rows, parallel) != 0){ + g_err << "Clear table failed" << endl; + return NDBT_FAILED; + } + } + return NDBT_OK; +} + +int +runUniqueNullTransactions(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + + bool logged = ctx->getProperty("LoggedIndexes", 1); + bool orderedIndex = ctx->getProperty("OrderedIndex", (unsigned)0); + NdbConnection * pTrans = 0; + + const NdbDictionary::Table* pTab = ctx->getTab(); + // Create index + char nullIndex[255]; + snprintf(nullIndex, 255, "IDC_PK_%s_NULL", pTab->getName()); + if (orderedIndex) + ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "ordered index " + << pkIdxName << " ("; + else + ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "unique index " + << pkIdxName << " ("; + + NdbDictionary::Index pIdx(pkIdxName); + pIdx.setTable(pTab->getName()); + if (orderedIndex) + pIdx.setType(NdbDictionary::Index::OrderedIndex); + else + pIdx.setType(NdbDictionary::Index::UniqueHashIndex); + pIdx.setStoredIndex(logged); + + for (int c = 0; c< pTab->getNoOfColumns(); c++){ + const NdbDictionary::Column * col = pTab->getColumn(c); + if(col->getPrimaryKey()){ + pIdx.addIndexColumn(col->getName()); + ndbout << col->getName() <<" "; + } + } + + int colId = -1; + for (int c = 0; c< pTab->getNoOfColumns(); c++){ + const NdbDictionary::Column * col = pTab->getColumn(c); + if(col->getNullable()){ + pIdx.addIndexColumn(col->getName()); + ndbout << col->getName() <<" "; + colId = c; + break; + } + } + ndbout << ") "; + + if(colId == -1){ + ndbout << endl << "No nullable column found -> NDBT_FAILED" << endl; + return NDBT_FAILED; + } + + if (pNdb->getDictionary()->createIndex(pIdx) != 0){ + ndbout << "FAILED!" << endl; + const NdbError err = pNdb->getDictionary()->getNdbError(); + ERR(err); + return NDBT_FAILED; + } + + int result = NDBT_OK; + + HugoTransactions hugoTrans(*ctx->getTab()); + const int batchSize = ctx->getProperty("BatchSize", 50); + int loops = ctx->getNumLoops(); + int rows = ctx->getNumRecords(); + while (loops-- > 0 && ctx->isTestStopped() == false) { + if (hugoTrans.pkUpdateRecords(pNdb, rows, batchSize) != 0){ + g_err << "Updated table failed" << endl; + result = NDBT_FAILED; + goto done; + } + } + + if(ctx->isTestStopped()){ + goto done; + } + + ctx->stopTest(); + while(ctx->getNoOfRunningSteps() > 1){ + NdbSleep_MilliSleep(100); + } + + result = NDBT_FAILED; + pTrans = pNdb->startTransaction(); + NdbScanOperation * sOp; + NdbOperation * uOp; + NdbResultSet * rs; + int eof; + if(!pTrans) goto done; + sOp = pTrans->getNdbScanOperation(pTab->getName()); + if(!sOp) goto done; + rs = sOp->readTuples(240, NdbScanOperation::LM_Exclusive); + if(!rs) goto done; + if(pTrans->execute(NoCommit) == -1) goto done; + while((eof = rs->nextResult(true)) == 0){ + do { + NdbOperation * uOp = rs->updateTuple(); + if(uOp == 0) goto done; + uOp->setValue(colId, 0); + } while((eof = rs->nextResult(false)) == 0); + eof = pTrans->execute(Commit); + if(eof == -1) goto done; + } + + done: + if(pTrans) pNdb->closeTransaction(pTrans); + pNdb->getDictionary()->dropIndex(nullIndex, pTab->getName()); + return result; +} + +int runLQHKEYREF(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int loops = ctx->getNumLoops() * 100; + NdbRestarter restarter; + + myRandom48Init(NdbTick_CurrentMillisecond()); + +#if 0 + int val = DumpStateOrd::DihMinTimeBetweenLCP; + if(restarter.dumpStateAllNodes(&val, 1) != 0){ + g_err << "Failed to dump DihMinTimeBetweenLCP" << endl; + return NDBT_FAILED; + } +#endif + + for(int i = 0; iisTestStopped(); i++){ + int randomId = myRandom48(restarter.getNumDbNodes()); + int nodeId = restarter.getDbNodeId(randomId); + + const Uint32 error = 5031 + (i % 3); + + if(restarter.insertErrorInNode(nodeId, error) != 0){ + g_err << "Failed to error insert( " << error << ") in node " + << nodeId << endl; + return NDBT_FAILED; + } + } + + ctx->stopTest(); + return NDBT_OK; +} + +NDBT_TESTSUITE(testIndex); +TESTCASE("CreateAll", + "Test that we can create all various indexes on each table\n" + "Then drop the indexes\n"){ + INITIALIZER(runCreateIndexes); +} +TESTCASE("CreateAll_O", + "Test that we can create all various indexes on each table\n" + "Then drop the indexes\n"){ + TC_PROPERTY("OrderedIndex", 1); + TC_PROPERTY("LoggedIndexes", (unsigned)0); + INITIALIZER(runCreateIndexes); +} +TESTCASE("InsertDeleteGentle", + "Create one index, then perform insert and delete in the table\n" + "loop number of times. Use batch size 1."){ + TC_PROPERTY("BatchSize", 1); + INITIALIZER(runInsertDelete); + FINALIZER(runClearTable); +} +TESTCASE("InsertDeleteGentle_O", + "Create one index, then perform insert and delete in the table\n" + "loop number of times. Use batch size 1."){ + TC_PROPERTY("OrderedIndex", 1); + TC_PROPERTY("LoggedIndexes", (unsigned)0); + TC_PROPERTY("BatchSize", 1); + INITIALIZER(runInsertDelete); + FINALIZER(runClearTable); +} +TESTCASE("InsertDelete", + "Create one index, then perform insert and delete in the table\n" + "loop number of times. Use batchsize 512 to stress db more"){ + TC_PROPERTY("BatchSize", 512); + INITIALIZER(runInsertDelete); + FINALIZER(runClearTable); + +} +TESTCASE("InsertDelete_O", + "Create one index, then perform insert and delete in the table\n" + "loop number of times. Use batchsize 512 to stress db more"){ + TC_PROPERTY("OrderedIndex", 1); + TC_PROPERTY("LoggedIndexes", (unsigned)0); + TC_PROPERTY("BatchSize", 512); + INITIALIZER(runInsertDelete); + FINALIZER(runClearTable); + +} +TESTCASE("CreateLoadDropGentle", + "Try to create, drop and load various indexes \n" + "on table loop number of times.Usa batch size 1.\n"){ + TC_PROPERTY("BatchSize", 1); + INITIALIZER(runCreateLoadDropIndex); +} +TESTCASE("CreateLoadDropGentle_O", + "Try to create, drop and load various indexes \n" + "on table loop number of times.Usa batch size 1.\n"){ + TC_PROPERTY("OrderedIndex", 1); + TC_PROPERTY("LoggedIndexes", (unsigned)0); + TC_PROPERTY("BatchSize", 1); + INITIALIZER(runCreateLoadDropIndex); +} +TESTCASE("CreateLoadDrop", + "Try to create, drop and load various indexes \n" + "on table loop number of times. Use batchsize 512 to stress db more\n"){ + TC_PROPERTY("BatchSize", 512); + INITIALIZER(runCreateLoadDropIndex); +} +TESTCASE("CreateLoadDrop_O", + "Try to create, drop and load various indexes \n" + "on table loop number of times. Use batchsize 512 to stress db more\n"){ + TC_PROPERTY("OrderedIndex", 1); + TC_PROPERTY("LoggedIndexes", (unsigned)0); + TC_PROPERTY("BatchSize", 512); + INITIALIZER(runCreateLoadDropIndex); +} +TESTCASE("NFNR1", + "Test that indexes are correctly maintained during node fail and node restart"){ + TC_PROPERTY("LoggedIndexes", (unsigned)0); + INITIALIZER(runClearTable); + INITIALIZER(createRandomIndex); + INITIALIZER(runLoadTable); + STEP(runRestarts); + STEP(runTransactions1); + STEP(runTransactions1); + FINALIZER(runVerifyIndex); + FINALIZER(createRandomIndex_Drop); + FINALIZER(runClearTable); +} +TESTCASE("NFNR1_O", + "Test that indexes are correctly maintained during node fail and node restart"){ + TC_PROPERTY("OrderedIndex", 1); + TC_PROPERTY("LoggedIndexes", (unsigned)0); + INITIALIZER(runClearTable); + INITIALIZER(createRandomIndex); + INITIALIZER(runLoadTable); + STEP(runRestarts); + STEP(runTransactions1); + STEP(runTransactions1); + FINALIZER(runVerifyIndex); + FINALIZER(createRandomIndex_Drop); + FINALIZER(runClearTable); +} +TESTCASE("NFNR2", + "Test that indexes are correctly maintained during node fail and node restart"){ + TC_PROPERTY("LoggedIndexes", (unsigned)0); + INITIALIZER(runClearTable); + INITIALIZER(createRandomIndex); + INITIALIZER(createPkIndex); + INITIALIZER(runLoadTable); + STEP(runRestarts); + STEP(runTransactions2); + STEP(runTransactions2); + FINALIZER(runVerifyIndex); + FINALIZER(createRandomIndex_Drop); + FINALIZER(createPkIndex_Drop); + FINALIZER(runClearTable); +} +TESTCASE("NFNR2_O", + "Test that indexes are correctly maintained during node fail and node restart"){ + TC_PROPERTY("OrderedIndex", 1); + TC_PROPERTY("LoggedIndexes", (unsigned)0); + INITIALIZER(runClearTable); + INITIALIZER(createRandomIndex); + INITIALIZER(createPkIndex); + INITIALIZER(runLoadTable); + STEP(runRestarts); + STEP(runTransactions2); + STEP(runTransactions2); + FINALIZER(runVerifyIndex); + FINALIZER(createRandomIndex_Drop); + FINALIZER(createPkIndex_Drop); + FINALIZER(runClearTable); +} +TESTCASE("NFNR3", + "Test that indexes are correctly maintained during node fail and node restart"){ + TC_PROPERTY("LoggedIndexes", (unsigned)0); + INITIALIZER(runClearTable); + INITIALIZER(createRandomIndex); + INITIALIZER(createPkIndex); + STEP(runRestarts); + STEP(runTransactions3); + STEP(runVerifyIndex); + FINALIZER(runVerifyIndex); + FINALIZER(createPkIndex_Drop); + FINALIZER(createRandomIndex_Drop); + FINALIZER(runClearTable); +} +TESTCASE("NFNR3_O", + "Test that indexes are correctly maintained during node fail and node restart"){ + TC_PROPERTY("OrderedIndex", 1); + TC_PROPERTY("LoggedIndexes", (unsigned)0); + INITIALIZER(runClearTable); + INITIALIZER(createRandomIndex); + INITIALIZER(createPkIndex); + STEP(runRestarts); + STEP(runTransactions3); + STEP(runVerifyIndex); + FINALIZER(runVerifyIndex); + FINALIZER(createPkIndex_Drop); + FINALIZER(createRandomIndex_Drop); + FINALIZER(runClearTable); +} +TESTCASE("NFNR4", + "Test that indexes are correctly maintained during node fail and node restart"){ + TC_PROPERTY("LoggedIndexes", (unsigned)0); + INITIALIZER(runClearTable); + INITIALIZER(createRandomIndex); + INITIALIZER(createPkIndex); + INITIALIZER(runLoadTable); + STEP(runRestarts); + STEP(runTransactions1); + STEP(runTransactions1); + STEP(runTransactions2); + STEP(runTransactions2); + FINALIZER(runVerifyIndex); + FINALIZER(createRandomIndex_Drop); + FINALIZER(createPkIndex_Drop); + FINALIZER(runClearTable); +} +TESTCASE("NFNR4_O", + "Test that indexes are correctly maintained during node fail and node restart"){ + TC_PROPERTY("OrderedIndex", 1); + TC_PROPERTY("LoggedIndexes", (unsigned)0); + INITIALIZER(runClearTable); + INITIALIZER(createRandomIndex); + INITIALIZER(createPkIndex); + INITIALIZER(runLoadTable); + STEP(runRestarts); + STEP(runTransactions1); + STEP(runTransactions1); + STEP(runTransactions2); + STEP(runTransactions2); + FINALIZER(runVerifyIndex); + FINALIZER(createRandomIndex_Drop); + FINALIZER(createPkIndex_Drop); + FINALIZER(runClearTable); +} +TESTCASE("NFNR5", + "Test that indexes are correctly maintained during node fail and node restart"){ + TC_PROPERTY("LoggedIndexes", (unsigned)0); + TC_PROPERTY("BatchSize", (unsigned)1); + INITIALIZER(runClearTable); + INITIALIZER(createRandomIndex); + INITIALIZER(createPkIndex); + INITIALIZER(runLoadTable); + STEP(runLQHKEYREF); + STEP(runTransactions1); + STEP(runTransactions1); + STEP(runTransactions2); + STEP(runTransactions2); + FINALIZER(runVerifyIndex); + FINALIZER(createRandomIndex_Drop); + FINALIZER(createPkIndex_Drop); + FINALIZER(runClearTable); +} +TESTCASE("NFNR5_O", + "Test that indexes are correctly maintained during node fail and node restart"){ + TC_PROPERTY("OrderedIndex", 1); + TC_PROPERTY("LoggedIndexes", (unsigned)0); + TC_PROPERTY("BatchSize", (unsigned)1); + INITIALIZER(runClearTable); + INITIALIZER(createRandomIndex); + INITIALIZER(createPkIndex); + INITIALIZER(runLoadTable); + STEP(runLQHKEYREF); + STEP(runTransactions1); + STEP(runTransactions1); + STEP(runTransactions2); + STEP(runTransactions2); + FINALIZER(runVerifyIndex); + FINALIZER(createRandomIndex_Drop); + FINALIZER(createPkIndex_Drop); + FINALIZER(runClearTable); +} +TESTCASE("SR1", + "Test that indexes are correctly maintained during SR"){ + INITIALIZER(runClearTable); + INITIALIZER(createRandomIndex); + INITIALIZER(createPkIndex); + STEP(runSystemRestart1); + FINALIZER(runVerifyIndex); + FINALIZER(createPkIndex_Drop); + FINALIZER(createRandomIndex_Drop); + FINALIZER(runClearTable); +} +TESTCASE("MixedTransaction", + "Test mixing of index and normal operations"){ + TC_PROPERTY("LoggedIndexes", (unsigned)0); + INITIALIZER(runClearTable); + INITIALIZER(createPkIndex); + INITIALIZER(runLoadTable); + STEP(runMixed1); + FINALIZER(createPkIndex_Drop); + FINALIZER(runClearTable); +} +TESTCASE("SR1_O", + "Test that indexes are correctly maintained during SR"){ + TC_PROPERTY("OrderedIndex", 1); + TC_PROPERTY("LoggedIndexes", (unsigned)0); + INITIALIZER(runClearTable); + INITIALIZER(createRandomIndex); + INITIALIZER(createPkIndex); + STEP(runSystemRestart1); + FINALIZER(runVerifyIndex); + FINALIZER(createPkIndex_Drop); + FINALIZER(createRandomIndex_Drop); + FINALIZER(runClearTable); +} +TESTCASE("BuildDuring", + "Test that index build when running transactions work"){ + TC_PROPERTY("OrderedIndex", (unsigned)0); + TC_PROPERTY("LoggedIndexes", (unsigned)0); + TC_PROPERTY("Threads", 1); // # runTransactions4 + INITIALIZER(runClearTable); + STEP(runBuildDuring); + STEP(runTransactions4); + //STEP(runTransactions4); + FINALIZER(runClearTable); +} +TESTCASE("BuildDuring_O", + "Test that index build when running transactions work"){ + TC_PROPERTY("OrderedIndex", (unsigned)1); + TC_PROPERTY("LoggedIndexes", (unsigned)0); + TC_PROPERTY("Threads", 1); // # runTransactions4 + INITIALIZER(runClearTable); + STEP(runBuildDuring); + STEP(runTransactions4); + //STEP(runTransactions4); + FINALIZER(runClearTable); +} +TESTCASE("UniqueNull", + "Test that unique indexes and nulls"){ + TC_PROPERTY("LoggedIndexes", (unsigned)0); + INITIALIZER(runClearTable); + INITIALIZER(createRandomIndex); + INITIALIZER(createPkIndex); + INITIALIZER(runLoadTable); + STEP(runTransactions1); + STEP(runTransactions2); + STEP(runUniqueNullTransactions); + FINALIZER(runVerifyIndex); + FINALIZER(createRandomIndex_Drop); + FINALIZER(createPkIndex_Drop); + FINALIZER(runClearTable); +} +NDBT_TESTSUITE_END(testIndex); + +int main(int argc, const char** argv){ + return testIndex.execute(argc, argv); +} + + diff --git a/ndb/test/ndbapi/testIndex/Makefile b/ndb/test/ndbapi/testIndex/Makefile deleted file mode 100644 index e5cd4542c9c..00000000000 --- a/ndb/test/ndbapi/testIndex/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -include .defs.mk - -TYPE = ndbapitest - -BIN_TARGET = testIndex - -SOURCES = testIndex.cpp - -CFLAGS_testIndex.cpp := -I$(call fixpath,$(NDB_TOP)/include/kernel) - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/testIndex/testIndex.cpp b/ndb/test/ndbapi/testIndex/testIndex.cpp deleted file mode 100644 index 47db0b3cff7..00000000000 --- a/ndb/test/ndbapi/testIndex/testIndex.cpp +++ /dev/null @@ -1,1495 +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 */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define CHECK(b) if (!(b)) { \ - g_err << "ERR: "<< step->getName() \ - << " failed on line " << __LINE__ << endl; \ - result = NDBT_FAILED; \ -} - - -struct Attrib { - bool indexCreated; - int numAttribs; - int attribs[1024]; - Attrib(){ - numAttribs = 0; - indexCreated = false; - } -}; -class AttribList { -public: - AttribList(){}; - ~AttribList(){ - for(size_t i = 0; i < attriblist.size(); i++){ - delete attriblist[i]; - } - }; - void buildAttribList(const NdbDictionary::Table* pTab); - Vector attriblist; -}; - -void AttribList::buildAttribList(const NdbDictionary::Table* pTab){ - attriblist.clear(); - - Attrib* attr; - // Build attrib definitions that describes which attributes to build index - // Try to build strange combinations, not just "all" or all PK's - - for(int i = 1; i <= pTab->getNoOfColumns(); i++){ - attr = new Attrib; - attr->numAttribs = i; - for(int a = 0; aattribs[a] = a; - attriblist.push_back(attr); - } - int b = 0; - for(int i = pTab->getNoOfColumns()-1; i > 0; i--){ - attr = new Attrib; - attr->numAttribs = i; - b++; - for(int a = 0; aattribs[a] = a+b; - attriblist.push_back(attr); - } - for(int i = pTab->getNoOfColumns(); i > 0; i--){ - attr = new Attrib; - attr->numAttribs = pTab->getNoOfColumns() - i; - for(int a = 0; agetNoOfColumns() - i; a++) - attr->attribs[a] = pTab->getNoOfColumns()-a-1; - attriblist.push_back(attr); - } - for(int i = 1; i < pTab->getNoOfColumns(); i++){ - attr = new Attrib; - attr->numAttribs = pTab->getNoOfColumns() - i; - for(int a = 0; agetNoOfColumns() - i; a++) - attr->attribs[a] = pTab->getNoOfColumns()-a-1; - attriblist.push_back(attr); - } - for(int i = 1; i < pTab->getNoOfColumns(); i++){ - attr = new Attrib; - attr->numAttribs = 2; - for(int a = 0; a<2; a++){ - attr->attribs[a] = i%pTab->getNoOfColumns(); - } - attriblist.push_back(attr); - } - - // Last - attr = new Attrib; - attr->numAttribs = 1; - attr->attribs[0] = pTab->getNoOfColumns()-1; - attriblist.push_back(attr); - - // Last and first - attr = new Attrib; - attr->numAttribs = 2; - attr->attribs[0] = pTab->getNoOfColumns()-1; - attr->attribs[1] = 0; - attriblist.push_back(attr); - - // First and last - attr = new Attrib; - attr->numAttribs = 2; - attr->attribs[0] = 0; - attr->attribs[1] = pTab->getNoOfColumns()-1; - attriblist.push_back(attr); - -#if 0 - for(size_t i = 0; i < attriblist.size(); i++){ - - ndbout << attriblist[i]->numAttribs << ": " ; - for(int a = 0; a < attriblist[i]->numAttribs; a++) - ndbout << attriblist[i]->attribs[a] << ", "; - ndbout << endl; - } -#endif - -} - -char idxName[255]; -char pkIdxName[255]; - -static const int SKIP_INDEX = 99; - -int create_index(NDBT_Context* ctx, int indxNum, - const NdbDictionary::Table* pTab, - Ndb* pNdb, Attrib* attr, bool logged){ - bool orderedIndex = ctx->getProperty("OrderedIndex", (unsigned)0); - int result = NDBT_OK; - - HugoCalculator calc(*pTab); - - if (attr->numAttribs == 1 && - calc.isUpdateCol(attr->attribs[0]) == true){ - // Don't create index for the Hugo update column - // since it's not unique - return SKIP_INDEX; - } - - // Create index - snprintf(idxName, 255, "IDC%d", indxNum); - if (orderedIndex) - ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "ordered index "<getName()); - if (orderedIndex) - pIdx.setType(NdbDictionary::Index::OrderedIndex); - else - pIdx.setType(NdbDictionary::Index::UniqueHashIndex); - for (int c = 0; c< attr->numAttribs; c++){ - int attrNo = attr->attribs[c]; - pIdx.addIndexColumn(pTab->getColumn(attrNo)->getName()); - ndbout << pTab->getColumn(attrNo)->getName()<<" "; - } - - pIdx.setStoredIndex(logged); - ndbout << ") "; - if (pNdb->getDictionary()->createIndex(pIdx) != 0){ - attr->indexCreated = false; - ndbout << "FAILED!" << endl; - const NdbError err = pNdb->getDictionary()->getNdbError(); - ERR(err); - if(err.classification == NdbError::ApplicationError) - return SKIP_INDEX; - - return NDBT_FAILED; - } else { - ndbout << "OK!" << endl; - attr->indexCreated = true; - } - return result; -} - - -int drop_index(int indxNum, Ndb* pNdb, - const NdbDictionary::Table* pTab, Attrib* attr){ - int result = NDBT_OK; - - if (attr->indexCreated == false) - return NDBT_OK; - - snprintf(idxName, 255, "IDC%d", indxNum); - - // Drop index - ndbout << "Dropping index "<getName() << ") "; - if (pNdb->getDictionary()->dropIndex(idxName, pTab->getName()) != 0){ - ndbout << "FAILED!" << endl; - ERR(pNdb->getDictionary()->getNdbError()); - result = NDBT_FAILED; - } else { - ndbout << "OK!" << endl; - } - return result; -} - -int runCreateIndexes(NDBT_Context* ctx, NDBT_Step* step){ - int loops = ctx->getNumLoops(); - int l = 0; - const NdbDictionary::Table* pTab = ctx->getTab(); - Ndb* pNdb = GETNDB(step); - int result = NDBT_OK; - // NOTE If we need to test creating both logged and non logged indexes - // this should be divided into two testcases - // The paramater logged should then be specified - // as a TC_PROPERTY. ex TC_PROPERTY("LoggedIndexes", 1); - // and read into the test step like - bool logged = ctx->getProperty("LoggedIndexes", 1); - - AttribList attrList; - attrList.buildAttribList(pTab); - - - while (l < loops && result == NDBT_OK){ - - for (unsigned int i = 0; i < attrList.attriblist.size(); i++){ - - // Try to create index - if (create_index(ctx, i, pTab, pNdb, attrList.attriblist[i], logged) == NDBT_FAILED) - result = NDBT_FAILED; - } - - // Now drop all indexes that where created - for (unsigned int i = 0; i < attrList.attriblist.size(); i++){ - - // Try to drop index - if (drop_index(i, pNdb, pTab, attrList.attriblist[i]) != NDBT_OK) - result = NDBT_FAILED; - } - - l++; - } - - return result; -} - -int createRandomIndex(NDBT_Context* ctx, NDBT_Step* step){ - const NdbDictionary::Table* pTab = ctx->getTab(); - Ndb* pNdb = GETNDB(step); - bool logged = ctx->getProperty("LoggedIndexes", 1); - - AttribList attrList; - attrList.buildAttribList(pTab); - - int retries = 100; - while(retries > 0){ - const Uint32 i = rand() % attrList.attriblist.size(); - int res = create_index(ctx, i, pTab, pNdb, attrList.attriblist[i], - logged); - if (res == SKIP_INDEX){ - retries--; - continue; - } - - if (res == NDBT_FAILED){ - return NDBT_FAILED; - } - - ctx->setProperty("createRandomIndex", i); - // Now drop all indexes that where created - - return NDBT_OK; - } - - return NDBT_FAILED; -} - -int createRandomIndex_Drop(NDBT_Context* ctx, NDBT_Step* step){ - Ndb* pNdb = GETNDB(step); - - Uint32 i = ctx->getProperty("createRandomIndex"); - - snprintf(idxName, 255, "IDC%d", i); - - // Drop index - ndbout << "Dropping index " << idxName << " "; - if (pNdb->getDictionary()->dropIndex(idxName, - ctx->getTab()->getName()) != 0){ - ndbout << "FAILED!" << endl; - ERR(pNdb->getDictionary()->getNdbError()); - return NDBT_FAILED; - } else { - ndbout << "OK!" << endl; - } - - return NDBT_OK; -} - -int createPkIndex(NDBT_Context* ctx, NDBT_Step* step){ - bool orderedIndex = ctx->getProperty("OrderedIndex", (unsigned)0); - - const NdbDictionary::Table* pTab = ctx->getTab(); - Ndb* pNdb = GETNDB(step); - - bool logged = ctx->getProperty("LoggedIndexes", 1); - - // Create index - snprintf(pkIdxName, 255, "IDC_PK_%s", pTab->getName()); - if (orderedIndex) - ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "ordered index " - << pkIdxName << " ("; - else - ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "unique index " - << pkIdxName << " ("; - - NdbDictionary::Index pIdx(pkIdxName); - pIdx.setTable(pTab->getName()); - if (orderedIndex) - pIdx.setType(NdbDictionary::Index::OrderedIndex); - else - pIdx.setType(NdbDictionary::Index::UniqueHashIndex); - for (int c = 0; c< pTab->getNoOfColumns(); c++){ - const NdbDictionary::Column * col = pTab->getColumn(c); - if(col->getPrimaryKey()){ - pIdx.addIndexColumn(col->getName()); - ndbout << col->getName() <<" "; - } - } - - pIdx.setStoredIndex(logged); - ndbout << ") "; - if (pNdb->getDictionary()->createIndex(pIdx) != 0){ - ndbout << "FAILED!" << endl; - const NdbError err = pNdb->getDictionary()->getNdbError(); - ERR(err); - return NDBT_FAILED; - } - - ndbout << "OK!" << endl; - return NDBT_OK; -} - -int createPkIndex_Drop(NDBT_Context* ctx, NDBT_Step* step){ - const NdbDictionary::Table* pTab = ctx->getTab(); - Ndb* pNdb = GETNDB(step); - - // Drop index - ndbout << "Dropping index " << pkIdxName << " "; - if (pNdb->getDictionary()->dropIndex(pkIdxName, - pTab->getName()) != 0){ - ndbout << "FAILED!" << endl; - ERR(pNdb->getDictionary()->getNdbError()); - return NDBT_FAILED; - } else { - ndbout << "OK!" << endl; - } - - return NDBT_OK; -} - -int -runVerifyIndex(NDBT_Context* ctx, NDBT_Step* step){ - // Verify that data in index match - // table data - Ndb* pNdb = GETNDB(step); - UtilTransactions utilTrans(*ctx->getTab()); - const int batchSize = ctx->getProperty("BatchSize", 16); - const int parallelism = batchSize > 240 ? 240 : batchSize; - - do { - if (utilTrans.verifyIndex(pNdb, idxName, parallelism, true) != 0){ - g_err << "Inconsistent index" << endl; - return NDBT_FAILED; - } - } while(ctx->isTestStopped() == false); - return NDBT_OK; -} - -int -runTransactions1(NDBT_Context* ctx, NDBT_Step* step){ - // Verify that data in index match - // table data - Ndb* pNdb = GETNDB(step); - HugoTransactions hugoTrans(*ctx->getTab()); - const int batchSize = ctx->getProperty("BatchSize", 50); - - int rows = ctx->getNumRecords(); - while (ctx->isTestStopped() == false) { - if (hugoTrans.pkUpdateRecords(pNdb, rows, batchSize) != 0){ - g_err << "Updated table failed" << endl; - return NDBT_FAILED; - } - if (hugoTrans.scanUpdateRecords(pNdb, rows, batchSize) != 0){ - g_err << "Updated table failed" << endl; - return NDBT_FAILED; - } - } - return NDBT_OK; -} - -int -runTransactions2(NDBT_Context* ctx, NDBT_Step* step){ - // Verify that data in index match - // table data - Ndb* pNdb = GETNDB(step); - HugoTransactions hugoTrans(*ctx->getTab()); - const int batchSize = ctx->getProperty("BatchSize", 50); - - int rows = ctx->getNumRecords(); - while (ctx->isTestStopped() == false) { -#if 1 - if (hugoTrans.indexReadRecords(pNdb, pkIdxName, rows, batchSize) != 0){ - g_err << "Index read failed" << endl; - return NDBT_FAILED; - } -#endif - - if(ctx->isTestStopped()) - break; -#if 1 - if (hugoTrans.indexUpdateRecords(pNdb, pkIdxName, rows, batchSize) != 0){ - g_err << "Index update failed" << endl; - return NDBT_FAILED; - } -#endif - } - return NDBT_OK; -} - -int -runTransactions3(NDBT_Context* ctx, NDBT_Step* step){ - // Verify that data in index match - // table data - Ndb* pNdb = GETNDB(step); - HugoTransactions hugoTrans(*ctx->getTab()); - UtilTransactions utilTrans(*ctx->getTab()); - const int batchSize = ctx->getProperty("BatchSize", 32); - const int parallel = batchSize > 240 ? 240 : batchSize; - - int rows = ctx->getNumRecords(); - while (ctx->isTestStopped() == false) { - if(hugoTrans.loadTable(pNdb, rows, batchSize, false) != 0){ - g_err << "Load table failed" << endl; - return NDBT_FAILED; - } - if(ctx->isTestStopped()) - break; - - if (hugoTrans.pkUpdateRecords(pNdb, rows, batchSize) != 0){ - g_err << "Updated table failed" << endl; - return NDBT_FAILED; - } - - if(ctx->isTestStopped()) - break; - - if (hugoTrans.indexReadRecords(pNdb, pkIdxName, rows, batchSize) != 0){ - g_err << "Index read failed" << endl; - return NDBT_FAILED; - } - - if(ctx->isTestStopped()) - break; - - if (hugoTrans.indexUpdateRecords(pNdb, pkIdxName, rows, batchSize) != 0){ - g_err << "Index update failed" << endl; - return NDBT_FAILED; - } - - if(ctx->isTestStopped()) - break; - - if (hugoTrans.scanUpdateRecords(pNdb, rows, 5, parallel) != 0){ - g_err << "Scan updated table failed" << endl; - return NDBT_FAILED; - } - - if(ctx->isTestStopped()) - break; - - if(utilTrans.clearTable(pNdb, rows, parallel) != 0){ - g_err << "Clear table failed" << endl; - return NDBT_FAILED; - } - if(ctx->isTestStopped()) - break; - - int count = -1; - if(utilTrans.selectCount(pNdb, 64, &count) != 0 || count != 0) - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runRestarts(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - int loops = ctx->getNumLoops(); - NDBT_TestCase* pCase = ctx->getCase(); - NdbRestarts restarts; - int i = 0; - int timeout = 240; - - while(iisTestStopped()){ - if(restarts.executeRestart("RestartRandomNodeAbort", timeout) != 0){ - g_err << "Failed to executeRestart(" <getName() <<")" << endl; - result = NDBT_FAILED; - break; - } - i++; - } - ctx->stopTest(); - return result; -} - -int runCreateLoadDropIndex(NDBT_Context* ctx, NDBT_Step* step){ - int loops = ctx->getNumLoops(); - int records = ctx->getNumRecords(); - int l = 0; - const NdbDictionary::Table* pTab = ctx->getTab(); - Ndb* pNdb = GETNDB(step); - int result = NDBT_OK; - int batchSize = ctx->getProperty("BatchSize", 1); - int parallelism = batchSize > 240? 240: batchSize; - ndbout << "batchSize="<getProperty("LoggedIndexes", 1); - - HugoTransactions hugoTrans(*pTab); - UtilTransactions utilTrans(*pTab); - AttribList attrList; - attrList.buildAttribList(pTab); - - for (unsigned int i = 0; i < attrList.attriblist.size(); i++){ - - while (l < loops && result == NDBT_OK){ - - if ((l % 2) == 0){ - // Create index first and then load - - // Try to create index - if (create_index(ctx, i, pTab, pNdb, attrList.attriblist[i], logged) == NDBT_FAILED){ - result = NDBT_FAILED; - } - - // Load the table with data - ndbout << "Loading data after" << endl; - CHECK(hugoTrans.loadTable(pNdb, records, batchSize) == 0); - - - } else { - // Load table then create index - - // Load the table with data - ndbout << "Loading data before" << endl; - CHECK(hugoTrans.loadTable(pNdb, records, batchSize) == 0); - - // Try to create index - if (create_index(ctx, i, pTab, pNdb, attrList.attriblist[i], logged) == NDBT_FAILED) - result = NDBT_FAILED; - - } - - // Verify that data in index match - // table data - CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0); - - // Do it all... - ndbout <<"Doing it all"<getNumLoops(); - int records = ctx->getNumRecords(); - const NdbDictionary::Table* pTab = ctx->getTab(); - Ndb* pNdb = GETNDB(step); - int result = NDBT_OK; - int batchSize = ctx->getProperty("BatchSize", 1); - int parallelism = batchSize > 240? 240: batchSize; - ndbout << "batchSize="<getProperty("LoggedIndexes", 1); - - HugoTransactions hugoTrans(*pTab); - UtilTransactions utilTrans(*pTab); - - AttribList attrList; - attrList.buildAttribList(pTab); - - for (unsigned int i = 0; i < attrList.attriblist.size(); i++){ - - Attrib* attr = attrList.attriblist[i]; - // Create index - if (create_index(ctx, i, pTab, pNdb, attr, logged) == NDBT_OK){ - int l = 1; - while (l <= loops && result == NDBT_OK){ - - CHECK(hugoTrans.loadTable(pNdb, records, batchSize) == 0); - CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0); - CHECK(utilTrans.clearTable(pNdb, records, parallelism) == 0); - CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0); - l++; - } - - // Drop index - if (drop_index(i, pNdb, pTab, attr) != NDBT_OK) - result = NDBT_FAILED; - } - } - - return result; -} -int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - - HugoTransactions hugoTrans(*ctx->getTab()); - int batchSize = ctx->getProperty("BatchSize", 1); - if(hugoTrans.loadTable(GETNDB(step), records, batchSize) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - - -int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - - UtilTransactions utilTrans(*ctx->getTab()); - if (utilTrans.clearTable(GETNDB(step), records) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runSystemRestart1(NDBT_Context* ctx, NDBT_Step* step){ - Ndb* pNdb = GETNDB(step); - int result = NDBT_OK; - int timeout = 300; - Uint32 loops = ctx->getNumLoops(); - int records = ctx->getNumRecords(); - int count; - NdbRestarter restarter; - Uint32 i = 1; - - UtilTransactions utilTrans(*ctx->getTab()); - HugoTransactions hugoTrans(*ctx->getTab()); - const char * name = ctx->getTab()->getName(); - while(i<=loops && result != NDBT_FAILED){ - - ndbout << "Loop " << i << "/"<< loops <<" started" << endl; - /* - 1. Load data - 2. Restart cluster and verify records - 3. Update records - 4. Restart cluster and verify records - 5. Delete half of the records - 6. Restart cluster and verify records - 7. Delete all records - 8. Restart cluster and verify records - 9. Insert, update, delete records - 10. Restart cluster and verify records - 11. Insert, update, delete records - 12. Restart cluster with error insert 5020 and verify records - */ - ndbout << "Loading records..." << endl; - CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0); - CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); - - ndbout << "Restarting cluster" << endl; - CHECK(restarter.restartAll() == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - CHECK(pNdb->waitUntilReady(timeout) == 0); - - ndbout << "Verifying records..." << endl; - CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0); - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == records); - CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); - - ndbout << "Updating records..." << endl; - CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); - CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); - - ndbout << "Restarting cluster..." << endl; - CHECK(restarter.restartAll() == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - CHECK(pNdb->waitUntilReady(timeout) == 0); - - ndbout << "Verifying records..." << endl; - CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0); - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == records); - CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); - - ndbout << "Deleting 50% of records..." << endl; - CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); - CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); - - ndbout << "Restarting cluster..." << endl; - CHECK(restarter.restartAll() == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - CHECK(pNdb->waitUntilReady(timeout) == 0); - - ndbout << "Verifying records..." << endl; - CHECK(hugoTrans.scanReadRecords(pNdb, records/2, 0, 64) == 0); - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == (records/2)); - CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); - - ndbout << "Deleting all records..." << endl; - CHECK(utilTrans.clearTable(pNdb, records/2) == 0); - CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); - - ndbout << "Restarting cluster..." << endl; - CHECK(restarter.restartAll() == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - CHECK(pNdb->waitUntilReady(timeout) == 0); - - ndbout << "Verifying records..." << endl; - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == 0); - CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); - - ndbout << "Doing it all..." << endl; - CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0); - CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); - CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); - CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); - CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); - CHECK(hugoTrans.scanUpdateRecords(pNdb, records) == 0); - CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); - CHECK(utilTrans.clearTable(pNdb, records) == 0); - CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0); - CHECK(utilTrans.clearTable(pNdb, records) == 0); - CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0); - CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); - CHECK(utilTrans.clearTable(pNdb, records) == 0); - - ndbout << "Restarting cluster..." << endl; - CHECK(restarter.restartAll() == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - CHECK(pNdb->waitUntilReady(timeout) == 0); - - ndbout << "Verifying records..." << endl; - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == 0); - - ndbout << "Doing it all..." << endl; - CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0); - CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); - CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); - CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); - CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); - CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); - CHECK(hugoTrans.scanUpdateRecords(pNdb, records) == 0); - CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); - CHECK(utilTrans.clearTable(pNdb, records) == 0); - CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0); - CHECK(utilTrans.clearTable(pNdb, records) == 0); - - ndbout << "Restarting cluster with error insert 5020..." << endl; - CHECK(restarter.restartAll(false, true) == 0); - CHECK(restarter.waitClusterNoStart(timeout) == 0); - CHECK(restarter.insertErrorInAllNodes(5020) == 0); - CHECK(restarter.startAll() == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - CHECK(pNdb->waitUntilReady(timeout) == 0); - - i++; - } - - ctx->stopTest(); - ndbout << "runSystemRestart1 finished" << endl; - - return result; -} - -#define CHECK2(b, t) if(!b){ g_err << __LINE__ << ": " << t << endl; break;} - -int -runMixed1(NDBT_Context* ctx, NDBT_Step* step){ - // Verify that data in index match - // table data - Ndb* pNdb = GETNDB(step); - HugoOperations hugoOps(*ctx->getTab()); - - - do { - // TC1 - g_err << "pkRead, indexRead, Commit" << endl; - CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction"); - CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0) == 0, "indexReadRecords"); - CHECK2(hugoOps.pkReadRecord(pNdb, 0) == 0, "pkReadRecord"); - CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit"); - CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction"); - - // TC1 - g_err << "pkRead, indexRead, Commit" << endl; - CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction"); - CHECK2(hugoOps.pkReadRecord(pNdb, 0) == 0, "pkReadRecord"); - CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0) == 0, "indexReadRecords"); - CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit"); - CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction"); - - - // TC2 - g_err << "pkRead, indexRead, NoCommit, Commit" << endl; - CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction"); - CHECK2(hugoOps.pkReadRecord(pNdb, 0) == 0, "pkReadRecord"); - CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0) == 0, - "indexReadRecords"); - CHECK2(hugoOps.execute_NoCommit(pNdb) == 0, "executeNoCommit"); - CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit"); - CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction"); - - // TC3 - g_err << "pkRead, pkRead, Commit" << endl; - CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction "); - CHECK2(hugoOps.pkReadRecord(pNdb, 0) == 0, "pkReadRecords "); - CHECK2(hugoOps.pkReadRecord(pNdb, 0) == 0, "pkReadRecords "); - CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit"); - CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction "); - - // TC4 - g_err << "indexRead, indexRead, Commit" << endl; - - CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction "); - CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0) == 0, "indexReadRecords"); - CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0) == 0, "indexReadRecords"); - CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit"); - - CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction "); - - return NDBT_OK; - } while(false); - - - hugoOps.closeTransaction(pNdb); - return NDBT_FAILED; -} - -int -runBuildDuring(NDBT_Context* ctx, NDBT_Step* step){ - // Verify that data in index match - // table data - const int Threads = ctx->getProperty("Threads", (Uint32)0); - const int loops = ctx->getNumLoops(); - - for(int i = 0; iisTestStopped()) - break; - -#if 1 - if(createRandomIndex(ctx, step) != NDBT_OK){ - g_err << "Failed to create index" << endl; - return NDBT_FAILED; - } -#endif - - if(ctx->isTestStopped()) - break; - - ctx->setProperty("pause", 1); - int count = 0; - for(int j = 0; count < Threads && !ctx->isTestStopped(); - j = (j+1) % Threads){ - char buf[255]; - sprintf(buf, "Thread%d_paused", j); - int tmp = ctx->getProperty(buf, (Uint32)0); - count += tmp; - } - - if(ctx->isTestStopped()) - break; - -#if 1 - if(createPkIndex_Drop(ctx, step) != NDBT_OK){ - g_err << "Failed to drop index" << endl; - return NDBT_FAILED; - } -#endif - - if(ctx->isTestStopped()) - break; - -#if 1 - if(createRandomIndex_Drop(ctx, step) != NDBT_OK){ - g_err << "Failed to drop index" << endl; - return NDBT_FAILED; - } -#endif - - ctx->setProperty("pause", (Uint32)0); - NdbSleep_SecSleep(2); - } - - ctx->stopTest(); - return NDBT_OK; -} - -static NdbLockable g_lock; -static int threadCounter = 0; - -void -wait_paused(NDBT_Context* ctx, int id){ - if(ctx->getProperty("pause", (Uint32)0) == 1){ - char buf[255]; - sprintf(buf, "Thread%d_paused", id); - ctx->setProperty(buf, 1); - while(!ctx->isTestStopped() && ctx->getProperty("pause", (Uint32)0) == 1){ - NdbSleep_MilliSleep(250); - } - ctx->setProperty(buf, (Uint32)0); - } -} - -int -runTransactions4(NDBT_Context* ctx, NDBT_Step* step){ - - g_lock.lock(); - const int ThreadId = threadCounter++; - g_lock.unlock(); - - // Verify that data in index match - // table data - Ndb* pNdb = GETNDB(step); - HugoTransactions hugoTrans(*ctx->getTab()); - UtilTransactions utilTrans(*ctx->getTab()); - const int batchSize = ctx->getProperty("BatchSize", 32); - const int parallel = batchSize > 240 ? 240 : batchSize; - - int rows = ctx->getNumRecords(); - while (ctx->isTestStopped() == false) { - if(hugoTrans.loadTable(pNdb, rows, batchSize, false) != 0){ - g_err << "Load table failed" << endl; - return NDBT_FAILED; - } - - wait_paused(ctx, ThreadId); - - if(ctx->isTestStopped()) - break; - - if (hugoTrans.pkUpdateRecords(pNdb, rows, batchSize) != 0){ - g_err << "Updated table failed" << endl; - return NDBT_FAILED; - } - - wait_paused(ctx, ThreadId); - - if(ctx->isTestStopped()) - break; - - if (hugoTrans.scanUpdateRecords(pNdb, rows, 5, parallel) != 0){ - g_err << "Scan updated table failed" << endl; - return NDBT_FAILED; - } - - wait_paused(ctx, ThreadId); - - if(ctx->isTestStopped()) - break; - - if(utilTrans.clearTable(pNdb, rows, parallel) != 0){ - g_err << "Clear table failed" << endl; - return NDBT_FAILED; - } - } - return NDBT_OK; -} - -int -runUniqueNullTransactions(NDBT_Context* ctx, NDBT_Step* step){ - Ndb* pNdb = GETNDB(step); - - bool logged = ctx->getProperty("LoggedIndexes", 1); - bool orderedIndex = ctx->getProperty("OrderedIndex", (unsigned)0); - NdbConnection * pTrans = 0; - - const NdbDictionary::Table* pTab = ctx->getTab(); - // Create index - char nullIndex[255]; - snprintf(nullIndex, 255, "IDC_PK_%s_NULL", pTab->getName()); - if (orderedIndex) - ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "ordered index " - << pkIdxName << " ("; - else - ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "unique index " - << pkIdxName << " ("; - - NdbDictionary::Index pIdx(pkIdxName); - pIdx.setTable(pTab->getName()); - if (orderedIndex) - pIdx.setType(NdbDictionary::Index::OrderedIndex); - else - pIdx.setType(NdbDictionary::Index::UniqueHashIndex); - pIdx.setStoredIndex(logged); - - for (int c = 0; c< pTab->getNoOfColumns(); c++){ - const NdbDictionary::Column * col = pTab->getColumn(c); - if(col->getPrimaryKey()){ - pIdx.addIndexColumn(col->getName()); - ndbout << col->getName() <<" "; - } - } - - int colId = -1; - for (int c = 0; c< pTab->getNoOfColumns(); c++){ - const NdbDictionary::Column * col = pTab->getColumn(c); - if(col->getNullable()){ - pIdx.addIndexColumn(col->getName()); - ndbout << col->getName() <<" "; - colId = c; - break; - } - } - ndbout << ") "; - - if(colId == -1){ - ndbout << endl << "No nullable column found -> NDBT_FAILED" << endl; - return NDBT_FAILED; - } - - if (pNdb->getDictionary()->createIndex(pIdx) != 0){ - ndbout << "FAILED!" << endl; - const NdbError err = pNdb->getDictionary()->getNdbError(); - ERR(err); - return NDBT_FAILED; - } - - int result = NDBT_OK; - - HugoTransactions hugoTrans(*ctx->getTab()); - const int batchSize = ctx->getProperty("BatchSize", 50); - int loops = ctx->getNumLoops(); - int rows = ctx->getNumRecords(); - while (loops-- > 0 && ctx->isTestStopped() == false) { - if (hugoTrans.pkUpdateRecords(pNdb, rows, batchSize) != 0){ - g_err << "Updated table failed" << endl; - result = NDBT_FAILED; - goto done; - } - } - - if(ctx->isTestStopped()){ - goto done; - } - - ctx->stopTest(); - while(ctx->getNoOfRunningSteps() > 1){ - NdbSleep_MilliSleep(100); - } - - result = NDBT_FAILED; - pTrans = pNdb->startTransaction(); - NdbScanOperation * sOp; - NdbOperation * uOp; - NdbResultSet * rs; - int eof; - if(!pTrans) goto done; - sOp = pTrans->getNdbScanOperation(pTab->getName()); - if(!sOp) goto done; - rs = sOp->readTuples(240, NdbScanOperation::LM_Exclusive); - if(!rs) goto done; - if(pTrans->execute(NoCommit) == -1) goto done; - while((eof = rs->nextResult(true)) == 0){ - do { - NdbOperation * uOp = rs->updateTuple(); - if(uOp == 0) goto done; - uOp->setValue(colId, 0); - } while((eof = rs->nextResult(false)) == 0); - eof = pTrans->execute(Commit); - if(eof == -1) goto done; - } - - done: - if(pTrans) pNdb->closeTransaction(pTrans); - pNdb->getDictionary()->dropIndex(nullIndex, pTab->getName()); - return result; -} - -int runLQHKEYREF(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - int loops = ctx->getNumLoops() * 100; - NdbRestarter restarter; - - myRandom48Init(NdbTick_CurrentMillisecond()); - -#if 0 - int val = DumpStateOrd::DihMinTimeBetweenLCP; - if(restarter.dumpStateAllNodes(&val, 1) != 0){ - g_err << "Failed to dump DihMinTimeBetweenLCP" << endl; - return NDBT_FAILED; - } -#endif - - for(int i = 0; iisTestStopped(); i++){ - int randomId = myRandom48(restarter.getNumDbNodes()); - int nodeId = restarter.getDbNodeId(randomId); - - const Uint32 error = 5031 + (i % 3); - - if(restarter.insertErrorInNode(nodeId, error) != 0){ - g_err << "Failed to error insert( " << error << ") in node " - << nodeId << endl; - return NDBT_FAILED; - } - } - - ctx->stopTest(); - return NDBT_OK; -} - -NDBT_TESTSUITE(testIndex); -TESTCASE("CreateAll", - "Test that we can create all various indexes on each table\n" - "Then drop the indexes\n"){ - INITIALIZER(runCreateIndexes); -} -TESTCASE("CreateAll_O", - "Test that we can create all various indexes on each table\n" - "Then drop the indexes\n"){ - TC_PROPERTY("OrderedIndex", 1); - TC_PROPERTY("LoggedIndexes", (unsigned)0); - INITIALIZER(runCreateIndexes); -} -TESTCASE("InsertDeleteGentle", - "Create one index, then perform insert and delete in the table\n" - "loop number of times. Use batch size 1."){ - TC_PROPERTY("BatchSize", 1); - INITIALIZER(runInsertDelete); - FINALIZER(runClearTable); -} -TESTCASE("InsertDeleteGentle_O", - "Create one index, then perform insert and delete in the table\n" - "loop number of times. Use batch size 1."){ - TC_PROPERTY("OrderedIndex", 1); - TC_PROPERTY("LoggedIndexes", (unsigned)0); - TC_PROPERTY("BatchSize", 1); - INITIALIZER(runInsertDelete); - FINALIZER(runClearTable); -} -TESTCASE("InsertDelete", - "Create one index, then perform insert and delete in the table\n" - "loop number of times. Use batchsize 512 to stress db more"){ - TC_PROPERTY("BatchSize", 512); - INITIALIZER(runInsertDelete); - FINALIZER(runClearTable); - -} -TESTCASE("InsertDelete_O", - "Create one index, then perform insert and delete in the table\n" - "loop number of times. Use batchsize 512 to stress db more"){ - TC_PROPERTY("OrderedIndex", 1); - TC_PROPERTY("LoggedIndexes", (unsigned)0); - TC_PROPERTY("BatchSize", 512); - INITIALIZER(runInsertDelete); - FINALIZER(runClearTable); - -} -TESTCASE("CreateLoadDropGentle", - "Try to create, drop and load various indexes \n" - "on table loop number of times.Usa batch size 1.\n"){ - TC_PROPERTY("BatchSize", 1); - INITIALIZER(runCreateLoadDropIndex); -} -TESTCASE("CreateLoadDropGentle_O", - "Try to create, drop and load various indexes \n" - "on table loop number of times.Usa batch size 1.\n"){ - TC_PROPERTY("OrderedIndex", 1); - TC_PROPERTY("LoggedIndexes", (unsigned)0); - TC_PROPERTY("BatchSize", 1); - INITIALIZER(runCreateLoadDropIndex); -} -TESTCASE("CreateLoadDrop", - "Try to create, drop and load various indexes \n" - "on table loop number of times. Use batchsize 512 to stress db more\n"){ - TC_PROPERTY("BatchSize", 512); - INITIALIZER(runCreateLoadDropIndex); -} -TESTCASE("CreateLoadDrop_O", - "Try to create, drop and load various indexes \n" - "on table loop number of times. Use batchsize 512 to stress db more\n"){ - TC_PROPERTY("OrderedIndex", 1); - TC_PROPERTY("LoggedIndexes", (unsigned)0); - TC_PROPERTY("BatchSize", 512); - INITIALIZER(runCreateLoadDropIndex); -} -TESTCASE("NFNR1", - "Test that indexes are correctly maintained during node fail and node restart"){ - TC_PROPERTY("LoggedIndexes", (unsigned)0); - INITIALIZER(runClearTable); - INITIALIZER(createRandomIndex); - INITIALIZER(runLoadTable); - STEP(runRestarts); - STEP(runTransactions1); - STEP(runTransactions1); - FINALIZER(runVerifyIndex); - FINALIZER(createRandomIndex_Drop); - FINALIZER(runClearTable); -} -TESTCASE("NFNR1_O", - "Test that indexes are correctly maintained during node fail and node restart"){ - TC_PROPERTY("OrderedIndex", 1); - TC_PROPERTY("LoggedIndexes", (unsigned)0); - INITIALIZER(runClearTable); - INITIALIZER(createRandomIndex); - INITIALIZER(runLoadTable); - STEP(runRestarts); - STEP(runTransactions1); - STEP(runTransactions1); - FINALIZER(runVerifyIndex); - FINALIZER(createRandomIndex_Drop); - FINALIZER(runClearTable); -} -TESTCASE("NFNR2", - "Test that indexes are correctly maintained during node fail and node restart"){ - TC_PROPERTY("LoggedIndexes", (unsigned)0); - INITIALIZER(runClearTable); - INITIALIZER(createRandomIndex); - INITIALIZER(createPkIndex); - INITIALIZER(runLoadTable); - STEP(runRestarts); - STEP(runTransactions2); - STEP(runTransactions2); - FINALIZER(runVerifyIndex); - FINALIZER(createRandomIndex_Drop); - FINALIZER(createPkIndex_Drop); - FINALIZER(runClearTable); -} -TESTCASE("NFNR2_O", - "Test that indexes are correctly maintained during node fail and node restart"){ - TC_PROPERTY("OrderedIndex", 1); - TC_PROPERTY("LoggedIndexes", (unsigned)0); - INITIALIZER(runClearTable); - INITIALIZER(createRandomIndex); - INITIALIZER(createPkIndex); - INITIALIZER(runLoadTable); - STEP(runRestarts); - STEP(runTransactions2); - STEP(runTransactions2); - FINALIZER(runVerifyIndex); - FINALIZER(createRandomIndex_Drop); - FINALIZER(createPkIndex_Drop); - FINALIZER(runClearTable); -} -TESTCASE("NFNR3", - "Test that indexes are correctly maintained during node fail and node restart"){ - TC_PROPERTY("LoggedIndexes", (unsigned)0); - INITIALIZER(runClearTable); - INITIALIZER(createRandomIndex); - INITIALIZER(createPkIndex); - STEP(runRestarts); - STEP(runTransactions3); - STEP(runVerifyIndex); - FINALIZER(runVerifyIndex); - FINALIZER(createPkIndex_Drop); - FINALIZER(createRandomIndex_Drop); - FINALIZER(runClearTable); -} -TESTCASE("NFNR3_O", - "Test that indexes are correctly maintained during node fail and node restart"){ - TC_PROPERTY("OrderedIndex", 1); - TC_PROPERTY("LoggedIndexes", (unsigned)0); - INITIALIZER(runClearTable); - INITIALIZER(createRandomIndex); - INITIALIZER(createPkIndex); - STEP(runRestarts); - STEP(runTransactions3); - STEP(runVerifyIndex); - FINALIZER(runVerifyIndex); - FINALIZER(createPkIndex_Drop); - FINALIZER(createRandomIndex_Drop); - FINALIZER(runClearTable); -} -TESTCASE("NFNR4", - "Test that indexes are correctly maintained during node fail and node restart"){ - TC_PROPERTY("LoggedIndexes", (unsigned)0); - INITIALIZER(runClearTable); - INITIALIZER(createRandomIndex); - INITIALIZER(createPkIndex); - INITIALIZER(runLoadTable); - STEP(runRestarts); - STEP(runTransactions1); - STEP(runTransactions1); - STEP(runTransactions2); - STEP(runTransactions2); - FINALIZER(runVerifyIndex); - FINALIZER(createRandomIndex_Drop); - FINALIZER(createPkIndex_Drop); - FINALIZER(runClearTable); -} -TESTCASE("NFNR4_O", - "Test that indexes are correctly maintained during node fail and node restart"){ - TC_PROPERTY("OrderedIndex", 1); - TC_PROPERTY("LoggedIndexes", (unsigned)0); - INITIALIZER(runClearTable); - INITIALIZER(createRandomIndex); - INITIALIZER(createPkIndex); - INITIALIZER(runLoadTable); - STEP(runRestarts); - STEP(runTransactions1); - STEP(runTransactions1); - STEP(runTransactions2); - STEP(runTransactions2); - FINALIZER(runVerifyIndex); - FINALIZER(createRandomIndex_Drop); - FINALIZER(createPkIndex_Drop); - FINALIZER(runClearTable); -} -TESTCASE("NFNR5", - "Test that indexes are correctly maintained during node fail and node restart"){ - TC_PROPERTY("LoggedIndexes", (unsigned)0); - TC_PROPERTY("BatchSize", (unsigned)1); - INITIALIZER(runClearTable); - INITIALIZER(createRandomIndex); - INITIALIZER(createPkIndex); - INITIALIZER(runLoadTable); - STEP(runLQHKEYREF); - STEP(runTransactions1); - STEP(runTransactions1); - STEP(runTransactions2); - STEP(runTransactions2); - FINALIZER(runVerifyIndex); - FINALIZER(createRandomIndex_Drop); - FINALIZER(createPkIndex_Drop); - FINALIZER(runClearTable); -} -TESTCASE("NFNR5_O", - "Test that indexes are correctly maintained during node fail and node restart"){ - TC_PROPERTY("OrderedIndex", 1); - TC_PROPERTY("LoggedIndexes", (unsigned)0); - TC_PROPERTY("BatchSize", (unsigned)1); - INITIALIZER(runClearTable); - INITIALIZER(createRandomIndex); - INITIALIZER(createPkIndex); - INITIALIZER(runLoadTable); - STEP(runLQHKEYREF); - STEP(runTransactions1); - STEP(runTransactions1); - STEP(runTransactions2); - STEP(runTransactions2); - FINALIZER(runVerifyIndex); - FINALIZER(createRandomIndex_Drop); - FINALIZER(createPkIndex_Drop); - FINALIZER(runClearTable); -} -TESTCASE("SR1", - "Test that indexes are correctly maintained during SR"){ - INITIALIZER(runClearTable); - INITIALIZER(createRandomIndex); - INITIALIZER(createPkIndex); - STEP(runSystemRestart1); - FINALIZER(runVerifyIndex); - FINALIZER(createPkIndex_Drop); - FINALIZER(createRandomIndex_Drop); - FINALIZER(runClearTable); -} -TESTCASE("MixedTransaction", - "Test mixing of index and normal operations"){ - TC_PROPERTY("LoggedIndexes", (unsigned)0); - INITIALIZER(runClearTable); - INITIALIZER(createPkIndex); - INITIALIZER(runLoadTable); - STEP(runMixed1); - FINALIZER(createPkIndex_Drop); - FINALIZER(runClearTable); -} -TESTCASE("SR1_O", - "Test that indexes are correctly maintained during SR"){ - TC_PROPERTY("OrderedIndex", 1); - TC_PROPERTY("LoggedIndexes", (unsigned)0); - INITIALIZER(runClearTable); - INITIALIZER(createRandomIndex); - INITIALIZER(createPkIndex); - STEP(runSystemRestart1); - FINALIZER(runVerifyIndex); - FINALIZER(createPkIndex_Drop); - FINALIZER(createRandomIndex_Drop); - FINALIZER(runClearTable); -} -TESTCASE("BuildDuring", - "Test that index build when running transactions work"){ - TC_PROPERTY("OrderedIndex", (unsigned)0); - TC_PROPERTY("LoggedIndexes", (unsigned)0); - TC_PROPERTY("Threads", 1); // # runTransactions4 - INITIALIZER(runClearTable); - STEP(runBuildDuring); - STEP(runTransactions4); - //STEP(runTransactions4); - FINALIZER(runClearTable); -} -TESTCASE("BuildDuring_O", - "Test that index build when running transactions work"){ - TC_PROPERTY("OrderedIndex", (unsigned)1); - TC_PROPERTY("LoggedIndexes", (unsigned)0); - TC_PROPERTY("Threads", 1); // # runTransactions4 - INITIALIZER(runClearTable); - STEP(runBuildDuring); - STEP(runTransactions4); - //STEP(runTransactions4); - FINALIZER(runClearTable); -} -TESTCASE("UniqueNull", - "Test that unique indexes and nulls"){ - TC_PROPERTY("LoggedIndexes", (unsigned)0); - INITIALIZER(runClearTable); - INITIALIZER(createRandomIndex); - INITIALIZER(createPkIndex); - INITIALIZER(runLoadTable); - STEP(runTransactions1); - STEP(runTransactions2); - STEP(runUniqueNullTransactions); - FINALIZER(runVerifyIndex); - FINALIZER(createRandomIndex_Drop); - FINALIZER(createPkIndex_Drop); - FINALIZER(runClearTable); -} -NDBT_TESTSUITE_END(testIndex); - -int main(int argc, const char** argv){ - return testIndex.execute(argc, argv); -} - - diff --git a/ndb/test/ndbapi/testInterpreter.cpp b/ndb/test/ndbapi/testInterpreter.cpp new file mode 100644 index 00000000000..9c584d6f581 --- /dev/null +++ b/ndb/test/ndbapi/testInterpreter.cpp @@ -0,0 +1,231 @@ +/* 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 */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define CHECK(b) if (!(b)) { \ + ndbout << "ERR: "<< step->getName() \ + << " failed on line " << __LINE__ << endl; \ + result = NDBT_FAILED; \ + continue; } + +int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + int batchSize = ctx->getProperty("BatchSize", 1); + + HugoTransactions hugoTrans(*ctx->getTab()); + if (hugoTrans.pkDelRecords(GETNDB(step), records, batchSize) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ + + int records = ctx->getNumRecords(); + HugoTransactions hugoTrans(*ctx->getTab()); + if (hugoTrans.loadTable(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runTestIncValue64(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + // NDBT_Table* pTab = ctx->getTab(); + //Ndb* pNdb = GETNDB(step); + + HugoTransactions hugoTrans(*ctx->getTab()); + if (hugoTrans.pkInterpretedUpdateRecords(GETNDB(step), + records) != 0){ + return NDBT_FAILED; + } + + // Verify the update + if (hugoTrans.pkReadRecords(GETNDB(step), + records) != 0){ + return NDBT_FAILED; + } + + return NDBT_OK; + +} + +int runTestIncValue32(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + const NdbDictionary::Table * pTab = ctx->getTab(); + Ndb* pNdb = GETNDB(step); + + + NdbConnection* pTrans = pNdb->startTransaction(); + if (pTrans == NULL){ + ERR(pNdb->getNdbError()); + return NDBT_FAILED; + } + + NdbOperation* pOp = pTrans->getNdbOperation(pTab->getName()); + if (pOp == NULL) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + int check = pOp->interpretedUpdateTuple(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + + // Primary keys + Uint32 pkVal = 1; + check = pOp->equal("KOL1", pkVal ); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + // Attributes + + // Update column + Uint32 valToIncWith = 1; + check = pOp->incValue("KOL2", valToIncWith); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + NdbRecAttr* valueRec = pOp->getValue("KOL2"); + if( valueRec == NULL ) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + check = pTrans->execute(Commit); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + Uint32 value = valueRec->u_32_value(); + + pNdb->closeTransaction(pTrans); + + + return NDBT_OK; +} + + +NDBT_TESTSUITE(testInterpreter); +TESTCASE("IncValue32", + "Test incValue for 32 bit integer\n"){ + INITIALIZER(runLoadTable); + INITIALIZER(runTestIncValue32); + FINALIZER(runClearTable); +} +TESTCASE("IncValue64", + "Test incValue for 64 bit integer\n"){ + INITIALIZER(runLoadTable); + INITIALIZER(runTestIncValue64); + FINALIZER(runClearTable); +} +#if 0 +TESTCASE("MaxTransactions", + "Start transactions until no more can be created\n"){ + INITIALIZER(runTestMaxTransaction); +} +TESTCASE("MaxOperations", + "Get operations until no more can be created\n"){ + INITIALIZER(runLoadTable); + INITIALIZER(runTestMaxOperations); + FINALIZER(runClearTable); +} +TESTCASE("MaxGetValue", + "Call getValue loads of time\n"){ + INITIALIZER(runLoadTable); + INITIALIZER(runTestGetValue); + FINALIZER(runClearTable); +} +TESTCASE("MaxEqual", + "Call equal loads of time\n"){ + INITIALIZER(runTestEqual); +} +TESTCASE("DeleteNdb", + "Make sure that a deleted Ndb object is properly deleted\n" + "and removed from transporter\n"){ + INITIALIZER(runLoadTable); + INITIALIZER(runTestDeleteNdb); + FINALIZER(runClearTable); +} +TESTCASE("WaitUntilReady", + "Make sure you get an error message when calling waitUntilReady\n" + "without an init'ed Ndb\n"){ + INITIALIZER(runTestWaitUntilReady); +} +TESTCASE("GetOperationNoTab", + "Call getNdbOperation on a table that does not exist\n"){ + INITIALIZER(runGetNdbOperationNoTab); +} +TESTCASE("MissingOperation", + "Missing operation request(insertTuple) should give an error code\n"){ + INITIALIZER(runMissingOperation); +} +TESTCASE("GetValueInUpdate", + "Test that it's not possible to perform getValue in an update\n"){ + INITIALIZER(runLoadTable); + INITIALIZER(runGetValueInUpdate); + FINALIZER(runClearTable); +} +TESTCASE("UpdateWithoutKeys", + "Test that it's not possible to perform update without setting\n" + "PKs"){ + INITIALIZER(runLoadTable); + INITIALIZER(runUpdateWithoutKeys); + FINALIZER(runClearTable); +} +TESTCASE("UpdateWithoutValues", + "Test that it's not possible to perform update without setValues\n"){ + INITIALIZER(runLoadTable); + INITIALIZER(runUpdateWithoutValues); + FINALIZER(runClearTable); +} +TESTCASE("NdbErrorOperation", + "Test that NdbErrorOperation is properly set"){ + INITIALIZER(runCheckGetNdbErrorOperation); +} +#endif +NDBT_TESTSUITE_END(testInterpreter); + +int main(int argc, const char** argv){ + // TABLE("T1"); + return testInterpreter.execute(argc, argv); +} + + diff --git a/ndb/test/ndbapi/testInterpreter/Makefile b/ndb/test/ndbapi/testInterpreter/Makefile deleted file mode 100644 index e84287a1b16..00000000000 --- a/ndb/test/ndbapi/testInterpreter/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include .defs.mk - -TYPE = ndbapitest - -BIN_TARGET = testInterpreter - -SOURCES = testInterpreter.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/testInterpreter/testInterpreter.cpp b/ndb/test/ndbapi/testInterpreter/testInterpreter.cpp deleted file mode 100644 index 9c584d6f581..00000000000 --- a/ndb/test/ndbapi/testInterpreter/testInterpreter.cpp +++ /dev/null @@ -1,231 +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 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define CHECK(b) if (!(b)) { \ - ndbout << "ERR: "<< step->getName() \ - << " failed on line " << __LINE__ << endl; \ - result = NDBT_FAILED; \ - continue; } - -int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - int batchSize = ctx->getProperty("BatchSize", 1); - - HugoTransactions hugoTrans(*ctx->getTab()); - if (hugoTrans.pkDelRecords(GETNDB(step), records, batchSize) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ - - int records = ctx->getNumRecords(); - HugoTransactions hugoTrans(*ctx->getTab()); - if (hugoTrans.loadTable(GETNDB(step), records) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runTestIncValue64(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - // NDBT_Table* pTab = ctx->getTab(); - //Ndb* pNdb = GETNDB(step); - - HugoTransactions hugoTrans(*ctx->getTab()); - if (hugoTrans.pkInterpretedUpdateRecords(GETNDB(step), - records) != 0){ - return NDBT_FAILED; - } - - // Verify the update - if (hugoTrans.pkReadRecords(GETNDB(step), - records) != 0){ - return NDBT_FAILED; - } - - return NDBT_OK; - -} - -int runTestIncValue32(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - const NdbDictionary::Table * pTab = ctx->getTab(); - Ndb* pNdb = GETNDB(step); - - - NdbConnection* pTrans = pNdb->startTransaction(); - if (pTrans == NULL){ - ERR(pNdb->getNdbError()); - return NDBT_FAILED; - } - - NdbOperation* pOp = pTrans->getNdbOperation(pTab->getName()); - if (pOp == NULL) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - - int check = pOp->interpretedUpdateTuple(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - - - // Primary keys - Uint32 pkVal = 1; - check = pOp->equal("KOL1", pkVal ); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - - // Attributes - - // Update column - Uint32 valToIncWith = 1; - check = pOp->incValue("KOL2", valToIncWith); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - - NdbRecAttr* valueRec = pOp->getValue("KOL2"); - if( valueRec == NULL ) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pTrans->execute(Commit); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - - Uint32 value = valueRec->u_32_value(); - - pNdb->closeTransaction(pTrans); - - - return NDBT_OK; -} - - -NDBT_TESTSUITE(testInterpreter); -TESTCASE("IncValue32", - "Test incValue for 32 bit integer\n"){ - INITIALIZER(runLoadTable); - INITIALIZER(runTestIncValue32); - FINALIZER(runClearTable); -} -TESTCASE("IncValue64", - "Test incValue for 64 bit integer\n"){ - INITIALIZER(runLoadTable); - INITIALIZER(runTestIncValue64); - FINALIZER(runClearTable); -} -#if 0 -TESTCASE("MaxTransactions", - "Start transactions until no more can be created\n"){ - INITIALIZER(runTestMaxTransaction); -} -TESTCASE("MaxOperations", - "Get operations until no more can be created\n"){ - INITIALIZER(runLoadTable); - INITIALIZER(runTestMaxOperations); - FINALIZER(runClearTable); -} -TESTCASE("MaxGetValue", - "Call getValue loads of time\n"){ - INITIALIZER(runLoadTable); - INITIALIZER(runTestGetValue); - FINALIZER(runClearTable); -} -TESTCASE("MaxEqual", - "Call equal loads of time\n"){ - INITIALIZER(runTestEqual); -} -TESTCASE("DeleteNdb", - "Make sure that a deleted Ndb object is properly deleted\n" - "and removed from transporter\n"){ - INITIALIZER(runLoadTable); - INITIALIZER(runTestDeleteNdb); - FINALIZER(runClearTable); -} -TESTCASE("WaitUntilReady", - "Make sure you get an error message when calling waitUntilReady\n" - "without an init'ed Ndb\n"){ - INITIALIZER(runTestWaitUntilReady); -} -TESTCASE("GetOperationNoTab", - "Call getNdbOperation on a table that does not exist\n"){ - INITIALIZER(runGetNdbOperationNoTab); -} -TESTCASE("MissingOperation", - "Missing operation request(insertTuple) should give an error code\n"){ - INITIALIZER(runMissingOperation); -} -TESTCASE("GetValueInUpdate", - "Test that it's not possible to perform getValue in an update\n"){ - INITIALIZER(runLoadTable); - INITIALIZER(runGetValueInUpdate); - FINALIZER(runClearTable); -} -TESTCASE("UpdateWithoutKeys", - "Test that it's not possible to perform update without setting\n" - "PKs"){ - INITIALIZER(runLoadTable); - INITIALIZER(runUpdateWithoutKeys); - FINALIZER(runClearTable); -} -TESTCASE("UpdateWithoutValues", - "Test that it's not possible to perform update without setValues\n"){ - INITIALIZER(runLoadTable); - INITIALIZER(runUpdateWithoutValues); - FINALIZER(runClearTable); -} -TESTCASE("NdbErrorOperation", - "Test that NdbErrorOperation is properly set"){ - INITIALIZER(runCheckGetNdbErrorOperation); -} -#endif -NDBT_TESTSUITE_END(testInterpreter); - -int main(int argc, const char** argv){ - // TABLE("T1"); - return testInterpreter.execute(argc, argv); -} - - diff --git a/ndb/test/ndbapi/testMgm.cpp b/ndb/test/ndbapi/testMgm.cpp new file mode 100644 index 00000000000..d5b9372cc9b --- /dev/null +++ b/ndb/test/ndbapi/testMgm.cpp @@ -0,0 +1,184 @@ +/* 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 */ + +#include +#include +#include +#include +#include +#include +#include + +int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ + + int records = ctx->getNumRecords(); + HugoTransactions hugoTrans(*ctx->getTab()); + if (hugoTrans.loadTable(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + + UtilTransactions utilTrans(*ctx->getTab()); + if (utilTrans.clearTable2(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + + +int create_index_on_pk(Ndb* pNdb, const char* tabName){ + int result = NDBT_OK; + + const NdbDictionary::Table * tab = NDBT_Table::discoverTableFromDb(pNdb, + tabName); + + // Create index + const char* idxName = "IDX_ON_PK"; + ndbout << "Create: " <getNoOfPrimaryKeys(); c++){ + pIdx.addIndexColumn(tab->getPrimaryKey(c)); + ndbout << tab->getPrimaryKey(c)<<" "; + } + + ndbout << ") "; + if (pNdb->getDictionary()->createIndex(pIdx) != 0){ + ndbout << "FAILED!" << endl; + const NdbError err = pNdb->getDictionary()->getNdbError(); + ERR(err); + result = NDBT_FAILED; + } else { + ndbout << "OK!" << endl; + } + return result; +} + +int drop_index_on_pk(Ndb* pNdb, const char* tabName){ + int result = NDBT_OK; + const char* idxName = "IDX_ON_PK"; + ndbout << "Drop: " << idxName; + if (pNdb->getDictionary()->dropIndex(idxName, tabName) != 0){ + ndbout << "FAILED!" << endl; + const NdbError err = pNdb->getDictionary()->getNdbError(); + ERR(err); + result = NDBT_FAILED; + } else { + ndbout << "OK!" << endl; + } + return result; +} + + +#define CHECK(b) if (!(b)) { \ + g_err << "ERR: "<< step->getName() \ + << " failed on line " << __LINE__ << endl; \ + result = NDBT_FAILED; \ + continue; } + +int runTestSingleUserMode(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + Ndb* pNdb = GETNDB(step); + NdbRestarter restarter; + char tabName[255]; + strncpy(tabName, ctx->getTab()->getName(), 255); + ndbout << "tabName="<getTab()); + UtilTransactions utilTrans(*ctx->getTab()); + while (igetNodeId()) == 0); + CHECK(restarter.waitClusterSingleUser(timeout) == 0); + CHECK(hugoTrans.loadTable(pNdb, records, 128) == 0); + CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0); + CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == records); + CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); + CHECK(hugoTrans.scanReadRecords(pNdb, records/2, 0, 64) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == (records/2)); + CHECK(utilTrans.clearTable(pNdb, records/2) == 0); + CHECK(restarter.exitSingleUserMode() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + + // Test create index in single user mode + CHECK(restarter.enterSingleUserMode(pNdb->getNodeId()) == 0); + CHECK(restarter.waitClusterSingleUser(timeout) == 0); + CHECK(create_index_on_pk(pNdb, tabName) == 0); + CHECK(hugoTrans.loadTable(pNdb, records, 128) == 0); + CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0); + CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == records); + CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); + CHECK(drop_index_on_pk(pNdb, tabName) == 0); + CHECK(restarter.exitSingleUserMode() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + + // Test recreate index in single user mode + CHECK(create_index_on_pk(pNdb, tabName) == 0); + CHECK(hugoTrans.loadTable(pNdb, records, 128) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(restarter.enterSingleUserMode(pNdb->getNodeId()) == 0); + CHECK(restarter.waitClusterSingleUser(timeout) == 0); + CHECK(drop_index_on_pk(pNdb, tabName) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(create_index_on_pk(pNdb, tabName) == 0); + CHECK(restarter.exitSingleUserMode() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(drop_index_on_pk(pNdb, tabName) == 0); + + CHECK(utilTrans.clearTable(GETNDB(step), records) == 0); + + ndbout << "Restarting cluster" << endl; + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(pNdb->waitUntilReady(timeout) == 0); + + i++; + + } + return result; +} + + + +NDBT_TESTSUITE(testMgm); +TESTCASE("SingleUserMode", + "Test single user mode"){ + INITIALIZER(runTestSingleUserMode); + FINALIZER(runClearTable); +} +NDBT_TESTSUITE_END(testMgm); + +int main(int argc, const char** argv){ + myRandom48Init(NdbTick_CurrentMillisecond()); + return testMgm.execute(argc, argv); +} + diff --git a/ndb/test/ndbapi/testMgm/Makefile b/ndb/test/ndbapi/testMgm/Makefile deleted file mode 100644 index be50d3dae7e..00000000000 --- a/ndb/test/ndbapi/testMgm/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include .defs.mk - -TYPE = ndbapitest - -BIN_TARGET = testMgm - -SOURCES = testMgm.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/testMgm/testMgm.cpp b/ndb/test/ndbapi/testMgm/testMgm.cpp deleted file mode 100644 index d5b9372cc9b..00000000000 --- a/ndb/test/ndbapi/testMgm/testMgm.cpp +++ /dev/null @@ -1,184 +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 */ - -#include -#include -#include -#include -#include -#include -#include - -int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ - - int records = ctx->getNumRecords(); - HugoTransactions hugoTrans(*ctx->getTab()); - if (hugoTrans.loadTable(GETNDB(step), records) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - - UtilTransactions utilTrans(*ctx->getTab()); - if (utilTrans.clearTable2(GETNDB(step), records) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - - -int create_index_on_pk(Ndb* pNdb, const char* tabName){ - int result = NDBT_OK; - - const NdbDictionary::Table * tab = NDBT_Table::discoverTableFromDb(pNdb, - tabName); - - // Create index - const char* idxName = "IDX_ON_PK"; - ndbout << "Create: " <getNoOfPrimaryKeys(); c++){ - pIdx.addIndexColumn(tab->getPrimaryKey(c)); - ndbout << tab->getPrimaryKey(c)<<" "; - } - - ndbout << ") "; - if (pNdb->getDictionary()->createIndex(pIdx) != 0){ - ndbout << "FAILED!" << endl; - const NdbError err = pNdb->getDictionary()->getNdbError(); - ERR(err); - result = NDBT_FAILED; - } else { - ndbout << "OK!" << endl; - } - return result; -} - -int drop_index_on_pk(Ndb* pNdb, const char* tabName){ - int result = NDBT_OK; - const char* idxName = "IDX_ON_PK"; - ndbout << "Drop: " << idxName; - if (pNdb->getDictionary()->dropIndex(idxName, tabName) != 0){ - ndbout << "FAILED!" << endl; - const NdbError err = pNdb->getDictionary()->getNdbError(); - ERR(err); - result = NDBT_FAILED; - } else { - ndbout << "OK!" << endl; - } - return result; -} - - -#define CHECK(b) if (!(b)) { \ - g_err << "ERR: "<< step->getName() \ - << " failed on line " << __LINE__ << endl; \ - result = NDBT_FAILED; \ - continue; } - -int runTestSingleUserMode(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - int loops = ctx->getNumLoops(); - int records = ctx->getNumRecords(); - Ndb* pNdb = GETNDB(step); - NdbRestarter restarter; - char tabName[255]; - strncpy(tabName, ctx->getTab()->getName(), 255); - ndbout << "tabName="<getTab()); - UtilTransactions utilTrans(*ctx->getTab()); - while (igetNodeId()) == 0); - CHECK(restarter.waitClusterSingleUser(timeout) == 0); - CHECK(hugoTrans.loadTable(pNdb, records, 128) == 0); - CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0); - CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == records); - CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); - CHECK(hugoTrans.scanReadRecords(pNdb, records/2, 0, 64) == 0); - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == (records/2)); - CHECK(utilTrans.clearTable(pNdb, records/2) == 0); - CHECK(restarter.exitSingleUserMode() == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - - // Test create index in single user mode - CHECK(restarter.enterSingleUserMode(pNdb->getNodeId()) == 0); - CHECK(restarter.waitClusterSingleUser(timeout) == 0); - CHECK(create_index_on_pk(pNdb, tabName) == 0); - CHECK(hugoTrans.loadTable(pNdb, records, 128) == 0); - CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0); - CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == records); - CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); - CHECK(drop_index_on_pk(pNdb, tabName) == 0); - CHECK(restarter.exitSingleUserMode() == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - - // Test recreate index in single user mode - CHECK(create_index_on_pk(pNdb, tabName) == 0); - CHECK(hugoTrans.loadTable(pNdb, records, 128) == 0); - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(restarter.enterSingleUserMode(pNdb->getNodeId()) == 0); - CHECK(restarter.waitClusterSingleUser(timeout) == 0); - CHECK(drop_index_on_pk(pNdb, tabName) == 0); - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(create_index_on_pk(pNdb, tabName) == 0); - CHECK(restarter.exitSingleUserMode() == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - CHECK(drop_index_on_pk(pNdb, tabName) == 0); - - CHECK(utilTrans.clearTable(GETNDB(step), records) == 0); - - ndbout << "Restarting cluster" << endl; - CHECK(restarter.restartAll() == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - CHECK(pNdb->waitUntilReady(timeout) == 0); - - i++; - - } - return result; -} - - - -NDBT_TESTSUITE(testMgm); -TESTCASE("SingleUserMode", - "Test single user mode"){ - INITIALIZER(runTestSingleUserMode); - FINALIZER(runClearTable); -} -NDBT_TESTSUITE_END(testMgm); - -int main(int argc, const char** argv){ - myRandom48Init(NdbTick_CurrentMillisecond()); - return testMgm.execute(argc, argv); -} - diff --git a/ndb/test/ndbapi/testNdbApi.cpp b/ndb/test/ndbapi/testNdbApi.cpp new file mode 100644 index 00000000000..c0e262f590f --- /dev/null +++ b/ndb/test/ndbapi/testNdbApi.cpp @@ -0,0 +1,1013 @@ +/* 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 */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define CHECK(b) if (!(b)) { \ + ndbout << "ERR: "<< step->getName() \ + << " failed on line " << __LINE__ << endl; \ + result = NDBT_FAILED; \ + continue; } + +#define CHECKE(b) if (!(b)) { \ + errors++; \ + ndbout << "ERR: "<< step->getName() \ + << " failed on line " << __LINE__ << endl; \ + result = NDBT_FAILED; \ + continue; } + + +int runTestMaxNdb(NDBT_Context* ctx, NDBT_Step* step){ + Uint32 loops = ctx->getNumLoops(); + Uint32 l = 0; + int oldi = 0; + int result = NDBT_OK; + + while (l < loops && result == NDBT_OK){ + ndbout_c("loop %d", l + 1); + int errors = 0; + int maxErrors = 5; + + Vector ndbVector; + int i = 0; + int init = 0; + do { + + Ndb* pNdb = new Ndb("TEST_DB"); + if (pNdb == NULL){ + ndbout << "pNdb == NULL" << endl; + errors++; + continue; + + } + i++; + + ndbVector.push_back(pNdb); + + if (pNdb->init()){ + ERR(pNdb->getNdbError()); + errors++; + continue; + } + + init++; + + } while (errors == 0); + + ndbout << i << " ndb objects created" << endl; + + if (l > 0 && i != oldi && init != MAX_NO_THREADS){ + ndbout << l << ": not as manyNdb objects created" << endl + << i << " != " << oldi << endl; + result = NDBT_FAILED; + } + + oldi = i; + + + for(size_t i = 0; i < ndbVector.size(); i++){ + delete ndbVector[i]; + if(((i+1) % 250) == 0){ + ndbout << "Deleted " << (Uint64) i << " ndb objects " << endl; + } + } + ndbVector.clear(); + + l++; + } + + return result; +} + +int runTestMaxTransaction(NDBT_Context* ctx, NDBT_Step* step){ + Uint32 loops = ctx->getNumLoops(); + Uint32 l = 0; + int oldi = 0; + int result = NDBT_OK; + + Ndb* pNdb = new Ndb("TEST_DB"); + if (pNdb == NULL){ + ndbout << "pNdb == NULL" << endl; + return NDBT_FAILED; + } + if (pNdb->init(2048)){ + ERR(pNdb->getNdbError()); + delete pNdb; + return NDBT_FAILED; + } + + while (l < loops && result == NDBT_OK){ + int errors = 0; + int maxErrors = 5; + + Vector conVector; + + + int i = 0; + do { + + NdbConnection* pCon; + + int type = i%4; + switch (type){ + case 0: + pCon = pNdb->startTransaction(); + break; + case 1: + pCon = pNdb->startTransaction(2, + "DATA", + 4); + break; + case 2: + pCon = pNdb->startTransactionDGroup(1, + "TEST", + 0); + break; + case 3: + pCon = pNdb->startTransactionDGroup(2, + "TEST", + 1); + break; + + default: + abort(); + } + + if (pCon == NULL){ + ERR(pNdb->getNdbError()); + errors++; + continue; + } + + conVector.push_back(pCon); + + i++; + } while (errors < maxErrors); + + ndbout << i << " connections created" << endl; + + if (l > 0 && i != oldi){ + ndbout << l << ": not as many transactions created" << endl + << i << " != " << oldi << endl; + result = NDBT_FAILED; + } + + oldi = i; + + + for(size_t i = 0; i < conVector.size(); i++){ + pNdb->closeTransaction(conVector[i]); + } + conVector.clear(); + l++; + + } + + // BONUS Test closeTransaction with null trans + pNdb->closeTransaction(NULL); + + delete pNdb; + + + return result; +} + +int runTestMaxOperations(NDBT_Context* ctx, NDBT_Step* step){ + Uint32 l = 1; + int result = NDBT_OK; + int maxOpsLimit = 1; + const NdbDictionary::Table* pTab = ctx->getTab(); + + Ndb* pNdb = new Ndb("TEST_DB"); + if (pNdb == NULL){ + ndbout << "pNdb == NULL" << endl; + return NDBT_FAILED; + } + if (pNdb->init(2048)){ + ERR(pNdb->getNdbError()); + delete pNdb; + return NDBT_FAILED; + } + + HugoOperations hugoOps(*pTab); + + bool endTest = false; + while (!endTest && result == NDBT_OK){ + int errors = 0; + int maxErrors = 5; + + maxOpsLimit = l*1000; + + if (hugoOps.startTransaction(pNdb) != NDBT_OK){ + delete pNdb; + return NDBT_FAILED; + } + + int i = 0; + while (errors < maxErrors){ + + if(hugoOps.pkReadRecord(pNdb,1, false, 1) != NDBT_OK){ + errors++; + continue; + } + + i++; + + if (i >= maxOpsLimit){ + errors = maxErrors; + } + + } + + ndbout << i << " operations used" << endl; + + int execResult = hugoOps.execute_Commit(pNdb); + switch(execResult){ + case NDBT_OK: + break; + case 233: // Out of operation records in transaction coordinator + // OK - end test + endTest = true; + break; + default: + result = NDBT_FAILED; + break; + } + + hugoOps.closeTransaction(pNdb); + + l++; + + } + + delete pNdb; + + return result; +} + +int runTestGetValue(NDBT_Context* ctx, NDBT_Step* step){ + + int result = NDBT_OK; + const NdbDictionary::Table* pTab = ctx->getTab(); + + Ndb* pNdb = new Ndb("TEST_DB"); + if (pNdb == NULL){ + ndbout << "pNdb == NULL" << endl; + return NDBT_FAILED; + } + if (pNdb->init(2048)){ + ERR(pNdb->getNdbError()); + delete pNdb; + return NDBT_FAILED; + } + + HugoOperations hugoOps(*pTab); + + for (int m = 1; m < 100; m++){ + int errors = 0; + int maxErrors = 5; + + NdbConnection* pCon = pNdb->startTransaction(); + if (pCon == NULL){ + delete pNdb; + return NDBT_FAILED; + } + + NdbOperation* pOp = pCon->getNdbOperation(pTab->getName()); + if (pOp == NULL){ + pNdb->closeTransaction(pCon); + delete pNdb; + return NDBT_FAILED; + } + + if (pOp->readTuple() != 0){ + pNdb->closeTransaction(pCon); + delete pNdb; + return NDBT_FAILED; + } + + for(int a = 0; agetNoOfColumns(); a++){ + if (pTab->getColumn(a)->getPrimaryKey() == true){ + if(hugoOps.equalForAttr(pOp, a, 1) != 0){ + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + delete pNdb; + return NDBT_FAILED; + } + } + } + + int i = 0; + int maxLimit = 1000*m; + do { + + if (pOp->getValue(pTab->getColumn(1)->getName()) == NULL) { + const NdbError err = pCon->getNdbError(); + ERR(err); + if (err.code == 0) + result = NDBT_FAILED; + errors++; + continue; + } + + i++; + + } while (errors < maxErrors && i < maxLimit); + + ndbout << i << " getValues called" << endl; + + + if (pCon->execute(Commit) != 0){ + const NdbError err = pCon->getNdbError(); + switch(err.code){ + case 880: // TUP - Read too much + case 823: // TUP - Too much AI + case 4257: // NDBAPI - Too much AI + // OK errors + ERR(pCon->getNdbError()); + break; + default: + ERR(pCon->getNdbError()); + ndbout << "Illegal error" << endl; + result= NDBT_FAILED; + break; + } + } + + pNdb->closeTransaction(pCon); + + }// m + + + delete pNdb; + + return result; +} + +int runTestEqual(NDBT_Context* ctx, NDBT_Step* step){ + Uint32 loops = ctx->getNumLoops(); + Uint32 l = 0; + int result = NDBT_OK; + const NdbDictionary::Table* pTab = ctx->getTab(); + + Ndb* pNdb = new Ndb("TEST_DB"); + if (pNdb == NULL){ + ndbout << "pNdb == NULL" << endl; + return NDBT_FAILED; + } + if (pNdb->init(2048)){ + ERR(pNdb->getNdbError()); + delete pNdb; + return NDBT_FAILED; + } + + HugoOperations hugoOps(*pTab); + + while (l < loops){ + for(int m = 1; m < 10; m++){ + int errors = 0; + int maxErrors = 5; + + NdbConnection* pCon = pNdb->startTransaction(); + if (pCon == NULL){ + ndbout << "Could not start transaction" << endl; + delete pNdb; + return NDBT_FAILED; + } + + NdbOperation* pOp = pCon->getNdbOperation(pTab->getName()); + if (pOp == NULL){ + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + delete pNdb; + return NDBT_FAILED; + } + + if (pOp->readTuple() != 0){ + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + delete pNdb; + return NDBT_FAILED; + } + + int i = 0; + int maxLimit = 1000*m; + do { + + if ((l%2)!=0){ + // Forward + for(int a = 0; agetNoOfColumns(); a++){ + if (pTab->getColumn(a)->getPrimaryKey() == true){ + if(hugoOps.equalForAttr(pOp, a, 1) != 0){ + const NdbError err = pCon->getNdbError(); + ERR(err); + if (err.code == 0) + result = NDBT_FAILED; + errors++; + } + } + } + } else { + // Backward + for(int a = pTab->getNoOfColumns()-1; a>=0; a--){ + if (pTab->getColumn(a)->getPrimaryKey() == true){ + if(hugoOps.equalForAttr(pOp, a, 1) != 0){ + const NdbError err = pCon->getNdbError(); + ERR(err); + if (err.code == 0) + result = NDBT_FAILED; + errors++; + } + } + } + } + + i++; + + } while (errors < maxErrors && i < maxLimit); + + if (pOp->getValue(pTab->getColumn(1)->getName()) == NULL) { + const NdbError err = pCon->getNdbError(); + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + delete pNdb; + if (err.code == 4225) { + return NDBT_OK; + } else { + return NDBT_FAILED; + }//if + } + + ndbout << i << " equal called" << endl; + + + int check = pCon->execute(Commit); + if (check != 0){ + ERR(pCon->getNdbError()); + } + + pNdb->closeTransaction(pCon); + + }// m + l++; + + }// l + + delete pNdb; + return result; +} + +int runTestDeleteNdb(NDBT_Context* ctx, NDBT_Step* step){ + Uint32 loops = ctx->getNumLoops(); + Uint32 l = 0; + int result = NDBT_OK; + NdbRestarts restarts; + Vector ndbVector; + const NdbDictionary::Table* pTab = ctx->getTab(); + HugoTransactions hugoTrans(*pTab); + int records = ctx->getNumRecords(); + + while (l < loops && result == NDBT_OK){ + + // Create 5 ndb objects + for( int i = 0; i < 5; i++){ + Ndb* pNdb = new Ndb("TEST_DB"); + if (pNdb == NULL){ + ndbout << "pNdb == NULL" << endl; + result = NDBT_FAILED; + goto end_test; + } + ndbVector.push_back(pNdb); + + if (pNdb->init()){ + ERR(pNdb->getNdbError()); + result = NDBT_FAILED; + goto end_test; + } + if (pNdb->waitUntilReady() != 0){ + ERR(pNdb->getNdbError()); + result = NDBT_FAILED; + goto end_test; + } + if (hugoTrans.pkReadRecords(pNdb, records) != 0){ + result = NDBT_FAILED; + goto end_test; + } + } + + if ((l % 2) == 0){ + // Restart random node + ndbout << "Restart random node " << endl; + if(restarts.executeRestart("RestartRandomNodeAbort", 120) != 0){ + g_err << "Failed to executeRestart(RestartRandomNode)"<getNumRecords(); + + UtilTransactions utilTrans(*ctx->getTab()); + if (utilTrans.clearTable2(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} +int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ + + int records = ctx->getNumRecords(); + HugoTransactions hugoTrans(*ctx->getTab()); + if (hugoTrans.loadTable(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runTestWaitUntilReady(NDBT_Context* ctx, NDBT_Step* step){ + + Ndb* pNdb = new Ndb("TEST_DB"); + + // Forget about calling pNdb->init(); + + if (pNdb->waitUntilReady() == 0){ + ndbout << "waitUntilReady returned OK" << endl; + delete pNdb; + return NDBT_FAILED; + } + const NdbError err = pNdb->getNdbError(); + delete pNdb; + + ERR(err); + if (err.code != 4256) + return NDBT_FAILED; + + return NDBT_OK; +} + +int runGetNdbOperationNoTab(NDBT_Context* ctx, NDBT_Step* step){ + + Ndb* pNdb = new Ndb("TEST_DB"); + if (pNdb == NULL){ + ndbout << "pNdb == NULL" << endl; + return NDBT_FAILED; + } + if (pNdb->init()){ + ERR(pNdb->getNdbError()); + delete pNdb; + return NDBT_FAILED; + } + + NdbConnection* pCon = pNdb->startTransaction(); + if (pCon == NULL){ + delete pNdb; + return NDBT_FAILED; + } + + // Call getNdbOperation on an unknown table + NdbOperation* pOp = pCon->getNdbOperation("HUPP76"); + if (pOp == NULL){ + NdbError err = pCon->getNdbError(); + ERR(err); + if (err.code == 0){ + pNdb->closeTransaction(pCon); + delete pNdb; + return NDBT_FAILED; + } + } + + pNdb->closeTransaction(pCon); + + delete pNdb; + + return NDBT_OK; +} + +int runMissingOperation(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + const NdbDictionary::Table* pTab = ctx->getTab(); + + + Ndb* pNdb = new Ndb("TEST_DB"); + if (pNdb == NULL){ + ndbout << "pNdb == NULL" << endl; + return NDBT_FAILED; + } + if (pNdb->init()){ + ERR(pNdb->getNdbError()); + delete pNdb; + return NDBT_FAILED; + } + + NdbConnection* pCon = pNdb->startTransaction(); + if (pCon == NULL){ + pNdb->closeTransaction(pCon); + delete pNdb; + return NDBT_FAILED; + } + + NdbOperation* pOp = pCon->getNdbOperation(pTab->getName()); + if (pOp == NULL){ + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + delete pNdb; + return NDBT_FAILED; + } + + // Forget about calling pOp->insertTuple(); + + // Call getValue should not work + if (pOp->getValue(pTab->getColumn(1)->getName()) == NULL) { + const NdbError err = pCon->getNdbError(); + ERR(err); + if (err.code == 0){ + ndbout << "hupp" << endl; + result = NDBT_FAILED; + } + } else { + ndbout << "hupp2" << endl; + result = NDBT_FAILED; + } + + pNdb->closeTransaction(pCon); + delete pNdb; + + return result; +} + +int runGetValueInUpdate(NDBT_Context* ctx, NDBT_Step* step){ + const NdbDictionary::Table* pTab = ctx->getTab(); + + Ndb* pNdb = new Ndb("TEST_DB"); + if (pNdb == NULL){ + ndbout << "pNdb == NULL" << endl; + return NDBT_FAILED; + } + if (pNdb->init()){ + ERR(pNdb->getNdbError()); + delete pNdb; + return NDBT_FAILED; + } + + NdbConnection* pCon = pNdb->startTransaction(); + if (pCon == NULL){ + pNdb->closeTransaction(pCon); + delete pNdb; + return NDBT_FAILED; + } + + NdbOperation* pOp = pCon->getNdbOperation(pTab->getName()); + if (pOp == NULL){ + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + delete pNdb; + return NDBT_FAILED; + } + + if (pOp->updateTuple() != 0){ + pNdb->closeTransaction(pCon); + delete pNdb; + return NDBT_FAILED; + } + + // Call getValue should not work + if (pOp->getValue(pTab->getColumn(1)->getName()) == NULL) { + // It didn't work + const NdbError err = pCon->getNdbError(); + ERR(err); + if (err.code == 0){ + pNdb->closeTransaction(pCon); + delete pNdb; + return NDBT_FAILED; + } + } else { + // It worked, not good! + pNdb->closeTransaction(pCon); + delete pNdb; + return NDBT_FAILED; + } + + int check = pCon->execute(Commit); + if (check != 0){ + ERR(pCon->getNdbError()); + } + + pNdb->closeTransaction(pCon); + delete pNdb; + + return NDBT_OK; +} + +int runUpdateWithoutValues(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + const NdbDictionary::Table* pTab = ctx->getTab(); + + HugoOperations hugoOps(*pTab); + + Ndb* pNdb = new Ndb("TEST_DB"); + if (pNdb == NULL){ + ndbout << "pNdb == NULL" << endl; + return NDBT_FAILED; + } + if (pNdb->init()){ + ERR(pNdb->getNdbError()); + delete pNdb; + return NDBT_FAILED; + } + + NdbConnection* pCon = pNdb->startTransaction(); + if (pCon == NULL){ + pNdb->closeTransaction(pCon); + delete pNdb; + return NDBT_FAILED; + } + + NdbOperation* pOp = pCon->getNdbOperation(pTab->getName()); + if (pOp == NULL){ + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + delete pNdb; + return NDBT_FAILED; + } + + if (pOp->updateTuple() != 0){ + pNdb->closeTransaction(pCon); + ERR(pOp->getNdbError()); + delete pNdb; + return NDBT_FAILED; + } + + for(int a = 0; agetNoOfColumns(); a++){ + if (pTab->getColumn(a)->getPrimaryKey() == true){ + if(hugoOps.equalForAttr(pOp, a, 1) != 0){ + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + delete pNdb; + return NDBT_FAILED; + } + } + } + + // Dont' call any setValues + + // Execute should not work + int check = pCon->execute(Commit); + if (check == 0){ + ndbout << "execute worked" << endl; + result = NDBT_FAILED; + } else { + ERR(pCon->getNdbError()); + } + + pNdb->closeTransaction(pCon); + delete pNdb; + + return result; +} + +int runUpdateWithoutKeys(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + const NdbDictionary::Table* pTab = ctx->getTab(); + + + Ndb* pNdb = new Ndb("TEST_DB"); + if (pNdb == NULL){ + ndbout << "pNdb == NULL" << endl; + return NDBT_FAILED; + } + if (pNdb->init()){ + ERR(pNdb->getNdbError()); + delete pNdb; + return NDBT_FAILED; + } + + NdbConnection* pCon = pNdb->startTransaction(); + if (pCon == NULL){ + pNdb->closeTransaction(pCon); + delete pNdb; + return NDBT_FAILED; + } + + NdbOperation* pOp = pCon->getNdbOperation(pTab->getName()); + if (pOp == NULL){ + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + delete pNdb; + return NDBT_FAILED; + } + + if (pOp->updateTuple() != 0){ + pNdb->closeTransaction(pCon); + ERR(pOp->getNdbError()); + delete pNdb; + return NDBT_FAILED; + } + + // Dont' call any equal or setValues + + // Execute should not work + int check = pCon->execute(Commit); + if (check == 0){ + ndbout << "execute worked" << endl; + result = NDBT_FAILED; + } else { + ERR(pCon->getNdbError()); + } + + pNdb->closeTransaction(pCon); + delete pNdb; + + return result; +} + +int runCheckGetNdbErrorOperation(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + const NdbDictionary::Table* pTab = ctx->getTab(); + + Ndb* pNdb = new Ndb("TEST_DB"); + if (pNdb == NULL){ + ndbout << "pNdb == NULL" << endl; + return NDBT_FAILED; + } + if (pNdb->init(2048)){ + ERR(pNdb->getNdbError()); + delete pNdb; + return NDBT_FAILED; + } + + HugoOperations hugoOps(*pTab); + + + NdbConnection* pCon = pNdb->startTransaction(); + if (pCon == NULL){ + ndbout << "Could not start transaction" << endl; + delete pNdb; + return NDBT_FAILED; + } + + NdbOperation* pOp = pCon->getNdbOperation(pTab->getName()); + if (pOp == NULL){ + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + delete pNdb; + return NDBT_FAILED; + } + + // Dont call readTuple here + // That's the error! + + for(int a = 0; agetNoOfColumns(); a++){ + if (pTab->getColumn(a)->getPrimaryKey() == true){ + if(hugoOps.equalForAttr(pOp, a, 1) != 0){ + // An error has occured, check that + // it's possible to get the NdbErrorOperation + const NdbError err = pCon->getNdbError(); + ERR(err); + if (err.code == 0) + result = NDBT_FAILED; + + NdbOperation* pOp2 = pCon->getNdbErrorOperation(); + if (pOp2 == NULL) + result = NDBT_FAILED; + else { + const NdbError err2 = pOp2->getNdbError(); + ERR(err2); + if (err.code == 0) + result = NDBT_FAILED; + } + } + } + } + + pNdb->closeTransaction(pCon); + + delete pNdb; + return result; +} + + +NDBT_TESTSUITE(testNdbApi); +TESTCASE("MaxNdb", + "Create Ndb objects until no more can be created\n"){ + INITIALIZER(runTestMaxNdb); +} +TESTCASE("MaxTransactions", + "Start transactions until no more can be created\n"){ + INITIALIZER(runTestMaxTransaction); +} +TESTCASE("MaxOperations", + "Get operations until no more can be created\n"){ + INITIALIZER(runLoadTable); + INITIALIZER(runTestMaxOperations); + FINALIZER(runClearTable); +} +TESTCASE("MaxGetValue", + "Call getValue loads of time\n"){ + INITIALIZER(runLoadTable); + INITIALIZER(runTestGetValue); + FINALIZER(runClearTable); +} +TESTCASE("MaxEqual", + "Call equal loads of time\n"){ + INITIALIZER(runTestEqual); +} +TESTCASE("DeleteNdb", + "Make sure that a deleted Ndb object is properly deleted\n" + "and removed from transporter\n"){ + INITIALIZER(runLoadTable); + INITIALIZER(runTestDeleteNdb); + FINALIZER(runClearTable); +} +TESTCASE("WaitUntilReady", + "Make sure you get an error message when calling waitUntilReady\n" + "without an init'ed Ndb\n"){ + INITIALIZER(runTestWaitUntilReady); +} +TESTCASE("GetOperationNoTab", + "Call getNdbOperation on a table that does not exist\n"){ + INITIALIZER(runGetNdbOperationNoTab); +} +TESTCASE("MissingOperation", + "Missing operation request(insertTuple) should give an error code\n"){ + INITIALIZER(runMissingOperation); +} +TESTCASE("GetValueInUpdate", + "Test that it's not possible to perform getValue in an update\n"){ + INITIALIZER(runLoadTable); + INITIALIZER(runGetValueInUpdate); + FINALIZER(runClearTable); +} +TESTCASE("UpdateWithoutKeys", + "Test that it's not possible to perform update without setting\n" + "PKs"){ + INITIALIZER(runLoadTable); + INITIALIZER(runUpdateWithoutKeys); + FINALIZER(runClearTable); +} +TESTCASE("UpdateWithoutValues", + "Test that it's not possible to perform update without setValues\n"){ + INITIALIZER(runLoadTable); + INITIALIZER(runUpdateWithoutValues); + FINALIZER(runClearTable); +} +TESTCASE("NdbErrorOperation", + "Test that NdbErrorOperation is properly set"){ + INITIALIZER(runCheckGetNdbErrorOperation); +} +NDBT_TESTSUITE_END(testNdbApi); + +int main(int argc, const char** argv){ + // TABLE("T1"); + return testNdbApi.execute(argc, argv); +} + + diff --git a/ndb/test/ndbapi/testNdbApi/Makefile b/ndb/test/ndbapi/testNdbApi/Makefile deleted file mode 100644 index 3bb3cba427e..00000000000 --- a/ndb/test/ndbapi/testNdbApi/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include .defs.mk - -TYPE = ndbapitest - -BIN_TARGET = testNdbApi - -SOURCES = testNdbApi.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/testNdbApi/testNdbApi.cpp b/ndb/test/ndbapi/testNdbApi/testNdbApi.cpp deleted file mode 100644 index c0e262f590f..00000000000 --- a/ndb/test/ndbapi/testNdbApi/testNdbApi.cpp +++ /dev/null @@ -1,1013 +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 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define CHECK(b) if (!(b)) { \ - ndbout << "ERR: "<< step->getName() \ - << " failed on line " << __LINE__ << endl; \ - result = NDBT_FAILED; \ - continue; } - -#define CHECKE(b) if (!(b)) { \ - errors++; \ - ndbout << "ERR: "<< step->getName() \ - << " failed on line " << __LINE__ << endl; \ - result = NDBT_FAILED; \ - continue; } - - -int runTestMaxNdb(NDBT_Context* ctx, NDBT_Step* step){ - Uint32 loops = ctx->getNumLoops(); - Uint32 l = 0; - int oldi = 0; - int result = NDBT_OK; - - while (l < loops && result == NDBT_OK){ - ndbout_c("loop %d", l + 1); - int errors = 0; - int maxErrors = 5; - - Vector ndbVector; - int i = 0; - int init = 0; - do { - - Ndb* pNdb = new Ndb("TEST_DB"); - if (pNdb == NULL){ - ndbout << "pNdb == NULL" << endl; - errors++; - continue; - - } - i++; - - ndbVector.push_back(pNdb); - - if (pNdb->init()){ - ERR(pNdb->getNdbError()); - errors++; - continue; - } - - init++; - - } while (errors == 0); - - ndbout << i << " ndb objects created" << endl; - - if (l > 0 && i != oldi && init != MAX_NO_THREADS){ - ndbout << l << ": not as manyNdb objects created" << endl - << i << " != " << oldi << endl; - result = NDBT_FAILED; - } - - oldi = i; - - - for(size_t i = 0; i < ndbVector.size(); i++){ - delete ndbVector[i]; - if(((i+1) % 250) == 0){ - ndbout << "Deleted " << (Uint64) i << " ndb objects " << endl; - } - } - ndbVector.clear(); - - l++; - } - - return result; -} - -int runTestMaxTransaction(NDBT_Context* ctx, NDBT_Step* step){ - Uint32 loops = ctx->getNumLoops(); - Uint32 l = 0; - int oldi = 0; - int result = NDBT_OK; - - Ndb* pNdb = new Ndb("TEST_DB"); - if (pNdb == NULL){ - ndbout << "pNdb == NULL" << endl; - return NDBT_FAILED; - } - if (pNdb->init(2048)){ - ERR(pNdb->getNdbError()); - delete pNdb; - return NDBT_FAILED; - } - - while (l < loops && result == NDBT_OK){ - int errors = 0; - int maxErrors = 5; - - Vector conVector; - - - int i = 0; - do { - - NdbConnection* pCon; - - int type = i%4; - switch (type){ - case 0: - pCon = pNdb->startTransaction(); - break; - case 1: - pCon = pNdb->startTransaction(2, - "DATA", - 4); - break; - case 2: - pCon = pNdb->startTransactionDGroup(1, - "TEST", - 0); - break; - case 3: - pCon = pNdb->startTransactionDGroup(2, - "TEST", - 1); - break; - - default: - abort(); - } - - if (pCon == NULL){ - ERR(pNdb->getNdbError()); - errors++; - continue; - } - - conVector.push_back(pCon); - - i++; - } while (errors < maxErrors); - - ndbout << i << " connections created" << endl; - - if (l > 0 && i != oldi){ - ndbout << l << ": not as many transactions created" << endl - << i << " != " << oldi << endl; - result = NDBT_FAILED; - } - - oldi = i; - - - for(size_t i = 0; i < conVector.size(); i++){ - pNdb->closeTransaction(conVector[i]); - } - conVector.clear(); - l++; - - } - - // BONUS Test closeTransaction with null trans - pNdb->closeTransaction(NULL); - - delete pNdb; - - - return result; -} - -int runTestMaxOperations(NDBT_Context* ctx, NDBT_Step* step){ - Uint32 l = 1; - int result = NDBT_OK; - int maxOpsLimit = 1; - const NdbDictionary::Table* pTab = ctx->getTab(); - - Ndb* pNdb = new Ndb("TEST_DB"); - if (pNdb == NULL){ - ndbout << "pNdb == NULL" << endl; - return NDBT_FAILED; - } - if (pNdb->init(2048)){ - ERR(pNdb->getNdbError()); - delete pNdb; - return NDBT_FAILED; - } - - HugoOperations hugoOps(*pTab); - - bool endTest = false; - while (!endTest && result == NDBT_OK){ - int errors = 0; - int maxErrors = 5; - - maxOpsLimit = l*1000; - - if (hugoOps.startTransaction(pNdb) != NDBT_OK){ - delete pNdb; - return NDBT_FAILED; - } - - int i = 0; - while (errors < maxErrors){ - - if(hugoOps.pkReadRecord(pNdb,1, false, 1) != NDBT_OK){ - errors++; - continue; - } - - i++; - - if (i >= maxOpsLimit){ - errors = maxErrors; - } - - } - - ndbout << i << " operations used" << endl; - - int execResult = hugoOps.execute_Commit(pNdb); - switch(execResult){ - case NDBT_OK: - break; - case 233: // Out of operation records in transaction coordinator - // OK - end test - endTest = true; - break; - default: - result = NDBT_FAILED; - break; - } - - hugoOps.closeTransaction(pNdb); - - l++; - - } - - delete pNdb; - - return result; -} - -int runTestGetValue(NDBT_Context* ctx, NDBT_Step* step){ - - int result = NDBT_OK; - const NdbDictionary::Table* pTab = ctx->getTab(); - - Ndb* pNdb = new Ndb("TEST_DB"); - if (pNdb == NULL){ - ndbout << "pNdb == NULL" << endl; - return NDBT_FAILED; - } - if (pNdb->init(2048)){ - ERR(pNdb->getNdbError()); - delete pNdb; - return NDBT_FAILED; - } - - HugoOperations hugoOps(*pTab); - - for (int m = 1; m < 100; m++){ - int errors = 0; - int maxErrors = 5; - - NdbConnection* pCon = pNdb->startTransaction(); - if (pCon == NULL){ - delete pNdb; - return NDBT_FAILED; - } - - NdbOperation* pOp = pCon->getNdbOperation(pTab->getName()); - if (pOp == NULL){ - pNdb->closeTransaction(pCon); - delete pNdb; - return NDBT_FAILED; - } - - if (pOp->readTuple() != 0){ - pNdb->closeTransaction(pCon); - delete pNdb; - return NDBT_FAILED; - } - - for(int a = 0; agetNoOfColumns(); a++){ - if (pTab->getColumn(a)->getPrimaryKey() == true){ - if(hugoOps.equalForAttr(pOp, a, 1) != 0){ - ERR(pCon->getNdbError()); - pNdb->closeTransaction(pCon); - delete pNdb; - return NDBT_FAILED; - } - } - } - - int i = 0; - int maxLimit = 1000*m; - do { - - if (pOp->getValue(pTab->getColumn(1)->getName()) == NULL) { - const NdbError err = pCon->getNdbError(); - ERR(err); - if (err.code == 0) - result = NDBT_FAILED; - errors++; - continue; - } - - i++; - - } while (errors < maxErrors && i < maxLimit); - - ndbout << i << " getValues called" << endl; - - - if (pCon->execute(Commit) != 0){ - const NdbError err = pCon->getNdbError(); - switch(err.code){ - case 880: // TUP - Read too much - case 823: // TUP - Too much AI - case 4257: // NDBAPI - Too much AI - // OK errors - ERR(pCon->getNdbError()); - break; - default: - ERR(pCon->getNdbError()); - ndbout << "Illegal error" << endl; - result= NDBT_FAILED; - break; - } - } - - pNdb->closeTransaction(pCon); - - }// m - - - delete pNdb; - - return result; -} - -int runTestEqual(NDBT_Context* ctx, NDBT_Step* step){ - Uint32 loops = ctx->getNumLoops(); - Uint32 l = 0; - int result = NDBT_OK; - const NdbDictionary::Table* pTab = ctx->getTab(); - - Ndb* pNdb = new Ndb("TEST_DB"); - if (pNdb == NULL){ - ndbout << "pNdb == NULL" << endl; - return NDBT_FAILED; - } - if (pNdb->init(2048)){ - ERR(pNdb->getNdbError()); - delete pNdb; - return NDBT_FAILED; - } - - HugoOperations hugoOps(*pTab); - - while (l < loops){ - for(int m = 1; m < 10; m++){ - int errors = 0; - int maxErrors = 5; - - NdbConnection* pCon = pNdb->startTransaction(); - if (pCon == NULL){ - ndbout << "Could not start transaction" << endl; - delete pNdb; - return NDBT_FAILED; - } - - NdbOperation* pOp = pCon->getNdbOperation(pTab->getName()); - if (pOp == NULL){ - ERR(pCon->getNdbError()); - pNdb->closeTransaction(pCon); - delete pNdb; - return NDBT_FAILED; - } - - if (pOp->readTuple() != 0){ - ERR(pCon->getNdbError()); - pNdb->closeTransaction(pCon); - delete pNdb; - return NDBT_FAILED; - } - - int i = 0; - int maxLimit = 1000*m; - do { - - if ((l%2)!=0){ - // Forward - for(int a = 0; agetNoOfColumns(); a++){ - if (pTab->getColumn(a)->getPrimaryKey() == true){ - if(hugoOps.equalForAttr(pOp, a, 1) != 0){ - const NdbError err = pCon->getNdbError(); - ERR(err); - if (err.code == 0) - result = NDBT_FAILED; - errors++; - } - } - } - } else { - // Backward - for(int a = pTab->getNoOfColumns()-1; a>=0; a--){ - if (pTab->getColumn(a)->getPrimaryKey() == true){ - if(hugoOps.equalForAttr(pOp, a, 1) != 0){ - const NdbError err = pCon->getNdbError(); - ERR(err); - if (err.code == 0) - result = NDBT_FAILED; - errors++; - } - } - } - } - - i++; - - } while (errors < maxErrors && i < maxLimit); - - if (pOp->getValue(pTab->getColumn(1)->getName()) == NULL) { - const NdbError err = pCon->getNdbError(); - ERR(pCon->getNdbError()); - pNdb->closeTransaction(pCon); - delete pNdb; - if (err.code == 4225) { - return NDBT_OK; - } else { - return NDBT_FAILED; - }//if - } - - ndbout << i << " equal called" << endl; - - - int check = pCon->execute(Commit); - if (check != 0){ - ERR(pCon->getNdbError()); - } - - pNdb->closeTransaction(pCon); - - }// m - l++; - - }// l - - delete pNdb; - return result; -} - -int runTestDeleteNdb(NDBT_Context* ctx, NDBT_Step* step){ - Uint32 loops = ctx->getNumLoops(); - Uint32 l = 0; - int result = NDBT_OK; - NdbRestarts restarts; - Vector ndbVector; - const NdbDictionary::Table* pTab = ctx->getTab(); - HugoTransactions hugoTrans(*pTab); - int records = ctx->getNumRecords(); - - while (l < loops && result == NDBT_OK){ - - // Create 5 ndb objects - for( int i = 0; i < 5; i++){ - Ndb* pNdb = new Ndb("TEST_DB"); - if (pNdb == NULL){ - ndbout << "pNdb == NULL" << endl; - result = NDBT_FAILED; - goto end_test; - } - ndbVector.push_back(pNdb); - - if (pNdb->init()){ - ERR(pNdb->getNdbError()); - result = NDBT_FAILED; - goto end_test; - } - if (pNdb->waitUntilReady() != 0){ - ERR(pNdb->getNdbError()); - result = NDBT_FAILED; - goto end_test; - } - if (hugoTrans.pkReadRecords(pNdb, records) != 0){ - result = NDBT_FAILED; - goto end_test; - } - } - - if ((l % 2) == 0){ - // Restart random node - ndbout << "Restart random node " << endl; - if(restarts.executeRestart("RestartRandomNodeAbort", 120) != 0){ - g_err << "Failed to executeRestart(RestartRandomNode)"<getNumRecords(); - - UtilTransactions utilTrans(*ctx->getTab()); - if (utilTrans.clearTable2(GETNDB(step), records) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} -int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ - - int records = ctx->getNumRecords(); - HugoTransactions hugoTrans(*ctx->getTab()); - if (hugoTrans.loadTable(GETNDB(step), records) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runTestWaitUntilReady(NDBT_Context* ctx, NDBT_Step* step){ - - Ndb* pNdb = new Ndb("TEST_DB"); - - // Forget about calling pNdb->init(); - - if (pNdb->waitUntilReady() == 0){ - ndbout << "waitUntilReady returned OK" << endl; - delete pNdb; - return NDBT_FAILED; - } - const NdbError err = pNdb->getNdbError(); - delete pNdb; - - ERR(err); - if (err.code != 4256) - return NDBT_FAILED; - - return NDBT_OK; -} - -int runGetNdbOperationNoTab(NDBT_Context* ctx, NDBT_Step* step){ - - Ndb* pNdb = new Ndb("TEST_DB"); - if (pNdb == NULL){ - ndbout << "pNdb == NULL" << endl; - return NDBT_FAILED; - } - if (pNdb->init()){ - ERR(pNdb->getNdbError()); - delete pNdb; - return NDBT_FAILED; - } - - NdbConnection* pCon = pNdb->startTransaction(); - if (pCon == NULL){ - delete pNdb; - return NDBT_FAILED; - } - - // Call getNdbOperation on an unknown table - NdbOperation* pOp = pCon->getNdbOperation("HUPP76"); - if (pOp == NULL){ - NdbError err = pCon->getNdbError(); - ERR(err); - if (err.code == 0){ - pNdb->closeTransaction(pCon); - delete pNdb; - return NDBT_FAILED; - } - } - - pNdb->closeTransaction(pCon); - - delete pNdb; - - return NDBT_OK; -} - -int runMissingOperation(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - const NdbDictionary::Table* pTab = ctx->getTab(); - - - Ndb* pNdb = new Ndb("TEST_DB"); - if (pNdb == NULL){ - ndbout << "pNdb == NULL" << endl; - return NDBT_FAILED; - } - if (pNdb->init()){ - ERR(pNdb->getNdbError()); - delete pNdb; - return NDBT_FAILED; - } - - NdbConnection* pCon = pNdb->startTransaction(); - if (pCon == NULL){ - pNdb->closeTransaction(pCon); - delete pNdb; - return NDBT_FAILED; - } - - NdbOperation* pOp = pCon->getNdbOperation(pTab->getName()); - if (pOp == NULL){ - ERR(pCon->getNdbError()); - pNdb->closeTransaction(pCon); - delete pNdb; - return NDBT_FAILED; - } - - // Forget about calling pOp->insertTuple(); - - // Call getValue should not work - if (pOp->getValue(pTab->getColumn(1)->getName()) == NULL) { - const NdbError err = pCon->getNdbError(); - ERR(err); - if (err.code == 0){ - ndbout << "hupp" << endl; - result = NDBT_FAILED; - } - } else { - ndbout << "hupp2" << endl; - result = NDBT_FAILED; - } - - pNdb->closeTransaction(pCon); - delete pNdb; - - return result; -} - -int runGetValueInUpdate(NDBT_Context* ctx, NDBT_Step* step){ - const NdbDictionary::Table* pTab = ctx->getTab(); - - Ndb* pNdb = new Ndb("TEST_DB"); - if (pNdb == NULL){ - ndbout << "pNdb == NULL" << endl; - return NDBT_FAILED; - } - if (pNdb->init()){ - ERR(pNdb->getNdbError()); - delete pNdb; - return NDBT_FAILED; - } - - NdbConnection* pCon = pNdb->startTransaction(); - if (pCon == NULL){ - pNdb->closeTransaction(pCon); - delete pNdb; - return NDBT_FAILED; - } - - NdbOperation* pOp = pCon->getNdbOperation(pTab->getName()); - if (pOp == NULL){ - ERR(pCon->getNdbError()); - pNdb->closeTransaction(pCon); - delete pNdb; - return NDBT_FAILED; - } - - if (pOp->updateTuple() != 0){ - pNdb->closeTransaction(pCon); - delete pNdb; - return NDBT_FAILED; - } - - // Call getValue should not work - if (pOp->getValue(pTab->getColumn(1)->getName()) == NULL) { - // It didn't work - const NdbError err = pCon->getNdbError(); - ERR(err); - if (err.code == 0){ - pNdb->closeTransaction(pCon); - delete pNdb; - return NDBT_FAILED; - } - } else { - // It worked, not good! - pNdb->closeTransaction(pCon); - delete pNdb; - return NDBT_FAILED; - } - - int check = pCon->execute(Commit); - if (check != 0){ - ERR(pCon->getNdbError()); - } - - pNdb->closeTransaction(pCon); - delete pNdb; - - return NDBT_OK; -} - -int runUpdateWithoutValues(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - const NdbDictionary::Table* pTab = ctx->getTab(); - - HugoOperations hugoOps(*pTab); - - Ndb* pNdb = new Ndb("TEST_DB"); - if (pNdb == NULL){ - ndbout << "pNdb == NULL" << endl; - return NDBT_FAILED; - } - if (pNdb->init()){ - ERR(pNdb->getNdbError()); - delete pNdb; - return NDBT_FAILED; - } - - NdbConnection* pCon = pNdb->startTransaction(); - if (pCon == NULL){ - pNdb->closeTransaction(pCon); - delete pNdb; - return NDBT_FAILED; - } - - NdbOperation* pOp = pCon->getNdbOperation(pTab->getName()); - if (pOp == NULL){ - ERR(pCon->getNdbError()); - pNdb->closeTransaction(pCon); - delete pNdb; - return NDBT_FAILED; - } - - if (pOp->updateTuple() != 0){ - pNdb->closeTransaction(pCon); - ERR(pOp->getNdbError()); - delete pNdb; - return NDBT_FAILED; - } - - for(int a = 0; agetNoOfColumns(); a++){ - if (pTab->getColumn(a)->getPrimaryKey() == true){ - if(hugoOps.equalForAttr(pOp, a, 1) != 0){ - ERR(pCon->getNdbError()); - pNdb->closeTransaction(pCon); - delete pNdb; - return NDBT_FAILED; - } - } - } - - // Dont' call any setValues - - // Execute should not work - int check = pCon->execute(Commit); - if (check == 0){ - ndbout << "execute worked" << endl; - result = NDBT_FAILED; - } else { - ERR(pCon->getNdbError()); - } - - pNdb->closeTransaction(pCon); - delete pNdb; - - return result; -} - -int runUpdateWithoutKeys(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - const NdbDictionary::Table* pTab = ctx->getTab(); - - - Ndb* pNdb = new Ndb("TEST_DB"); - if (pNdb == NULL){ - ndbout << "pNdb == NULL" << endl; - return NDBT_FAILED; - } - if (pNdb->init()){ - ERR(pNdb->getNdbError()); - delete pNdb; - return NDBT_FAILED; - } - - NdbConnection* pCon = pNdb->startTransaction(); - if (pCon == NULL){ - pNdb->closeTransaction(pCon); - delete pNdb; - return NDBT_FAILED; - } - - NdbOperation* pOp = pCon->getNdbOperation(pTab->getName()); - if (pOp == NULL){ - ERR(pCon->getNdbError()); - pNdb->closeTransaction(pCon); - delete pNdb; - return NDBT_FAILED; - } - - if (pOp->updateTuple() != 0){ - pNdb->closeTransaction(pCon); - ERR(pOp->getNdbError()); - delete pNdb; - return NDBT_FAILED; - } - - // Dont' call any equal or setValues - - // Execute should not work - int check = pCon->execute(Commit); - if (check == 0){ - ndbout << "execute worked" << endl; - result = NDBT_FAILED; - } else { - ERR(pCon->getNdbError()); - } - - pNdb->closeTransaction(pCon); - delete pNdb; - - return result; -} - -int runCheckGetNdbErrorOperation(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - const NdbDictionary::Table* pTab = ctx->getTab(); - - Ndb* pNdb = new Ndb("TEST_DB"); - if (pNdb == NULL){ - ndbout << "pNdb == NULL" << endl; - return NDBT_FAILED; - } - if (pNdb->init(2048)){ - ERR(pNdb->getNdbError()); - delete pNdb; - return NDBT_FAILED; - } - - HugoOperations hugoOps(*pTab); - - - NdbConnection* pCon = pNdb->startTransaction(); - if (pCon == NULL){ - ndbout << "Could not start transaction" << endl; - delete pNdb; - return NDBT_FAILED; - } - - NdbOperation* pOp = pCon->getNdbOperation(pTab->getName()); - if (pOp == NULL){ - ERR(pCon->getNdbError()); - pNdb->closeTransaction(pCon); - delete pNdb; - return NDBT_FAILED; - } - - // Dont call readTuple here - // That's the error! - - for(int a = 0; agetNoOfColumns(); a++){ - if (pTab->getColumn(a)->getPrimaryKey() == true){ - if(hugoOps.equalForAttr(pOp, a, 1) != 0){ - // An error has occured, check that - // it's possible to get the NdbErrorOperation - const NdbError err = pCon->getNdbError(); - ERR(err); - if (err.code == 0) - result = NDBT_FAILED; - - NdbOperation* pOp2 = pCon->getNdbErrorOperation(); - if (pOp2 == NULL) - result = NDBT_FAILED; - else { - const NdbError err2 = pOp2->getNdbError(); - ERR(err2); - if (err.code == 0) - result = NDBT_FAILED; - } - } - } - } - - pNdb->closeTransaction(pCon); - - delete pNdb; - return result; -} - - -NDBT_TESTSUITE(testNdbApi); -TESTCASE("MaxNdb", - "Create Ndb objects until no more can be created\n"){ - INITIALIZER(runTestMaxNdb); -} -TESTCASE("MaxTransactions", - "Start transactions until no more can be created\n"){ - INITIALIZER(runTestMaxTransaction); -} -TESTCASE("MaxOperations", - "Get operations until no more can be created\n"){ - INITIALIZER(runLoadTable); - INITIALIZER(runTestMaxOperations); - FINALIZER(runClearTable); -} -TESTCASE("MaxGetValue", - "Call getValue loads of time\n"){ - INITIALIZER(runLoadTable); - INITIALIZER(runTestGetValue); - FINALIZER(runClearTable); -} -TESTCASE("MaxEqual", - "Call equal loads of time\n"){ - INITIALIZER(runTestEqual); -} -TESTCASE("DeleteNdb", - "Make sure that a deleted Ndb object is properly deleted\n" - "and removed from transporter\n"){ - INITIALIZER(runLoadTable); - INITIALIZER(runTestDeleteNdb); - FINALIZER(runClearTable); -} -TESTCASE("WaitUntilReady", - "Make sure you get an error message when calling waitUntilReady\n" - "without an init'ed Ndb\n"){ - INITIALIZER(runTestWaitUntilReady); -} -TESTCASE("GetOperationNoTab", - "Call getNdbOperation on a table that does not exist\n"){ - INITIALIZER(runGetNdbOperationNoTab); -} -TESTCASE("MissingOperation", - "Missing operation request(insertTuple) should give an error code\n"){ - INITIALIZER(runMissingOperation); -} -TESTCASE("GetValueInUpdate", - "Test that it's not possible to perform getValue in an update\n"){ - INITIALIZER(runLoadTable); - INITIALIZER(runGetValueInUpdate); - FINALIZER(runClearTable); -} -TESTCASE("UpdateWithoutKeys", - "Test that it's not possible to perform update without setting\n" - "PKs"){ - INITIALIZER(runLoadTable); - INITIALIZER(runUpdateWithoutKeys); - FINALIZER(runClearTable); -} -TESTCASE("UpdateWithoutValues", - "Test that it's not possible to perform update without setValues\n"){ - INITIALIZER(runLoadTable); - INITIALIZER(runUpdateWithoutValues); - FINALIZER(runClearTable); -} -TESTCASE("NdbErrorOperation", - "Test that NdbErrorOperation is properly set"){ - INITIALIZER(runCheckGetNdbErrorOperation); -} -NDBT_TESTSUITE_END(testNdbApi); - -int main(int argc, const char** argv){ - // TABLE("T1"); - return testNdbApi.execute(argc, argv); -} - - diff --git a/ndb/test/ndbapi/testNodeRestart.cpp b/ndb/test/ndbapi/testNodeRestart.cpp new file mode 100644 index 00000000000..fd591f04c69 --- /dev/null +++ b/ndb/test/ndbapi/testNodeRestart.cpp @@ -0,0 +1,449 @@ +/* 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 */ + +#include +#include +#include +#include +#include +#include +#include + + +int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ + + int records = ctx->getNumRecords(); + HugoTransactions hugoTrans(*ctx->getTab()); + if (hugoTrans.loadTable(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runFillTable(NDBT_Context* ctx, NDBT_Step* step){ + + HugoTransactions hugoTrans(*ctx->getTab()); + if (hugoTrans.fillTable(GETNDB(step)) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runInsertUntilStopped(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int records = ctx->getNumRecords(); + int i = 0; + HugoTransactions hugoTrans(*ctx->getTab()); + while (ctx->isTestStopped() == false) { + g_info << i << ": "; + if (hugoTrans.loadTable(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + i++; + } + return result; +} + +int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + + UtilTransactions utilTrans(*ctx->getTab()); + if (utilTrans.clearTable(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runClearTableUntilStopped(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + int i = 0; + + UtilTransactions utilTrans(*ctx->getTab()); + while (ctx->isTestStopped() == false) { + g_info << i << ": "; + if (utilTrans.clearTable(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + i++; + } + return NDBT_OK; +} + +int runScanReadUntilStopped(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int records = ctx->getNumRecords(); + int i = 0; + HugoTransactions hugoTrans(*ctx->getTab()); + while (ctx->isTestStopped() == false) { + g_info << i << ": "; + if (hugoTrans.scanReadRecords(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + i++; + } + return result; +} + +int runPkReadUntilStopped(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int records = ctx->getNumRecords(); + int i = 0; + HugoTransactions hugoTrans(*ctx->getTab()); + while (ctx->isTestStopped() == false) { + g_info << i << ": "; + if (hugoTrans.pkReadRecords(GETNDB(step), records, 128) != 0){ + return NDBT_FAILED; + } + i++; + } + return result; +} + +int runPkUpdateUntilStopped(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int records = ctx->getNumRecords(); + int i = 0; + HugoTransactions hugoTrans(*ctx->getTab()); + while (ctx->isTestStopped() == false) { + g_info << i << ": "; + if (hugoTrans.pkUpdateRecords(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + i++; + } + return result; +} + +int runScanUpdateUntilStopped(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int records = ctx->getNumRecords(); + int parallelism = ctx->getProperty("Parallelism", 1); + int abort = ctx->getProperty("AbortProb", (Uint32)0); + int i = 0; + HugoTransactions hugoTrans(*ctx->getTab()); + while (ctx->isTestStopped() == false) { + g_info << i << ": "; + if (hugoTrans.scanUpdateRecords(GETNDB(step), records, abort, + parallelism) == NDBT_FAILED){ + return NDBT_FAILED; + } + i++; + } + return result; +} + +int runScanReadVerify(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + HugoTransactions hugoTrans(*ctx->getTab()); + + if (hugoTrans.scanReadRecords(GETNDB(step), records, 0, 64) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runRestarter(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int loops = ctx->getNumLoops(); + NdbRestarter restarter; + int i = 0; + int lastId = 0; + + if (restarter.getNumDbNodes() < 2){ + ctx->stopTest(); + return NDBT_OK; + } + + if(restarter.waitClusterStarted(60) != 0){ + g_err << "Cluster failed to start" << endl; + return NDBT_FAILED; + } + + loops *= restarter.getNumDbNodes(); + while(iisTestStopped()){ + + int id = lastId % restarter.getNumDbNodes(); + int nodeId = restarter.getDbNodeId(id); + ndbout << "Restart node " << nodeId << endl; + if(restarter.restartOneDbNode(nodeId) != 0){ + g_err << "Failed to restartNextDbNode" << endl; + result = NDBT_FAILED; + break; + } + + if(restarter.waitClusterStarted(60) != 0){ + g_err << "Cluster failed to start" << endl; + result = NDBT_FAILED; + break; + } + + NdbSleep_SecSleep(1); + + lastId++; + i++; + } + + ctx->stopTest(); + + return result; +} + +int runCheckAllNodesStarted(NDBT_Context* ctx, NDBT_Step* step){ + NdbRestarter restarter; + + if(restarter.waitClusterStarted(1) != 0){ + g_err << "All nodes was not started " << endl; + return NDBT_FAILED; + } + + return NDBT_OK; +} + + + +int runRestarts(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int loops = ctx->getNumLoops(); + NDBT_TestCase* pCase = ctx->getCase(); + NdbRestarts restarts; + int i = 0; + int timeout = 240; + + while(iisTestStopped()){ + + if(restarts.executeRestart(pCase->getName(), timeout) != 0){ + g_err << "Failed to executeRestart(" <getName() <<")" << endl; + result = NDBT_FAILED; + break; + } + i++; + } + return result; +} + +NDBT_TESTSUITE(testNodeRestart); +TESTCASE("NoLoad", + "Test that one node at a time can be stopped and then restarted "\ + "when there are no load on the system. Do this loop number of times"){ + INITIALIZER(runCheckAllNodesStarted); + INITIALIZER(runLoadTable); + STEP(runRestarter); + FINALIZER(runClearTable); +} +TESTCASE("PkRead", + "Test that one node at a time can be stopped and then restarted "\ + "perform pk read while restarting. Do this loop number of times"){ + INITIALIZER(runCheckAllNodesStarted); + INITIALIZER(runLoadTable); + STEP(runRestarter); + STEP(runPkReadUntilStopped); + FINALIZER(runClearTable); +} +TESTCASE("PkReadPkUpdate", + "Test that one node at a time can be stopped and then restarted "\ + "perform pk read and pk update while restarting. Do this loop number of times"){ + INITIALIZER(runCheckAllNodesStarted); + INITIALIZER(runLoadTable); + STEP(runRestarter); + STEP(runPkReadUntilStopped); + STEP(runPkReadUntilStopped); + STEP(runPkReadUntilStopped); + STEP(runPkReadUntilStopped); + STEP(runPkUpdateUntilStopped); + FINALIZER(runClearTable); +} +TESTCASE("ReadUpdateScan", + "Test that one node at a time can be stopped and then restarted "\ + "perform pk read, pk update and scan reads while restarting. Do this loop number of times"){ + INITIALIZER(runCheckAllNodesStarted); + INITIALIZER(runLoadTable); + STEP(runRestarter); + STEP(runPkReadUntilStopped); + STEP(runPkUpdateUntilStopped); + STEP(runScanReadUntilStopped); + STEP(runScanUpdateUntilStopped); + FINALIZER(runClearTable); +} +TESTCASE("Terror", + "Test that one node at a time can be stopped and then restarted "\ + "perform all kind of transactions while restarting. Do this loop number of times"){ + INITIALIZER(runCheckAllNodesStarted); + INITIALIZER(runLoadTable); + STEP(runRestarter); + STEP(runPkReadUntilStopped); + STEP(runPkUpdateUntilStopped); + STEP(runScanReadUntilStopped); + STEP(runScanUpdateUntilStopped); + STEP(runInsertUntilStopped); + STEP(runClearTableUntilStopped); + FINALIZER(runClearTable); +} +TESTCASE("FullDb", + "Test that one node at a time can be stopped and then restarted "\ + "when db is full. Do this loop number of times"){ + INITIALIZER(runCheckAllNodesStarted); + INITIALIZER(runFillTable); + STEP(runRestarter); + FINALIZER(runClearTable); +} +TESTCASE("RestartRandomNode", + "Test that we can execute the restart RestartRandomNode loop\n"\ + "number of times"){ + INITIALIZER(runCheckAllNodesStarted); + INITIALIZER(runLoadTable); + STEP(runRestarts); + FINALIZER(runScanReadVerify); + FINALIZER(runClearTable); +} +TESTCASE("RestartRandomNodeError", + "Test that we can execute the restart RestartRandomNodeError loop\n"\ + "number of times"){ + INITIALIZER(runCheckAllNodesStarted); + INITIALIZER(runLoadTable); + STEP(runRestarts); + FINALIZER(runScanReadVerify); + FINALIZER(runClearTable); +} +TESTCASE("RestartRandomNodeInitial", + "Test that we can execute the restart RestartRandomNodeInitial loop\n"\ + "number of times"){ + INITIALIZER(runCheckAllNodesStarted); + INITIALIZER(runLoadTable); + STEP(runRestarts); + FINALIZER(runScanReadVerify); + FINALIZER(runClearTable); +} +TESTCASE("RestartNFDuringNR", + "Test that we can execute the restart RestartNFDuringNR loop\n"\ + "number of times"){ + INITIALIZER(runCheckAllNodesStarted); + INITIALIZER(runLoadTable); + STEP(runRestarts); + FINALIZER(runScanReadVerify); + FINALIZER(runClearTable); +} +TESTCASE("RestartMasterNodeError", + "Test that we can execute the restart RestartMasterNodeError loop\n"\ + "number of times"){ + INITIALIZER(runCheckAllNodesStarted); + INITIALIZER(runLoadTable); + STEP(runRestarts); + FINALIZER(runScanReadVerify); + FINALIZER(runClearTable); +} + +TESTCASE("TwoNodeFailure", + "Test that we can execute the restart TwoNodeFailure\n"\ + "(which is a multiple node failure restart) loop\n"\ + "number of times"){ + INITIALIZER(runCheckAllNodesStarted); + INITIALIZER(runLoadTable); + STEP(runRestarts); + FINALIZER(runScanReadVerify); + FINALIZER(runClearTable); +} +TESTCASE("TwoMasterNodeFailure", + "Test that we can execute the restart TwoMasterNodeFailure\n"\ + "(which is a multiple node failure restart) loop\n"\ + "number of times"){ + INITIALIZER(runCheckAllNodesStarted); + INITIALIZER(runLoadTable); + STEP(runRestarts); + FINALIZER(runScanReadVerify); + FINALIZER(runClearTable); +} +TESTCASE("FiftyPercentFail", + "Test that we can execute the restart FiftyPercentFail\n"\ + "(which is a multiple node failure restart) loop\n"\ + "number of times"){ + INITIALIZER(runCheckAllNodesStarted); + INITIALIZER(runLoadTable); + STEP(runRestarts); + FINALIZER(runScanReadVerify); + FINALIZER(runClearTable); +} +TESTCASE("RestartAllNodes", + "Test that we can execute the restart RestartAllNodes\n"\ + "(which is a system restart) loop\n"\ + "number of times"){ + INITIALIZER(runCheckAllNodesStarted); + INITIALIZER(runLoadTable); + STEP(runRestarts); + FINALIZER(runScanReadVerify); + FINALIZER(runClearTable); +} +TESTCASE("RestartAllNodesAbort", + "Test that we can execute the restart RestartAllNodesAbort\n"\ + "(which is a system restart) loop\n"\ + "number of times"){ + INITIALIZER(runCheckAllNodesStarted); + INITIALIZER(runLoadTable); + STEP(runRestarts); + FINALIZER(runScanReadVerify); + FINALIZER(runClearTable); +} +TESTCASE("RestartAllNodesError9999", + "Test that we can execute the restart RestartAllNodesError9999\n"\ + "(which is a system restart) loop\n"\ + "number of times"){ + INITIALIZER(runCheckAllNodesStarted); + INITIALIZER(runLoadTable); + STEP(runRestarts); + FINALIZER(runScanReadVerify); + FINALIZER(runClearTable); +} +TESTCASE("FiftyPercentStopAndWait", + "Test that we can execute the restart FiftyPercentStopAndWait\n"\ + "(which is a system restart) loop\n"\ + "number of times"){ + INITIALIZER(runCheckAllNodesStarted); + INITIALIZER(runLoadTable); + STEP(runRestarts); + FINALIZER(runScanReadVerify); + FINALIZER(runClearTable); +} +TESTCASE("RestartNodeDuringLCP", + "Test that we can execute the restart RestartRandomNode loop\n"\ + "number of times"){ + INITIALIZER(runCheckAllNodesStarted); + INITIALIZER(runLoadTable); + STEP(runRestarts); + FINALIZER(runScanReadVerify); + FINALIZER(runClearTable); +} +TESTCASE("StopOnError", + "Test StopOnError. A node that has StopOnError set to false "\ + "should restart automatically when an error occurs"){ + INITIALIZER(runCheckAllNodesStarted); + INITIALIZER(runLoadTable); + STEP(runRestarts); + FINALIZER(runScanReadVerify); + FINALIZER(runClearTable); +} +NDBT_TESTSUITE_END(testNodeRestart); + +int main(int argc, const char** argv){ +#if 0 + // It might be interesting to have longer defaults for num + // loops in this test + // Just performing 100 node restarts would not be enough? + // We can have initialisers in the NDBT_Testcase class like + // this... + testNodeRestart.setDefaultLoops(1000); +#endif + return testNodeRestart.execute(argc, argv); +} + diff --git a/ndb/test/ndbapi/testNodeRestart/Makefile b/ndb/test/ndbapi/testNodeRestart/Makefile deleted file mode 100644 index 8c13ab3beb4..00000000000 --- a/ndb/test/ndbapi/testNodeRestart/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include .defs.mk - -TYPE = ndbapitest - -BIN_TARGET = testNodeRestart - -SOURCES = testNodeRestart.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/testNodeRestart/testNodeRestart.cpp b/ndb/test/ndbapi/testNodeRestart/testNodeRestart.cpp deleted file mode 100644 index fd591f04c69..00000000000 --- a/ndb/test/ndbapi/testNodeRestart/testNodeRestart.cpp +++ /dev/null @@ -1,449 +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 */ - -#include -#include -#include -#include -#include -#include -#include - - -int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ - - int records = ctx->getNumRecords(); - HugoTransactions hugoTrans(*ctx->getTab()); - if (hugoTrans.loadTable(GETNDB(step), records) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runFillTable(NDBT_Context* ctx, NDBT_Step* step){ - - HugoTransactions hugoTrans(*ctx->getTab()); - if (hugoTrans.fillTable(GETNDB(step)) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runInsertUntilStopped(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - int records = ctx->getNumRecords(); - int i = 0; - HugoTransactions hugoTrans(*ctx->getTab()); - while (ctx->isTestStopped() == false) { - g_info << i << ": "; - if (hugoTrans.loadTable(GETNDB(step), records) != 0){ - return NDBT_FAILED; - } - i++; - } - return result; -} - -int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - - UtilTransactions utilTrans(*ctx->getTab()); - if (utilTrans.clearTable(GETNDB(step), records) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runClearTableUntilStopped(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - int i = 0; - - UtilTransactions utilTrans(*ctx->getTab()); - while (ctx->isTestStopped() == false) { - g_info << i << ": "; - if (utilTrans.clearTable(GETNDB(step), records) != 0){ - return NDBT_FAILED; - } - i++; - } - return NDBT_OK; -} - -int runScanReadUntilStopped(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - int records = ctx->getNumRecords(); - int i = 0; - HugoTransactions hugoTrans(*ctx->getTab()); - while (ctx->isTestStopped() == false) { - g_info << i << ": "; - if (hugoTrans.scanReadRecords(GETNDB(step), records) != 0){ - return NDBT_FAILED; - } - i++; - } - return result; -} - -int runPkReadUntilStopped(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - int records = ctx->getNumRecords(); - int i = 0; - HugoTransactions hugoTrans(*ctx->getTab()); - while (ctx->isTestStopped() == false) { - g_info << i << ": "; - if (hugoTrans.pkReadRecords(GETNDB(step), records, 128) != 0){ - return NDBT_FAILED; - } - i++; - } - return result; -} - -int runPkUpdateUntilStopped(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - int records = ctx->getNumRecords(); - int i = 0; - HugoTransactions hugoTrans(*ctx->getTab()); - while (ctx->isTestStopped() == false) { - g_info << i << ": "; - if (hugoTrans.pkUpdateRecords(GETNDB(step), records) != 0){ - return NDBT_FAILED; - } - i++; - } - return result; -} - -int runScanUpdateUntilStopped(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - int records = ctx->getNumRecords(); - int parallelism = ctx->getProperty("Parallelism", 1); - int abort = ctx->getProperty("AbortProb", (Uint32)0); - int i = 0; - HugoTransactions hugoTrans(*ctx->getTab()); - while (ctx->isTestStopped() == false) { - g_info << i << ": "; - if (hugoTrans.scanUpdateRecords(GETNDB(step), records, abort, - parallelism) == NDBT_FAILED){ - return NDBT_FAILED; - } - i++; - } - return result; -} - -int runScanReadVerify(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - HugoTransactions hugoTrans(*ctx->getTab()); - - if (hugoTrans.scanReadRecords(GETNDB(step), records, 0, 64) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runRestarter(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - int loops = ctx->getNumLoops(); - NdbRestarter restarter; - int i = 0; - int lastId = 0; - - if (restarter.getNumDbNodes() < 2){ - ctx->stopTest(); - return NDBT_OK; - } - - if(restarter.waitClusterStarted(60) != 0){ - g_err << "Cluster failed to start" << endl; - return NDBT_FAILED; - } - - loops *= restarter.getNumDbNodes(); - while(iisTestStopped()){ - - int id = lastId % restarter.getNumDbNodes(); - int nodeId = restarter.getDbNodeId(id); - ndbout << "Restart node " << nodeId << endl; - if(restarter.restartOneDbNode(nodeId) != 0){ - g_err << "Failed to restartNextDbNode" << endl; - result = NDBT_FAILED; - break; - } - - if(restarter.waitClusterStarted(60) != 0){ - g_err << "Cluster failed to start" << endl; - result = NDBT_FAILED; - break; - } - - NdbSleep_SecSleep(1); - - lastId++; - i++; - } - - ctx->stopTest(); - - return result; -} - -int runCheckAllNodesStarted(NDBT_Context* ctx, NDBT_Step* step){ - NdbRestarter restarter; - - if(restarter.waitClusterStarted(1) != 0){ - g_err << "All nodes was not started " << endl; - return NDBT_FAILED; - } - - return NDBT_OK; -} - - - -int runRestarts(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - int loops = ctx->getNumLoops(); - NDBT_TestCase* pCase = ctx->getCase(); - NdbRestarts restarts; - int i = 0; - int timeout = 240; - - while(iisTestStopped()){ - - if(restarts.executeRestart(pCase->getName(), timeout) != 0){ - g_err << "Failed to executeRestart(" <getName() <<")" << endl; - result = NDBT_FAILED; - break; - } - i++; - } - return result; -} - -NDBT_TESTSUITE(testNodeRestart); -TESTCASE("NoLoad", - "Test that one node at a time can be stopped and then restarted "\ - "when there are no load on the system. Do this loop number of times"){ - INITIALIZER(runCheckAllNodesStarted); - INITIALIZER(runLoadTable); - STEP(runRestarter); - FINALIZER(runClearTable); -} -TESTCASE("PkRead", - "Test that one node at a time can be stopped and then restarted "\ - "perform pk read while restarting. Do this loop number of times"){ - INITIALIZER(runCheckAllNodesStarted); - INITIALIZER(runLoadTable); - STEP(runRestarter); - STEP(runPkReadUntilStopped); - FINALIZER(runClearTable); -} -TESTCASE("PkReadPkUpdate", - "Test that one node at a time can be stopped and then restarted "\ - "perform pk read and pk update while restarting. Do this loop number of times"){ - INITIALIZER(runCheckAllNodesStarted); - INITIALIZER(runLoadTable); - STEP(runRestarter); - STEP(runPkReadUntilStopped); - STEP(runPkReadUntilStopped); - STEP(runPkReadUntilStopped); - STEP(runPkReadUntilStopped); - STEP(runPkUpdateUntilStopped); - FINALIZER(runClearTable); -} -TESTCASE("ReadUpdateScan", - "Test that one node at a time can be stopped and then restarted "\ - "perform pk read, pk update and scan reads while restarting. Do this loop number of times"){ - INITIALIZER(runCheckAllNodesStarted); - INITIALIZER(runLoadTable); - STEP(runRestarter); - STEP(runPkReadUntilStopped); - STEP(runPkUpdateUntilStopped); - STEP(runScanReadUntilStopped); - STEP(runScanUpdateUntilStopped); - FINALIZER(runClearTable); -} -TESTCASE("Terror", - "Test that one node at a time can be stopped and then restarted "\ - "perform all kind of transactions while restarting. Do this loop number of times"){ - INITIALIZER(runCheckAllNodesStarted); - INITIALIZER(runLoadTable); - STEP(runRestarter); - STEP(runPkReadUntilStopped); - STEP(runPkUpdateUntilStopped); - STEP(runScanReadUntilStopped); - STEP(runScanUpdateUntilStopped); - STEP(runInsertUntilStopped); - STEP(runClearTableUntilStopped); - FINALIZER(runClearTable); -} -TESTCASE("FullDb", - "Test that one node at a time can be stopped and then restarted "\ - "when db is full. Do this loop number of times"){ - INITIALIZER(runCheckAllNodesStarted); - INITIALIZER(runFillTable); - STEP(runRestarter); - FINALIZER(runClearTable); -} -TESTCASE("RestartRandomNode", - "Test that we can execute the restart RestartRandomNode loop\n"\ - "number of times"){ - INITIALIZER(runCheckAllNodesStarted); - INITIALIZER(runLoadTable); - STEP(runRestarts); - FINALIZER(runScanReadVerify); - FINALIZER(runClearTable); -} -TESTCASE("RestartRandomNodeError", - "Test that we can execute the restart RestartRandomNodeError loop\n"\ - "number of times"){ - INITIALIZER(runCheckAllNodesStarted); - INITIALIZER(runLoadTable); - STEP(runRestarts); - FINALIZER(runScanReadVerify); - FINALIZER(runClearTable); -} -TESTCASE("RestartRandomNodeInitial", - "Test that we can execute the restart RestartRandomNodeInitial loop\n"\ - "number of times"){ - INITIALIZER(runCheckAllNodesStarted); - INITIALIZER(runLoadTable); - STEP(runRestarts); - FINALIZER(runScanReadVerify); - FINALIZER(runClearTable); -} -TESTCASE("RestartNFDuringNR", - "Test that we can execute the restart RestartNFDuringNR loop\n"\ - "number of times"){ - INITIALIZER(runCheckAllNodesStarted); - INITIALIZER(runLoadTable); - STEP(runRestarts); - FINALIZER(runScanReadVerify); - FINALIZER(runClearTable); -} -TESTCASE("RestartMasterNodeError", - "Test that we can execute the restart RestartMasterNodeError loop\n"\ - "number of times"){ - INITIALIZER(runCheckAllNodesStarted); - INITIALIZER(runLoadTable); - STEP(runRestarts); - FINALIZER(runScanReadVerify); - FINALIZER(runClearTable); -} - -TESTCASE("TwoNodeFailure", - "Test that we can execute the restart TwoNodeFailure\n"\ - "(which is a multiple node failure restart) loop\n"\ - "number of times"){ - INITIALIZER(runCheckAllNodesStarted); - INITIALIZER(runLoadTable); - STEP(runRestarts); - FINALIZER(runScanReadVerify); - FINALIZER(runClearTable); -} -TESTCASE("TwoMasterNodeFailure", - "Test that we can execute the restart TwoMasterNodeFailure\n"\ - "(which is a multiple node failure restart) loop\n"\ - "number of times"){ - INITIALIZER(runCheckAllNodesStarted); - INITIALIZER(runLoadTable); - STEP(runRestarts); - FINALIZER(runScanReadVerify); - FINALIZER(runClearTable); -} -TESTCASE("FiftyPercentFail", - "Test that we can execute the restart FiftyPercentFail\n"\ - "(which is a multiple node failure restart) loop\n"\ - "number of times"){ - INITIALIZER(runCheckAllNodesStarted); - INITIALIZER(runLoadTable); - STEP(runRestarts); - FINALIZER(runScanReadVerify); - FINALIZER(runClearTable); -} -TESTCASE("RestartAllNodes", - "Test that we can execute the restart RestartAllNodes\n"\ - "(which is a system restart) loop\n"\ - "number of times"){ - INITIALIZER(runCheckAllNodesStarted); - INITIALIZER(runLoadTable); - STEP(runRestarts); - FINALIZER(runScanReadVerify); - FINALIZER(runClearTable); -} -TESTCASE("RestartAllNodesAbort", - "Test that we can execute the restart RestartAllNodesAbort\n"\ - "(which is a system restart) loop\n"\ - "number of times"){ - INITIALIZER(runCheckAllNodesStarted); - INITIALIZER(runLoadTable); - STEP(runRestarts); - FINALIZER(runScanReadVerify); - FINALIZER(runClearTable); -} -TESTCASE("RestartAllNodesError9999", - "Test that we can execute the restart RestartAllNodesError9999\n"\ - "(which is a system restart) loop\n"\ - "number of times"){ - INITIALIZER(runCheckAllNodesStarted); - INITIALIZER(runLoadTable); - STEP(runRestarts); - FINALIZER(runScanReadVerify); - FINALIZER(runClearTable); -} -TESTCASE("FiftyPercentStopAndWait", - "Test that we can execute the restart FiftyPercentStopAndWait\n"\ - "(which is a system restart) loop\n"\ - "number of times"){ - INITIALIZER(runCheckAllNodesStarted); - INITIALIZER(runLoadTable); - STEP(runRestarts); - FINALIZER(runScanReadVerify); - FINALIZER(runClearTable); -} -TESTCASE("RestartNodeDuringLCP", - "Test that we can execute the restart RestartRandomNode loop\n"\ - "number of times"){ - INITIALIZER(runCheckAllNodesStarted); - INITIALIZER(runLoadTable); - STEP(runRestarts); - FINALIZER(runScanReadVerify); - FINALIZER(runClearTable); -} -TESTCASE("StopOnError", - "Test StopOnError. A node that has StopOnError set to false "\ - "should restart automatically when an error occurs"){ - INITIALIZER(runCheckAllNodesStarted); - INITIALIZER(runLoadTable); - STEP(runRestarts); - FINALIZER(runScanReadVerify); - FINALIZER(runClearTable); -} -NDBT_TESTSUITE_END(testNodeRestart); - -int main(int argc, const char** argv){ -#if 0 - // It might be interesting to have longer defaults for num - // loops in this test - // Just performing 100 node restarts would not be enough? - // We can have initialisers in the NDBT_Testcase class like - // this... - testNodeRestart.setDefaultLoops(1000); -#endif - return testNodeRestart.execute(argc, argv); -} - diff --git a/ndb/test/ndbapi/testOIBasic.cpp b/ndb/test/ndbapi/testOIBasic.cpp new file mode 100644 index 00000000000..a47d9d2099e --- /dev/null +++ b/ndb/test/ndbapi/testOIBasic.cpp @@ -0,0 +1,2767 @@ +/* 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 */ + +/* + * testOIBasic - ordered index test + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +// options + +struct Opt { + // common options + const char* m_case; + bool m_core; + bool m_dups; + NdbDictionary::Object::FragmentType m_fragtype; + const char* m_index; + unsigned m_loop; + unsigned m_rows; + unsigned m_scanrd; + unsigned m_scanex; + unsigned m_seed; + unsigned m_subloop; + const char* m_table; + unsigned m_threads; + unsigned m_v; + Opt() : + m_case(0), + m_core(false), + m_dups(false), + m_fragtype(NdbDictionary::Object::FragUndefined), + m_index(0), + m_loop(1), + m_rows(1000), + m_scanrd(240), + m_scanex(240), + m_seed(1), + m_subloop(4), + m_table(0), + m_threads(4), + m_v(1) { + } +}; + +static Opt g_opt; + +static void printcases(); +static void printtables(); + +static void +printhelp() +{ + Opt d; + ndbout + << "usage: testOIbasic [options]" << endl + << " -case abc only given test cases (letters a-z)" << endl + << " -core core dump on error [" << d.m_core << "]" << endl + << " -dups allow duplicate tuples from index scan [" << d.m_dups << "]" << endl + << " -fragtype T fragment type single/small/medium/large" << endl + << " -index xyz only given index numbers (digits 1-9)" << endl + << " -loop N loop count full suite forever=0 [" << d.m_loop << "]" << endl + << " -rows N rows per thread [" << d.m_rows << "]" << endl + << " -scanrd N scan read parallelism [" << d.m_scanrd << "]" << endl + << " -scanex N scan exclusive parallelism [" << d.m_scanex << "]" << endl + << " -seed N srandom seed [" << d.m_seed << "]" << endl + << " -subloop N subtest loop count [" << d.m_subloop << "]" << endl + << " -table xyz only given table numbers (digits 1-9)" << endl + << " -threads N number of threads [" << d.m_threads << "]" << endl + << " -vN verbosity [" << d.m_v << "]" << endl + << " -h or -help print this help text" << endl + ; + printcases(); + printtables(); +} + +// log and error macros + +static NdbMutex ndbout_mutex = NDB_MUTEX_INITIALIZER; + +static unsigned getthrno(); + +static const char* +getthrstr() +{ + static char buf[20]; + unsigned n = getthrno(); + if (n == (unsigned)-1) + strcpy(buf, ""); + else { + unsigned m = + g_opt.m_threads < 10 ? 1 : + g_opt.m_threads < 100 ? 2 : 3; + sprintf(buf, "[%0*u] ", m, n); + } + return buf; +} + +#define LLN(n, s) \ + do { \ + if ((n) > g_opt.m_v) break; \ + NdbMutex_Lock(&ndbout_mutex); \ + ndbout << getthrstr() << s << endl; \ + NdbMutex_Unlock(&ndbout_mutex); \ + } while(0) + +#define LL0(s) LLN(0, s) +#define LL1(s) LLN(1, s) +#define LL2(s) LLN(2, s) +#define LL3(s) LLN(3, s) +#define LL4(s) LLN(4, s) +#define LL5(s) LLN(5, s) + +// following check a condition and return -1 on failure + +#undef CHK // simple check +#undef CHKTRY // execute action (try-catch) on failure +#undef CHKMSG // print extra message on failure +#undef CHKCON // print NDB API errors on failure + +#define CHK(x) CHKTRY(x, ;) + +#define CHKTRY(x, act) \ + do { \ + if (x) break; \ + LL0("line " << __LINE__ << ": " << #x << " failed"); \ + if (g_opt.m_core) abort(); \ + act; \ + return -1; \ + } while (0) + +#define CHKMSG(x, msg) \ + do { \ + if (x) break; \ + LL0("line " << __LINE__ << ": " << #x << " failed: " << msg); \ + if (g_opt.m_core) abort(); \ + return -1; \ + } while (0) + +#define CHKCON(x, con) \ + do { \ + if (x) break; \ + LL0("line " << __LINE__ << ": " << #x << " failed"); \ + (con).printerror(ndbout); \ + if (g_opt.m_core) abort(); \ + return -1; \ + } while (0) + +// method parameters base class + +class Thr; +class Con; +class Tab; +class Set; + +struct Par : public Opt { + unsigned m_no; + Con* m_con; + Con& con() const { assert(m_con != 0); return *m_con; } + const Tab* m_tab; + const Tab& tab() const { assert(m_tab != 0); return *m_tab; } + Set* m_set; + Set& set() const { assert(m_set != 0); return *m_set; } + unsigned m_totrows; + unsigned m_batch; + // value calculation + unsigned m_pctnull; + unsigned m_range; + unsigned m_pctrange; + // do verify after read + bool m_verify; + // timer location + Par(const Opt& opt) : + Opt(opt), + m_no(0), + m_con(0), + m_tab(0), + m_set(0), + m_totrows(m_threads * m_rows), + m_batch(32), + m_pctnull(10), + m_range(m_rows), + m_pctrange(0), + m_verify(false) { + } +}; + +static bool +usetable(unsigned i) +{ + return g_opt.m_table == 0 || strchr(g_opt.m_table, '1' + i) != 0; +} + +static bool +useindex(unsigned i) +{ + return g_opt.m_index == 0 || strchr(g_opt.m_index, '1' + i) != 0; +} + +static unsigned +thrrow(Par par, unsigned j) +{ + return par.m_threads * j + par.m_no; +} + +static bool +isthrrow(Par par, unsigned i) +{ + return i % par.m_threads == par.m_no; +} + +// timer + +struct Tmr { + void clr(); + void on(); + void off(unsigned cnt = 0); + const char* time(); + const char* over(const Tmr& t1); + NDB_TICKS m_on; + unsigned m_ms; + unsigned m_cnt; + char m_time[100]; + char m_over[100]; + Tmr() { clr(); } +}; + +void +Tmr::clr() +{ + m_on = m_ms = m_cnt = m_time[0] = m_over[0] = 0; +} + +void +Tmr::on() +{ + assert(m_on == 0); + m_on = NdbTick_CurrentMillisecond(); +} + +void +Tmr::off(unsigned cnt) +{ + NDB_TICKS off = NdbTick_CurrentMillisecond(); + assert(m_on != 0 && off >= m_on); + m_ms += off - m_on; + m_cnt += cnt; + m_on = 0; +} + +const char* +Tmr::time() +{ + if (m_cnt == 0) { + sprintf(m_time, "%u ms", m_ms); + } else { + sprintf(m_time, "%u ms per %u ( %u ms per 1000 )", m_ms, m_cnt, (1000 * m_ms) / m_cnt); + } + return m_time; +} + +const char* +Tmr::over(const Tmr& t1) +{ + if (0 < t1.m_ms && t1.m_ms < m_ms) { + sprintf(m_over, "%u pct", (100 * (m_ms - t1.m_ms)) / t1.m_ms); + } else { + sprintf(m_over, "[cannot measure]"); + } + return m_over; +} + +// tables and indexes + +// Col - table column + +struct Col { + unsigned m_num; + const char* m_name; + bool m_pk; + NdbDictionary::Column::Type m_type; + unsigned m_length; + bool m_nullable; + void verify(const void* addr) const; +}; + +void +Col::verify(const void* addr) const +{ + switch (m_type) { + case NdbDictionary::Column::Unsigned: + break; + case NdbDictionary::Column::Varchar: + { + const unsigned char* p = (const unsigned char*)addr; + unsigned n = (p[0] << 8) | p[1]; + assert(n <= m_length); + for (unsigned i = 0; i < n; i++) { + assert(p[2 + i] != 0); + } + for (unsigned i = n; i < m_length; i++) { + assert(p[2 + i] == 0); + } + } + break; + default: + assert(false); + break; + } +} + +static NdbOut& +operator<<(NdbOut& out, const Col& col) +{ + out << "col " << col.m_num; + out << " " << col.m_name; + switch (col.m_type) { + case NdbDictionary::Column::Unsigned: + out << " unsigned"; + break; + case NdbDictionary::Column::Varchar: + out << " varchar(" << col.m_length << ")"; + break; + default: + out << "type" << (int)col.m_type; + assert(false); + break; + } + out << (col.m_pk ? " pk" : ""); + out << (col.m_nullable ? " nullable" : ""); + return out; +} + +// ICol - index column + +struct ICol { + unsigned m_num; + struct Col m_col; +}; + +// ITab - index + +struct ITab { + const char* m_name; + unsigned m_icols; + const ICol* m_icol; +}; + +static NdbOut& +operator<<(NdbOut& out, const ITab& itab) +{ + out << "itab " << itab.m_name << " " << itab.m_icols; + for (unsigned k = 0; k < itab.m_icols; k++) { + out << endl; + out << "icol " << k << " " << itab.m_icol[k].m_col; + } + return out; +} + +// Tab - table + +struct Tab { + const char* m_name; + unsigned m_cols; + const Col* m_col; + unsigned m_itabs; + const ITab* m_itab; +}; + +static NdbOut& +operator<<(NdbOut& out, const Tab& tab) +{ + out << "tab " << tab.m_name << " " << tab.m_cols; + for (unsigned k = 0; k < tab.m_cols; k++) { + out << endl; + out << tab.m_col[k]; + } + for (unsigned i = 0; i < tab.m_itabs; i++) { + if (! useindex(i)) + continue; + out << endl; + out << tab.m_itab[i]; + } + return out; +} + +// tt1 + tt1x1 tt1x2 tt1x3 tt1x4 + +static const Col +tt1col[] = { + { 0, "A", 1, NdbDictionary::Column::Unsigned, 1, 0 }, + { 1, "B", 0, NdbDictionary::Column::Unsigned, 1, 1 }, + { 2, "C", 0, NdbDictionary::Column::Unsigned, 1, 1 }, + { 3, "D", 0, NdbDictionary::Column::Unsigned, 1, 1 }, + { 4, "E", 0, NdbDictionary::Column::Unsigned, 1, 1 } +}; + +static const ICol +tt1x1col[] = { + { 0, tt1col[1] } +}; + +static const ICol +tt1x2col[] = { + { 0, tt1col[1] }, + { 1, tt1col[2] } +}; + +static const ICol +tt1x3col[] = { + { 0, tt1col[3] }, + { 1, tt1col[2] }, + { 2, tt1col[1] } +}; + +static const ICol +tt1x4col[] = { + { 0, tt1col[1] }, + { 1, tt1col[4] }, + { 2, tt1col[2] }, + { 3, tt1col[3] } +}; + +static const ITab +tt1x1 = { + "TT1X1", 1, tt1x1col +}; + +static const ITab +tt1x2 = { + "TT1X2", 2, tt1x2col +}; + +static const ITab +tt1x3 = { + "TT1X3", 3, tt1x3col +}; + +static const ITab +tt1x4 = { + "TT1X4", 4, tt1x4col +}; + +static const ITab +tt1itab[] = { + tt1x1, + tt1x2, + tt1x3, + tt1x4 +}; + +static const Tab +tt1 = { + "TT1", 5, tt1col, 4, tt1itab +}; + +// tt2 + tt2x1 tt2x2 tt2x3 + +static const Col +tt2col[] = { + { 0, "A", 1, NdbDictionary::Column::Unsigned, 1, 0 }, + { 1, "B", 0, NdbDictionary::Column::Unsigned, 1, 1 }, + { 2, "C", 0, NdbDictionary::Column::Varchar, 20, 1 }, + { 3, "D", 0, NdbDictionary::Column::Varchar, 5, 1 }, + { 4, "E", 0, NdbDictionary::Column::Varchar, 5, 1 } +}; + +static const ICol +tt2x1col[] = { + { 0, tt2col[1] }, + { 1, tt2col[2] } +}; + +static const ICol +tt2x2col[] = { + { 0, tt2col[2] }, + { 1, tt2col[1] } +}; + +static const ICol +tt2x3col[] = { + { 0, tt2col[3] }, + { 1, tt2col[4] } +}; + +static const ITab +tt2x1 = { + "TT2X1", 2, tt2x1col +}; + +static const ITab +tt2x2 = { + "TT2X2", 2, tt2x2col +}; + +static const ITab +tt2x3 = { + "TT2X3", 2, tt2x3col +}; + +static const ITab +tt2itab[] = { + tt2x1, + tt2x2, + tt2x3 +}; + +static const Tab +tt2 = { + "TT2", 5, tt2col, 3, tt2itab +}; + +// all tables + +static const Tab +tablist[] = { + tt1, + tt2 +}; + +static const unsigned +tabcount = sizeof(tablist) / sizeof(tablist[0]); + +// connections + +struct Con { + Ndb* m_ndb; + NdbDictionary::Dictionary* m_dic; + NdbConnection* m_tx; + NdbOperation* m_op; + NdbConnection* m_scantx; + NdbOperation* m_scanop; + enum ScanMode { ScanNo = 0, Committed, Latest, Exclusive }; + ScanMode m_scanmode; + enum ErrType { ErrNone = 0, ErrDeadlock, ErrOther }; + ErrType m_errtype; + Con() : + m_ndb(0), m_dic(0), m_tx(0), m_op(0), + m_scantx(0), m_scanop(0), m_scanmode(ScanNo), m_errtype(ErrNone) {} + int connect(); + void disconnect(); + int startTransaction(); + int startBuddyTransaction(const Con& con); + int getNdbOperation(const Tab& tab); + int getNdbOperation(const ITab& itab, const Tab& tab); + int equal(int num, const char* addr); + int getValue(int num, NdbRecAttr*& rec); + int setValue(int num, const char* addr); + int setBound(int num, int type, const void* value); + int execute(ExecType t); + int openScanRead(unsigned parallelism); + int openScanExclusive(unsigned parallelism); + int executeScan(); + int nextScanResult(); + int takeOverForUpdate(Con& scan); + int takeOverForDelete(Con& scan); + void closeTransaction(); + void printerror(NdbOut& out); + // flush dict cache + int bugger() { + //disconnect(); + //CHK(connect() == 0); + return 0; + } +}; + +int +Con::connect() +{ + assert(m_ndb == 0); + m_ndb = new Ndb("TEST_DB"); + CHKCON(m_ndb->init() == 0, *this); + CHKCON(m_ndb->waitUntilReady(30) == 0, *this); + m_dic = m_ndb->getDictionary(); + m_tx = 0, m_op = 0; + return 0; +} + +void +Con::disconnect() +{ + delete m_ndb; + m_ndb = 0, m_dic = 0, m_tx = 0, m_op = 0; +} + +int +Con::startTransaction() +{ + assert(m_ndb != 0 && m_tx == 0); + CHKCON((m_tx = m_ndb->startTransaction()) != 0, *this); + return 0; +} + +int +Con::startBuddyTransaction(const Con& con) +{ + assert(m_ndb != 0 && m_tx == 0 && con.m_ndb == m_ndb && con.m_tx != 0); + CHKCON((m_tx = m_ndb->hupp(con.m_tx)) != 0, *this); + return 0; +} + +int +Con::getNdbOperation(const Tab& tab) +{ + assert(m_tx != 0); + CHKCON((m_op = m_tx->getNdbOperation(tab.m_name)) != 0, *this); + return 0; +} + +int +Con::getNdbOperation(const ITab& itab, const Tab& tab) +{ + CHKCON((m_op = m_tx->getNdbOperation(itab.m_name, tab.m_name)) != 0, *this); + return 0; +} + +int +Con::equal(int num, const char* addr) +{ + assert(m_tx != 0 && m_op != 0); + CHKCON(m_op->equal(num, addr) == 0, *this); + return 0; +} + +int +Con::getValue(int num, NdbRecAttr*& rec) +{ + assert(m_tx != 0 && m_op != 0); + CHKCON((rec = m_op->getValue(num, 0)) != 0, *this); + return 0; +} + +int +Con::setValue(int num, const char* addr) +{ + assert(m_tx != 0 && m_op != 0); + CHKCON(m_op->setValue(num, addr) == 0, *this); + return 0; +} + +int +Con::setBound(int num, int type, const void* value) +{ + assert(m_tx != 0 && m_op != 0); + CHKCON(m_op->setBound(num, type, value) == 0, *this); + return 0; +} + +int +Con::execute(ExecType t) +{ + assert(m_tx != 0); + CHKCON(m_tx->execute(t) == 0, *this); + return 0; +} + +int +Con::openScanRead(unsigned parallelism) +{ + assert(m_tx != 0 && m_op != 0); + CHKCON(m_op->openScanRead(parallelism) == 0, *this); + return 0; +} + +int +Con::openScanExclusive(unsigned parallelism) +{ + assert(m_tx != 0 && m_op != 0); + CHKCON(m_op->openScanExclusive(parallelism) == 0, *this); + return 0; +} + +int +Con::executeScan() +{ + CHKCON(m_tx->executeScan() == 0, *this); + return 0; +} + +int +Con::nextScanResult() +{ + int ret; + CHKCON((ret = m_tx->nextScanResult()) != -1, *this); + assert(ret == 0 || ret == 1); + return ret; +} + +int +Con::takeOverForUpdate(Con& scan) +{ + assert(m_tx != 0 && scan.m_op != 0); + CHKCON((m_op = scan.m_op->takeOverForUpdate(m_tx)) != 0, scan); + return 0; +} + +int +Con::takeOverForDelete(Con& scan) +{ + assert(m_tx != 0 && scan.m_op != 0); + CHKCON((m_op = scan.m_op->takeOverForUpdate(m_tx)) != 0, scan); + return 0; +} + +void +Con::closeTransaction() +{ + assert(m_ndb != 0 && m_tx != 0); + m_ndb->closeTransaction(m_tx); + m_tx = 0, m_op = 0; +} + +void +Con::printerror(NdbOut& out) +{ + m_errtype = ErrOther; + unsigned any = 0; + int code; + if (m_ndb) { + if ((code = m_ndb->getNdbError().code) != 0) { + LL0(++any << " ndb: error " << m_ndb->getNdbError()); + } + if (m_dic && (code = m_dic->getNdbError().code) != 0) { + LL0(++any << " dic: error " << m_dic->getNdbError()); + } + if (m_tx) { + if ((code = m_tx->getNdbError().code) != 0) { + LL0(++any << " con: error " << m_tx->getNdbError()); + if (code == 266 || code == 274 || code == 296 || code == 297) + m_errtype = ErrDeadlock; + } + if (m_op && m_op->getNdbError().code != 0) { + LL0(++any << " op : error " << m_op->getNdbError()); + } + } + } + if (! any) { + LL0("failed but no NDB error code"); + } +} + +// dictionary operations + +static int +invalidateindex(Par par, const ITab& itab) +{ + Con& con = par.con(); + const Tab& tab = par.tab(); + con.m_dic->invalidateIndex(itab.m_name, tab.m_name); + return 0; +} + +static int +invalidateindex(Par par) +{ + Con& con = par.con(); + const Tab& tab = par.tab(); + for (unsigned i = 0; i < tab.m_itabs; i++) { + if (! useindex(i)) + continue; + const ITab& itab = tab.m_itab[i]; + invalidateindex(par, itab); + } + return 0; +} + +static int +invalidatetable(Par par) +{ + Con& con = par.con(); + const Tab& tab = par.tab(); + invalidateindex(par); + con.m_dic->invalidateTable(tab.m_name); + return 0; +} + +static int +droptable(Par par) +{ + Con& con = par.con(); + const Tab& tab = par.tab(); + if (con.m_dic->getTable(tab.m_name) == 0) { + // how to check for error + LL4("no table " << tab.m_name); + } else { + LL3("drop table " << tab.m_name); + CHKCON(con.m_dic->dropTable(tab.m_name) == 0, con); + } + return 0; +} + +static int +createtable(Par par) +{ + Con& con = par.con(); + CHK(con.bugger() == 0); + const Tab& tab = par.tab(); + LL3("create table " << tab.m_name); + LL4(tab); + NdbDictionary::Table t(tab.m_name); + if (par.m_fragtype != NdbDictionary::Object::FragUndefined) { + t.setFragmentType(par.m_fragtype); + } + for (unsigned k = 0; k < tab.m_cols; k++) { + const Col& col = tab.m_col[k]; + NdbDictionary::Column c(col.m_name); + c.setPrimaryKey(col.m_pk); + c.setType(col.m_type); + c.setLength(col.m_length); + c.setNullable(col.m_nullable); + t.addColumn(c); + } + CHKCON(con.m_dic->createTable(t) == 0, con); + return 0; +} + +static int +dropindex(Par par, const ITab& itab) +{ + Con& con = par.con(); + const Tab& tab = par.tab(); + if (con.m_dic->getIndex(itab.m_name, tab.m_name) == 0) { + // how to check for error + LL4("no index " << itab.m_name); + } else { + LL3("drop index " << itab.m_name); + CHKCON(con.m_dic->dropIndex(itab.m_name, tab.m_name) == 0, con); + } + return 0; +} + +static int +dropindex(Par par) +{ + const Tab& tab = par.tab(); + for (unsigned i = 0; i < tab.m_itabs; i++) { + if (! useindex(i)) + continue; + const ITab& itab = tab.m_itab[i]; + CHK(dropindex(par, itab) == 0); + } + return 0; +} + +static int +createindex(Par par, const ITab& itab) +{ + Con& con = par.con(); + CHK(con.bugger() == 0); + const Tab& tab = par.tab(); + LL3("create index " << itab.m_name); + LL4(itab); + NdbDictionary::Index x(itab.m_name); + x.setTable(tab.m_name); + x.setType(NdbDictionary::Index::OrderedIndex); + x.setLogging(false); + for (unsigned k = 0; k < itab.m_icols; k++) { + const Col& col = itab.m_icol[k].m_col; + x.addColumnName(col.m_name); + } + CHKCON(con.m_dic->createIndex(x) == 0, con); + return 0; +} + +static int +createindex(Par par) +{ + const Tab& tab = par.tab(); + for (unsigned i = 0; i < tab.m_itabs; i++) { + if (! useindex(i)) + continue; + const ITab& itab = tab.m_itab[i]; + CHK(createindex(par, itab) == 0); + } + return 0; +} + +// data sets + +static unsigned +urandom(unsigned n) +{ + if (n == 0) + return 0; + unsigned i = random() % n; + return i; +} + +static int +irandom(unsigned n) +{ + if (n == 0) + return 0; + int i = random() % n; + if (random() & 0x1) + i = -i; + return i; +} + +// Val - typed column value + +struct Val { + const Col& m_col; + union { + Uint32 m_uint32; + char* m_varchar; + }; + Val(const Col& col); + ~Val(); + void copy(const Val& val2); + void copy(const void* addr); + const void* dataaddr() const; + bool m_null; + int setval(Par par) const; + void calc(Par par, unsigned i); + int verify(const Val& val2) const; + int cmp(const Val& val2) const; +private: + Val& operator=(const Val& val2); +}; + +static NdbOut& +operator<<(NdbOut& out, const Val& val); + +Val::Val(const Col& col) : + m_col(col) +{ + switch (col.m_type) { + case NdbDictionary::Column::Unsigned: + break; + case NdbDictionary::Column::Varchar: + m_varchar = new char [2 + col.m_length]; + break; + default: + assert(false); + break; + } +} + +Val::~Val() +{ + const Col& col = m_col; + switch (col.m_type) { + case NdbDictionary::Column::Unsigned: + break; + case NdbDictionary::Column::Varchar: + delete [] m_varchar; + break; + default: + assert(false); + break; + } +} + +void +Val::copy(const Val& val2) +{ + const Col& col = m_col; + const Col& col2 = val2.m_col; + assert(col.m_type == col2.m_type && col.m_length == col2.m_length); + if (val2.m_null) { + m_null = true; + return; + } + copy(val2.dataaddr()); +} + +void +Val::copy(const void* addr) +{ + const Col& col = m_col; + switch (col.m_type) { + case NdbDictionary::Column::Unsigned: + m_uint32 = *(const Uint32*)addr; + break; + case NdbDictionary::Column::Varchar: + memcpy(m_varchar, addr, 2 + col.m_length); + break; + default: + assert(false); + break; + } + m_null = false; +} + +const void* +Val::dataaddr() const +{ + const Col& col = m_col; + switch (col.m_type) { + case NdbDictionary::Column::Unsigned: + return &m_uint32; + case NdbDictionary::Column::Varchar: + return m_varchar; + default: + break; + } + assert(false); + return 0; +} + +int +Val::setval(Par par) const +{ + Con& con = par.con(); + const Col& col = m_col; + const char* addr = (const char*)dataaddr(); + if (m_null) + addr = 0; + if (col.m_pk) + CHK(con.equal(col.m_num, addr) == 0); + else + CHK(con.setValue(col.m_num, addr) == 0); + LL5("setval [" << m_col << "] " << *this); + return 0; +} + +void +Val::calc(Par par, unsigned i) +{ + const Col& col = m_col; + m_null = false; + if (col.m_pk) { + m_uint32 = i; + return; + } + if (col.m_nullable && urandom(100) < par.m_pctnull) { + m_null = true; + return; + } + unsigned v = par.m_range + irandom((par.m_pctrange * par.m_range) / 100); + switch (col.m_type) { + case NdbDictionary::Column::Unsigned: + m_uint32 = v; + break; + case NdbDictionary::Column::Varchar: + { + unsigned n = 0; + while (n < col.m_length) { + if (urandom(1 + col.m_length) == 0) { + // nice distribution on lengths + break; + } + m_varchar[2 + n++] = 'a' + urandom((par.m_pctrange * 10) / 100); + } + m_varchar[0] = (n >> 8); + m_varchar[1] = (n & 0xff); + while (n < col.m_length) { + m_varchar[2 + n++] = 0; + } + } + break; + default: + assert(false); + break; + } + // verify format + col.verify(dataaddr()); +} + +int +Val::verify(const Val& val2) const +{ + CHK(cmp(val2) == 0); + return 0; +} + +int +Val::cmp(const Val& val2) const +{ + const Col& col = m_col; + const Col& col2 = val2.m_col; + assert(col.m_type == col2.m_type && col.m_length == col2.m_length); + if (m_null || val2.m_null) { + if (! m_null) + return -1; + if (! val2.m_null) + return +1; + return 0; + } + // verify data formats + col.verify(dataaddr()); + col.verify(val2.dataaddr()); + // compare + switch (col.m_type) { + case NdbDictionary::Column::Unsigned: + if (m_uint32 < val2.m_uint32) + return -1; + if (m_uint32 > val2.m_uint32) + return +1; + return 0; + case NdbDictionary::Column::Varchar: + return memcmp(&m_varchar[2], &val2.m_varchar[2], col.m_length); + default: + break; + } + assert(false); + return 0; +} + +static NdbOut& +operator<<(NdbOut& out, const Val& val) +{ + const Col& col = val.m_col; + if (val.m_null) { + out << "NULL"; + return out; + } + switch (col.m_type) { + case NdbDictionary::Column::Unsigned: + out << val.m_uint32; + break; + case NdbDictionary::Column::Varchar: + { + char buf[8000]; + unsigned n = (val.m_varchar[0] << 8) | val.m_varchar[1]; + assert(n <= col.m_length); + sprintf(buf, "'%.*s'[%d]", n, &val.m_varchar[2], n); + out << buf; + } + break; + default: + out << "type" << col.m_type; + assert(false); + break; + } + return out; +} + +// Row - table tuple + +struct Row { + const Tab& m_tab; + Val** m_val; + bool m_exist; + Row(const Tab& tab); + ~Row(); + void copy(const Row& row2); + void calc(Par par, unsigned i); + int verify(const Row& row2) const; + int insrow(Par par); + int updrow(Par par); + int delrow(Par par); + int selrow(Par par); + int setrow(Par par); + int cmp(const Row& row2) const; +private: + Row& operator=(const Row& row2); +}; + +Row::Row(const Tab& tab) : + m_tab(tab) +{ + m_val = new Val* [tab.m_cols]; + for (unsigned k = 0; k < tab.m_cols; k++) { + const Col& col = tab.m_col[k]; + m_val[k] = new Val(col); + } + m_exist = false; +} + +Row::~Row() +{ + const Tab& tab = m_tab; + for (unsigned k = 0; k < tab.m_cols; k++) { + delete m_val[k]; + } + delete [] m_val; +} + +void +Row::copy(const Row& row2) +{ + const Tab& tab = m_tab; + assert(&tab == &row2.m_tab); + for (unsigned k = 0; k < tab.m_cols; k++) { + Val& val = *m_val[k]; + const Val& val2 = *row2.m_val[k]; + val.copy(val2); + } +} + +void +Row::calc(Par par, unsigned i) +{ + const Tab& tab = m_tab; + for (unsigned k = 0; k < tab.m_cols; k++) { + Val& val = *m_val[k]; + val.calc(par, i); + } +} + +int +Row::verify(const Row& row2) const +{ + const Tab& tab = m_tab; + assert(&tab == &row2.m_tab); + for (unsigned k = 0; k < tab.m_cols; k++) { + const Val& val = *m_val[k]; + const Val& val2 = *row2.m_val[k]; + CHK(val.verify(val2) == 0); + } + return 0; +} + +int +Row::insrow(Par par) +{ + Con& con = par.con(); + const Tab& tab = m_tab; + assert(! m_exist); + CHK(con.getNdbOperation(tab) == 0); + CHKCON(con.m_op->insertTuple() == 0, con); + for (unsigned k = 0; k < tab.m_cols; k++) { + const Val& val = *m_val[k]; + CHK(val.setval(par) == 0); + } + m_exist = true; + return 0; +} + +int +Row::updrow(Par par) +{ + Con& con = par.con(); + const Tab& tab = m_tab; + assert(m_exist); + CHK(con.getNdbOperation(tab) == 0); + CHKCON(con.m_op->updateTuple() == 0, con); + for (unsigned k = 0; k < tab.m_cols; k++) { + const Val& val = *m_val[k]; + CHK(val.setval(par) == 0); + } + return 0; +} + +int +Row::delrow(Par par) +{ + Con& con = par.con(); + const Tab& tab = m_tab; + assert(m_exist); + CHK(con.getNdbOperation(m_tab) == 0); + CHKCON(con.m_op->deleteTuple() == 0, con); + for (unsigned k = 0; k < tab.m_cols; k++) { + const Val& val = *m_val[k]; + const Col& col = val.m_col; + if (col.m_pk) + CHK(val.setval(par) == 0); + } + m_exist = false; + return 0; +} + +int +Row::selrow(Par par) +{ + Con& con = par.con(); + const Tab& tab = m_tab; + CHK(con.getNdbOperation(m_tab) == 0); + CHKCON(con.m_op->readTuple() == 0, con); + for (unsigned k = 0; k < tab.m_cols; k++) { + const Val& val = *m_val[k]; + const Col& col = val.m_col; + if (col.m_pk) + CHK(val.setval(par) == 0); + } + m_exist = false; + return 0; +} + +int +Row::setrow(Par par) +{ + Con& con = par.con(); + const Tab& tab = m_tab; + for (unsigned k = 0; k < tab.m_cols; k++) { + const Val& val = *m_val[k]; + const Col& col = val.m_col; + if (! col.m_pk) + CHK(val.setval(par) == 0); + } + return 0; +} + +int +Row::cmp(const Row& row2) const +{ + const Tab& tab = m_tab; + assert(&tab == &row2.m_tab); + int c = 0; + for (unsigned k = 0; k < tab.m_cols; k++) { + const Val& val = *m_val[k]; + const Val& val2 = *row2.m_val[k]; + if ((c = val.cmp(val2)) != 0) + break; + } + return c; +} + +static NdbOut& +operator<<(NdbOut& out, const Row& row) +{ + const Tab& tab = row.m_tab; + for (unsigned i = 0; i < tab.m_cols; i++) { + if (i > 0) + out << " "; + out << *row.m_val[i]; + } + return out; +} + +// Set - set of table tuples + +struct Set { + const Tab& m_tab; + unsigned m_rows; + unsigned m_count; + Row** m_row; + Row** m_saverow; + Row* m_keyrow; + NdbRecAttr** m_rec; + Set(const Tab& tab, unsigned rows); + ~Set(); + // row methods + bool exist(unsigned i) const; + void calc(Par par, unsigned i); + int insrow(Par par, unsigned i); + int updrow(Par par, unsigned i); + int delrow(Par par, unsigned i); + int selrow(Par par, unsigned i); + int setrow(Par par, unsigned i); + int getval(Par par); + int getkey(Par par, unsigned* i); + int putval(unsigned i, bool force); + // set methods + int verify(const Set& set2) const; + void savepoint(); + void commit(); + void rollback(); + // locking (not perfect since ops may complete in different order) + NdbMutex* m_mutex; + void lock() { + NdbMutex_Lock(m_mutex); + } + void unlock() { + NdbMutex_Unlock(m_mutex); + } +private: + Set& operator=(const Set& set2); +}; + +Set::Set(const Tab& tab, unsigned rows) : + m_tab(tab) +{ + m_rows = rows; + m_count = 0; + m_row = new Row* [m_rows]; + for (unsigned i = 0; i < m_rows; i++) { + m_row[i] = 0; + } + m_saverow = 0; + m_keyrow = new Row(tab); + m_rec = new NdbRecAttr* [tab.m_cols]; + for (unsigned k = 0; k < tab.m_cols; k++) { + m_rec[k] = 0; + } + m_mutex = NdbMutex_Create(); + assert(m_mutex != 0); +} + +Set::~Set() +{ + for (unsigned i = 0; i < m_rows; i++) { + delete m_row[i]; + if (m_saverow != 0) + delete m_saverow[i]; + } + delete [] m_row; + delete [] m_saverow; + delete m_keyrow; + delete [] m_rec; + NdbMutex_Destroy(m_mutex); +} + +bool +Set::exist(unsigned i) const +{ + assert(i < m_rows); + return m_row[i] != 0 && m_row[i]->m_exist; +} + +void +Set::calc(Par par, unsigned i) +{ + const Tab& tab = m_tab; + if (m_row[i] == 0) + m_row[i] = new Row(tab); + Row& row = *m_row[i]; + // value generation parameters + par.m_pctnull = 10; + par.m_pctrange = 40; + row.calc(par, i); +} + +int +Set::insrow(Par par, unsigned i) +{ + assert(m_row[i] != 0 && m_count < m_rows); + CHK(m_row[i]->insrow(par) == 0); + m_count++; + return 0; +} + +int +Set::updrow(Par par, unsigned i) +{ + assert(m_row[i] != 0); + CHK(m_row[i]->updrow(par) == 0); + return 0; +} + +int +Set::delrow(Par par, unsigned i) +{ + assert(m_row[i] != 0 && m_count != 0); + CHK(m_row[i]->delrow(par) == 0); + m_count--; + return 0; +} + +int +Set::selrow(Par par, unsigned i) +{ + Con& con = par.con(); + m_keyrow->calc(par, i); + CHK(m_keyrow->selrow(par) == 0); + CHK(getval(par) == 0); + return 0; +} + +int +Set::setrow(Par par, unsigned i) +{ + Con& con = par.con(); + assert(m_row[i] != 0); + CHK(m_row[i]->setrow(par) == 0); + return 0; +} + +int +Set::getval(Par par) +{ + Con& con = par.con(); + const Tab& tab = m_tab; + for (unsigned k = 0; k < tab.m_cols; k++) { + CHK(con.getValue(k, m_rec[k]) == 0); + } + return 0; +} + +int +Set::getkey(Par par, unsigned* i) +{ + assert(m_rec[0] != 0); + const char* aRef0 = m_rec[0]->aRef(); + Uint32 key = *(const Uint32*)aRef0; + CHKMSG(key < m_rows, "key=" << key << " rows=" << m_rows); + *i = key; + return 0; +} + +int +Set::putval(unsigned i, bool force) +{ + const Tab& tab = m_tab; + if (m_row[i] == 0) + m_row[i] = new Row(tab); + Row& row = *m_row[i]; + CHK(! row.m_exist || force); + for (unsigned k = 0; k < tab.m_cols; k++) { + Val& val = *row.m_val[k]; + NdbRecAttr* rec = m_rec[k]; + assert(rec != 0); + if (rec->isNULL()) { + val.m_null = true; + continue; + } + const char* aRef = m_rec[k]->aRef(); + val.copy(aRef); + val.m_null = false; + } + if (! row.m_exist) { + row.m_exist = true; + m_count++; + } + return 0; +} + +int +Set::verify(const Set& set2) const +{ + const Tab& tab = m_tab; + assert(&tab == &set2.m_tab && m_rows == set2.m_rows); + CHKMSG(m_count == set2.m_count, "set=" << m_count << " set2=" << set2.m_count); + for (unsigned i = 0; i < m_rows; i++) { + CHK(exist(i) == set2.exist(i)); + if (! exist(i)) + continue; + Row& row = *m_row[i]; + Row& row2 = *set2.m_row[i]; + CHK(row.verify(row2) == 0); + } + return 0; +} + +void +Set::savepoint() +{ + const Tab& tab = m_tab; + assert(m_saverow == 0); + m_saverow = new Row* [m_rows]; + for (unsigned i = 0; i < m_rows; i++) { + if (m_row[i] == 0) + m_saverow[i] = 0; + else { + m_saverow[i] = new Row(tab); + m_saverow[i]->copy(*m_row[i]); + } + } +} + +void +Set::commit() +{ + delete [] m_saverow; + m_saverow = 0; +} + +void +Set::rollback() +{ + assert(m_saverow != 0); + m_row = m_saverow; + m_saverow = 0; +} + +static NdbOut& +operator<<(NdbOut& out, const Set& set) +{ + for (unsigned i = 0; i < set.m_rows; i++) { + const Row& row = *set.m_row[i]; + if (i > 0) + out << endl; + out << row; + } + return out; +} + +// BVal - range scan bound + +struct BVal : public Val { + const ICol& m_icol; + int m_type; + BVal(const ICol& icol); + int setbnd(Par par) const; +}; + +BVal::BVal(const ICol& icol) : + Val(icol.m_col), + m_icol(icol) +{ +} + +int +BVal::setbnd(Par par) const +{ + Con& con = par.con(); + const char* addr = (const char*)dataaddr(); + assert(! m_null); + const ICol& icol = m_icol; + CHK(con.setBound(icol.m_num, m_type, addr) == 0); + return 0; +} + +static NdbOut& +operator<<(NdbOut& out, const BVal& bval) +{ + const ICol& icol = bval.m_icol; + const Col& col = icol.m_col; + const Val& val = bval; + out << "type " << bval.m_type; + out << " icol " << icol.m_num; + out << " col " << col.m_name << "(" << col.m_num << ")"; + out << " value " << val; + return out; +} + +// BSet - set of bounds + +struct BSet { + const Tab& m_tab; + const ITab& m_itab; + unsigned m_alloc; + unsigned m_bvals; + BVal** m_bval; + BSet(const Tab& tab, const ITab& itab, unsigned rows); + void calc(Par par); + int setbnd(Par par) const; + void filter(const Set& set, Set& set2) const; +}; + +BSet::BSet(const Tab& tab, const ITab& itab, unsigned rows) : + m_tab(tab), + m_itab(itab), + m_alloc(2 * itab.m_icols), + m_bvals(0) +{ + m_bval = new BVal* [m_alloc]; +} + +void +BSet::calc(Par par) +{ + const ITab& itab = m_itab; + for (unsigned k = 0; k < itab.m_icols; k++) { + const ICol& icol = itab.m_icol[k]; + const Col& col = icol.m_col; + for (unsigned i = 0; i <= 1; i++) { + if (urandom(10) == 0) + return; + assert(m_bvals < m_alloc); + BVal& bval = *new BVal(icol); + m_bval[m_bvals++] = &bval; + bval.m_null = false; + // equality bound only on i==0 + unsigned sel = urandom(5 - i); + if (sel < 2) + bval.m_type = 0 | (1 << i); + else if (sel < 4) + bval.m_type = 1 | (1 << i); + else + bval.m_type = 4; + if (k + 1 < itab.m_icols) + bval.m_type = 4; + // value generation parammeters + par.m_pctnull = 0; + par.m_pctrange = 50; // bit higher + do { + bval.calc(par, 0); + if (i == 1) { + assert(m_bvals >= 2); + const BVal& bv1 = *m_bval[m_bvals - 2]; + const BVal& bv2 = *m_bval[m_bvals - 1]; + if (bv1.cmp(bv2) > 0 && urandom(100) != 0) + continue; + } + } while (0); + // equality bound only once + if (bval.m_type == 4) + break; + } + } +} + +int +BSet::setbnd(Par par) const +{ + for (unsigned j = 0; j < m_bvals; j++) { + const BVal& bval = *m_bval[j]; + CHK(bval.setbnd(par) == 0); + } + return 0; +} + +void +BSet::filter(const Set& set, Set& set2) const +{ + const Tab& tab = m_tab; + const ITab& itab = m_itab; + assert(&tab == &set2.m_tab && set.m_rows == set2.m_rows); + assert(set2.m_count == 0); + for (unsigned i = 0; i < set.m_rows; i++) { + if (! set.exist(i)) + continue; + const Row& row = *set.m_row[i]; + bool ok1 = false; + for (unsigned k = 0; k < itab.m_icols; k++) { + const ICol& icol = itab.m_icol[k]; + const Col& col = icol.m_col; + const Val& val = *row.m_val[col.m_num]; + if (! val.m_null) { + ok1 = true; + break; + } + } + if (! ok1) + continue; + bool ok2 = true; + for (unsigned j = 0; j < m_bvals; j++) { + const BVal& bval = *m_bval[j]; + const ICol& icol = bval.m_icol; + const Col& col = icol.m_col; + const Val& val = *row.m_val[col.m_num]; + int ret = bval.cmp(val); + if (bval.m_type == 0) + ok2 = (ret <= 0); + else if (bval.m_type == 1) + ok2 = (ret < 0); + else if (bval.m_type == 2) + ok2 = (ret >= 0); + else if (bval.m_type == 3) + ok2 = (ret > 0); + else if (bval.m_type == 4) + ok2 = (ret == 0); + else { + assert(false); + } + if (! ok2) + break; + } + if (! ok2) + continue; + if (set2.m_row[i] == 0) + set2.m_row[i] = new Row(tab); + Row& row2 = *set2.m_row[i]; + assert(! row2.m_exist); + row2.copy(row); + row2.m_exist = true; + set2.m_count++; + } +} + +static NdbOut& +operator<<(NdbOut& out, const BSet& bset) +{ + out << "bounds=" << bset.m_bvals; + for (unsigned j = 0; j < bset.m_bvals; j++) { + out << endl; + const BVal& bval = *bset.m_bval[j]; + out << "bound " << j << ": " << bval; + } + return out; +} + +// pk operations + +static int +pkinsert(Par par) +{ + Con& con = par.con(); + Set& set = par.set(); + LL3("pkinsert"); + CHK(con.startTransaction() == 0); + unsigned n = 0; + for (unsigned j = 0; j < par.m_rows; j++) { + unsigned i = thrrow(par, j); + set.lock(); + if (set.exist(i)) { + set.unlock(); + continue; + } + set.calc(par, i); + LL4("pkinsert " << i << ": " << *set.m_row[i]); + CHKTRY(set.insrow(par, i) == 0, set.unlock()); + set.unlock(); + if (++n == par.m_batch) { + CHK(con.execute(Commit) == 0); + con.closeTransaction(); + CHK(con.startTransaction() == 0); + n = 0; + } + } + if (n != 0) { + CHK(con.execute(Commit) == 0); + n = 0; + } + con.closeTransaction(); + return 0; +}; + +static int +pkupdate(Par par) +{ + Con& con = par.con(); + Set& set = par.set(); + LL3("pkupdate"); + CHK(con.startTransaction() == 0); + unsigned n = 0; + for (unsigned j = 0; j < par.m_rows; j++) { + unsigned i = thrrow(par, j); + set.lock(); + if (! set.exist(i)) { + set.unlock(); + continue; + } + set.calc(par, i); + LL4("pkupdate " << i << ": " << *set.m_row[i]); + CHKTRY(set.updrow(par, i) == 0, set.unlock()); + set.unlock(); + if (++n == par.m_batch) { + CHK(con.execute(Commit) == 0); + con.closeTransaction(); + CHK(con.startTransaction() == 0); + n = 0; + } + } + if (n != 0) { + CHK(con.execute(Commit) == 0); + n = 0; + } + con.closeTransaction(); + return 0; +}; + +static int +pkdelete(Par par) +{ + Con& con = par.con(); + Set& set = par.set(); + LL3("pkdelete"); + CHK(con.startTransaction() == 0); + unsigned n = 0; + for (unsigned j = 0; j < par.m_rows; j++) { + unsigned i = thrrow(par, j); + set.lock(); + if (! set.exist(i)) { + set.unlock(); + continue; + } + LL4("pkdelete " << i << ": " << *set.m_row[i]); + CHKTRY(set.delrow(par, i) == 0, set.unlock()); + set.unlock(); + if (++n == par.m_batch) { + CHK(con.execute(Commit) == 0); + con.closeTransaction(); + CHK(con.startTransaction() == 0); + n = 0; + } + } + if (n != 0) { + CHK(con.execute(Commit) == 0); + n = 0; + } + con.closeTransaction(); + return 0; +}; + +static int +pkread(Par par) +{ + Con& con = par.con(); + const Tab& tab = par.tab(); + const Set& set = par.set(); + LL3((par.m_verify ? "pkverify " : "pkread ") << tab.m_name); + // expected + const Set& set1 = set; + Set set2(tab, set.m_rows); + for (unsigned i = 0; i < set.m_rows; i++) { + if (! set.exist(i)) + continue; + CHK(con.startTransaction() == 0); + CHK(set2.selrow(par, i) == 0); + CHK(con.execute(Commit) == 0); + unsigned i2 = (unsigned)-1; + CHK(set2.getkey(par, &i2) == 0 && i == i2); + CHK(set2.putval(i, false) == 0); + LL4("row " << set2.m_count << ": " << *set2.m_row[i]); + con.closeTransaction(); + } + if (par.m_verify) + CHK(set1.verify(set2) == 0); + return 0; +} + +// scan read + +static int +scanreadtable(Par par) +{ + Con& con = par.con(); + const Tab& tab = par.tab(); + const Set& set = par.set(); + // expected + const Set& set1 = set; + LL3((par.m_verify ? "scanverify " : "scanread ") << tab.m_name); + Set set2(tab, set.m_rows); + CHK(con.startTransaction() == 0); + CHK(con.getNdbOperation(tab) == 0); + CHK(con.openScanRead(par.m_scanrd) == 0); + set2.getval(par); + CHK(con.executeScan() == 0); + while (1) { + int ret; + CHK((ret = con.nextScanResult()) == 0 || ret == 1); + if (ret == 1) + break; + unsigned i = (unsigned)-1; + CHK(set2.getkey(par, &i) == 0); + CHK(set2.putval(i, false) == 0); + LL4("row " << set2.m_count << ": " << *set2.m_row[i]); + } + con.closeTransaction(); + if (par.m_verify) + CHK(set1.verify(set2) == 0); + return 0; +} + +static int +scanreadindex(Par par, const ITab& itab, const BSet& bset) +{ + Con& con = par.con(); + const Tab& tab = par.tab(); + const Set& set = par.set(); + // expected + Set set1(tab, set.m_rows); + bset.filter(set, set1); + LL3((par.m_verify ? "scanverify " : "scanread ") << itab.m_name << " bounds=" << bset.m_bvals); + LL4(bset); + Set set2(tab, set.m_rows); + CHK(con.startTransaction() == 0); + CHK(con.getNdbOperation(itab, tab) == 0); + CHK(con.openScanRead(par.m_scanrd) == 0); + CHK(bset.setbnd(par) == 0); + set2.getval(par); + CHK(con.executeScan() == 0); + while (1) { + int ret; + CHK((ret = con.nextScanResult()) == 0 || ret == 1); + if (ret == 1) + break; + unsigned i = (unsigned)-1; + CHK(set2.getkey(par, &i) == 0); + LL4("key " << i); + CHK(set2.putval(i, par.m_dups) == 0); + LL4("row " << set2.m_count << ": " << *set2.m_row[i]); + } + con.closeTransaction(); + if (par.m_verify) + CHK(set1.verify(set2) == 0); + return 0; +} + +static int +scanreadindex(Par par, const ITab& itab) +{ + const Tab& tab = par.tab(); + for (unsigned i = 0; i < par.m_subloop; i++) { + BSet bset(tab, itab, par.m_rows); + bset.calc(par); + CHK(scanreadindex(par, itab, bset) == 0); + } + return 0; +} + +static int +scanreadindex(Par par) +{ + const Tab& tab = par.tab(); + for (unsigned i = 0; i < tab.m_itabs; i++) { + if (! useindex(i)) + continue; + const ITab& itab = tab.m_itab[i]; + CHK(scanreadindex(par, itab) == 0); + } + return 0; +} + +static int +scanreadall(Par par) +{ + if (par.m_no < 11) + CHK(scanreadtable(par) == 0); + CHK(scanreadindex(par) == 0); + return 0; +} + +// scan update + +static int +scanupdatetable(Par par) +{ + Con& con = par.con(); + const Tab& tab = par.tab(); + Set& set = par.set(); + LL3("scan update " << tab.m_name); + Set set2(tab, set.m_rows); + CHK(con.startTransaction() == 0); + CHK(con.getNdbOperation(tab) == 0); + CHK(con.openScanExclusive(par.m_scanex) == 0); + set2.getval(par); + CHK(con.executeScan() == 0); + unsigned count = 0; + // updating trans + Con con2; + con2.m_ndb = con.m_ndb; + CHK(con2.startBuddyTransaction(con) == 0); + while (1) { + int ret; + CHK((ret = con.nextScanResult()) == 0 || ret == 1); + if (ret == 1) + break; + unsigned i = (unsigned)-1; + CHK(set2.getkey(par, &i) == 0); + LL4("key " << i); + CHK(set2.putval(i, false) == 0); + CHK(con2.takeOverForUpdate(con) == 0); + Par par2 = par; + par2.m_con = &con2; + set.lock(); + set.calc(par, i); + LL4("scan update " << tab.m_name << ": " << *set.m_row[i]); + CHKTRY(set.setrow(par2, i) == 0, set.unlock()); + set.unlock(); + CHK(con2.execute(NoCommit) == 0); + count++; + } + CHK(con2.execute(Commit) == 0); + con2.closeTransaction(); + LL3("scan update " << tab.m_name << " rows updated=" << count); + con.closeTransaction(); + return 0; +} + +static int +scanupdateindex(Par par, const ITab& itab, const BSet& bset) +{ + Con& con = par.con(); + const Tab& tab = par.tab(); + Set& set = par.set(); + LL3("scan update " << itab.m_name); + Set set2(tab, set.m_rows); + CHK(con.startTransaction() == 0); + CHK(con.getNdbOperation(itab, tab) == 0); + CHK(con.openScanExclusive(par.m_scanex) == 0); + CHK(bset.setbnd(par) == 0); + set2.getval(par); + CHK(con.executeScan() == 0); + unsigned count = 0; + // updating trans + Con con2; + con2.m_ndb = con.m_ndb; + CHK(con2.startBuddyTransaction(con) == 0); + while (1) { + int ret; + CHK((ret = con.nextScanResult()) == 0 || ret == 1); + if (ret == 1) + break; + unsigned i = (unsigned)-1; + CHK(set2.getkey(par, &i) == 0); + LL4("key " << i); + CHK(set2.putval(i, par.m_dups) == 0); + // avoid deadlock for now + //if (! isthrrow(par, i)) + //continue; + CHK(con2.takeOverForUpdate(con) == 0); + Par par2 = par; + par2.m_con = &con2; + set.lock(); + set.calc(par, i); + LL4("scan update " << itab.m_name << ": " << *set.m_row[i]); + CHKTRY(set.setrow(par2, i) == 0, set.unlock()); + set.unlock(); + CHK(con2.execute(NoCommit) == 0); + count++; + } + CHK(con2.execute(Commit) == 0); + con2.closeTransaction(); + LL3("scan update " << itab.m_name << " rows updated=" << count); + con.closeTransaction(); + return 0; +} + +static int +scanupdateindex(Par par, const ITab& itab) +{ + const Tab& tab = par.tab(); + for (unsigned i = 0; i < par.m_subloop; i++) { + BSet bset(tab, itab, par.m_rows); + bset.calc(par); + CHK(scanupdateindex(par, itab, bset) == 0); + } + return 0; +} + +static int +scanupdateindex(Par par) +{ + const Tab& tab = par.tab(); + for (unsigned i = 0; i < tab.m_itabs; i++) { + if (! useindex(i)) + continue; + const ITab& itab = tab.m_itab[i]; + CHK(scanupdateindex(par, itab) == 0); + } + return 0; +} + +static int +scanupdateall(Par par) +{ + CHK(scanupdatetable(par) == 0); + CHK(scanupdateindex(par) == 0); + return 0; +} + +// medium level routines + +static bool +ignoreverifyerror(Par par) +{ + Con& con = par.con(); + bool b = par.m_threads > 1; + if (b) { + LL1("ignore verify error"); + if (con.m_tx != 0) + con.closeTransaction(); + return true; + } + return b; +} + +static int +readverify(Par par) +{ + par.m_verify = true; + CHK(pkread(par) == 0 || ignoreverifyerror(par)); + CHK(scanreadall(par) == 0 || ignoreverifyerror(par)); + return 0; +} + +static bool +ignoredeadlock(Par par) +{ + Con& con = par.con(); + if (con.m_errtype == Con::ErrDeadlock) { + LL1("ignore deadlock"); + con.closeTransaction(); + return true; + } + return false; +} + +static int +pkupdatescanread(Par par) +{ + par.m_dups = true; + unsigned sel = urandom(10); + if (sel < 5) { + CHK(pkupdate(par) == 0); + } else if (sel < 6) { + par.m_verify = false; + CHK(scanreadtable(par) == 0); + } else { + par.m_verify = false; + CHK(scanreadindex(par) == 0); + } + return 0; +} + +static int +mixedoperations(Par par) +{ + par.m_dups = true; + unsigned sel = urandom(10); + if (sel < 2) { + CHK(pkdelete(par) == 0 || ignoredeadlock(par)); + } else if (sel < 4) { + CHK(pkupdate(par) == 0 || ignoredeadlock(par)); + } else if (sel < 6) { + CHK(scanupdatetable(par) == 0 || ignoredeadlock(par)); + } else { + CHK(scanupdateindex(par) == 0 || ignoredeadlock(par)); + } + return 0; +} + +static int +pkupdateindexbuild(Par par) +{ + if (par.m_no == 0) { + CHK(createindex(par) == 0); + CHK(invalidateindex(par) == 0); + } else { + CHK(pkupdate(par) == 0); + } + return 0; +} + +// threads + +typedef int (*TFunc)(Par par); +enum TMode { ST = 1, MT = 2 }; + +extern "C" { static void* runthread(void* arg); } + +struct Thr { + enum State { Wait, Start, Stop, Stopped, Exit }; + State m_state; + Par m_par; + Uint64 m_id; + NdbThread* m_thread; + NdbMutex* m_mutex; + NdbCondition* m_cond; + TFunc m_func; + int m_ret; + void* m_status; + Thr(Par par, unsigned n); + ~Thr(); + int run(); + void start(); + void stop(); + void stopped(); + void exit(); + // + void lock() { + NdbMutex_Lock(m_mutex); + } + void unlock() { + NdbMutex_Unlock(m_mutex); + } + void wait() { + NdbCondition_Wait(m_cond, m_mutex); + } + void signal() { + NdbCondition_Signal(m_cond); + } + void join() { + NdbThread_WaitFor(m_thread, &m_status); + m_thread = 0; + } +}; + +Thr::Thr(Par par, unsigned n) : + m_state(Wait), + m_par(par), + m_id(0), + m_thread(0), + m_mutex(0), + m_cond(0), + m_func(0), + m_ret(0), + m_status(0) +{ + m_par.m_no = n; + char buf[10]; + sprintf(buf, "thr%03u", par.m_no); + const char* name = strcpy(new char[10], buf); + // mutex + m_mutex = NdbMutex_Create(); + m_cond = NdbCondition_Create(); + assert(m_mutex != 0 && m_cond != 0); + // run + const unsigned stacksize = 256 * 1024; + const NDB_THREAD_PRIO prio = NDB_THREAD_PRIO_LOW; + m_thread = NdbThread_Create(runthread, (void**)this, stacksize, name, prio); +} + +Thr::~Thr() +{ + if (m_thread != 0) { + NdbThread_Destroy(&m_thread); + m_thread = 0; + } + if (m_cond != 0) { + NdbCondition_Destroy(m_cond); + m_cond = 0; + } + if (m_mutex != 0) { + NdbMutex_Destroy(m_mutex); + m_mutex = 0; + } +} + +static void* +runthread(void* arg) +{ + Thr& thr = *(Thr*)arg; + thr.m_id = (Uint64)pthread_self(); + if (thr.run() < 0) { + LL1("exit on error"); + } else { + LL4("exit ok"); + } + return 0; +} + +int +Thr::run() +{ + LL4("run"); + Con con; + CHK(con.connect() == 0); + m_par.m_con = &con; + LL4("connected"); + while (1) { + lock(); + while (m_state != Start && m_state != Exit) { + LL4("wait"); + wait(); + } + if (m_state == Exit) { + LL4("exit"); + unlock(); + break; + } + LL4("start"); + CHK(con.bugger() == 0); + assert(m_state == Start); + m_ret = (*m_func)(m_par); + m_state = Stopped; + LL4("stop"); + signal(); + unlock(); + CHK(m_ret == 0); + } + con.disconnect(); + return 0; +} + +void +Thr::start() +{ + lock(); + m_state = Start; + signal(); + unlock(); +} + +void +Thr::stop() +{ + lock(); + m_state = Stop; + signal(); + unlock(); +} + +void +Thr::stopped() +{ + lock(); + while (m_state != Stopped) + wait(); + m_state = Wait; + unlock(); +} + +void +Thr::exit() +{ + lock(); + m_state = Exit; + signal(); + unlock(); +} + +// test run + +static Thr** g_thrlist = 0; + +static unsigned +getthrno() +{ + if (g_thrlist != 0) { + Uint64 id = (Uint64)pthread_self(); + for (unsigned n = 0; n < g_opt.m_threads; n++) { + if (g_thrlist[n] != 0) { + const Thr& thr = *g_thrlist[n]; + if (thr.m_id == id) + return thr.m_par.m_no; + } + } + } + return (unsigned)-1; +} + +static int +runstep(Par par, const char* fname, TFunc func, unsigned mode) +{ + LL2(fname); + const int threads = (mode & ST ? 1 : par.m_threads); + for (int n = 0; n < threads; n++) { + LL4("start " << n); + Thr& thr = *g_thrlist[n]; + thr.m_par.m_tab = par.m_tab; + thr.m_par.m_set = par.m_set; + thr.m_func = func; + thr.start(); + } + unsigned errs = 0; + for (int n = threads - 1; n >= 0; n--) { + LL4("stop " << n); + Thr& thr = *g_thrlist[n]; + thr.stopped(); + if (thr.m_ret != 0) + errs++; + } + CHK(errs == 0); + return 0; +} + +#define RUNSTEP(par, func, mode) CHK(runstep(par, #func, func, mode) == 0) + +static int +tbuild(Par par) +{ + RUNSTEP(par, droptable, ST); + RUNSTEP(par, createtable, ST); + RUNSTEP(par, invalidatetable, MT); + for (unsigned i = 0; i < par.m_subloop; i++) { + if (i % 2 == 0) { + RUNSTEP(par, createindex, ST); + RUNSTEP(par, invalidateindex, MT); + RUNSTEP(par, pkinsert, MT); + } else { + RUNSTEP(par, pkinsert, MT); + RUNSTEP(par, createindex, ST); + RUNSTEP(par, invalidateindex, MT); + } + RUNSTEP(par, readverify, MT); + RUNSTEP(par, pkdelete, MT); + RUNSTEP(par, readverify, MT); + RUNSTEP(par, dropindex, ST); + } + return 0; +} + +static int +tpkops(Par par) +{ + RUNSTEP(par, droptable, ST); + RUNSTEP(par, createtable, ST); + RUNSTEP(par, invalidatetable, MT); + RUNSTEP(par, pkinsert, MT); + RUNSTEP(par, createindex, ST); + RUNSTEP(par, invalidateindex, MT); + RUNSTEP(par, readverify, MT); + for (unsigned i = 0; i < par.m_subloop; i++) { + RUNSTEP(par, pkupdatescanread, MT); + RUNSTEP(par, readverify, MT); + } + RUNSTEP(par, pkdelete, MT); + RUNSTEP(par, readverify, MT); + return 0; +} + +static int +tmixedops(Par par) +{ + RUNSTEP(par, droptable, ST); + RUNSTEP(par, createtable, ST); + RUNSTEP(par, invalidatetable, MT); + RUNSTEP(par, pkinsert, MT); + RUNSTEP(par, createindex, ST); + RUNSTEP(par, invalidateindex, MT); + RUNSTEP(par, readverify, MT); + for (unsigned i = 0; i < par.m_subloop; i++) { + RUNSTEP(par, mixedoperations, MT); + RUNSTEP(par, readverify, MT); + } + return 0; +} + +static int +tbusybuild(Par par) +{ + RUNSTEP(par, droptable, ST); + RUNSTEP(par, createtable, ST); + RUNSTEP(par, invalidatetable, MT); + RUNSTEP(par, pkinsert, MT); + for (unsigned i = 0; i < par.m_subloop; i++) { + RUNSTEP(par, pkupdateindexbuild, MT); + RUNSTEP(par, readverify, MT); + RUNSTEP(par, dropindex, ST); + } + return 0; +} + +static int +ttiming(Par par) +{ + Tmr t0, t1, t2; + RUNSTEP(par, droptable, ST); + RUNSTEP(par, createtable, ST); + RUNSTEP(par, invalidatetable, MT); + for (unsigned i = 0; i < par.m_subloop; i++) { + RUNSTEP(par, pkinsert, MT); + t1.on(); + RUNSTEP(par, pkupdate, MT); + t1.off(par.m_totrows); + t0.on(); + RUNSTEP(par, createindex, ST); + RUNSTEP(par, invalidateindex, MT); + t0.off(par.m_totrows); + t2.on(); + RUNSTEP(par, pkupdate, MT); + t2.off(par.m_totrows); + RUNSTEP(par, dropindex, ST); + } + LL1("build index - " << t0.time()); + LL1("update - " << t1.time()); + LL1("update indexed - " << t2.time()); + LL1("overhead - " << t2.over(t1)); + return 0; +} + +static int +tdrop(Par par) +{ + RUNSTEP(par, droptable, ST); + return 0; +} + +struct TCase { + const char* m_name; + TFunc m_func; + const char* m_desc; + TCase(const char* name, TFunc func, const char* desc) : + m_name(name), + m_func(func), + m_desc(desc) { + } +}; + +static const TCase +tcaselist[] = { + TCase("a", tbuild, "index build"), + TCase("b", tpkops, "pk operations and scan reads"), + TCase("c", tmixedops, "pk operations and scan operations"), + TCase("d", tbusybuild, "pk operations and index build"), + TCase("t", ttiming, "time index build and maintenance"), + TCase("z", tdrop, "drop test tables") +}; + +static const unsigned +tcasecount = sizeof(tcaselist) / sizeof(tcaselist[0]); + +static void +printcases() +{ + ndbout << "test cases:" << endl; + for (unsigned i = 0; i < tcasecount; i++) { + const TCase& tcase = tcaselist[i]; + ndbout << " " << tcase.m_name << " - " << tcase.m_desc << endl; + } +} + +static void +printtables() +{ + ndbout << "tables and indexes:" << endl; + for (unsigned j = 0; j < tabcount; j++) { + const Tab& tab = tablist[j]; + ndbout << " " << tab.m_name; + for (unsigned i = 0; i < tab.m_itabs; i++) { + const ITab& itab = tab.m_itab[i]; + ndbout << " " << itab.m_name; + } + ndbout << endl; + } +} + +static int +runtest(Par par) +{ + LL1("start"); + srandom(par.m_seed); + Con con; + CHK(con.connect() == 0); + par.m_con = &con; + g_thrlist = new Thr* [par.m_threads]; + for (unsigned n = 0; n < par.m_threads; n++) { + g_thrlist[n] = 0; + } + for (unsigned n = 0; n < par.m_threads; n++) { + g_thrlist[n] = new Thr(par, n); + Thr& thr = *g_thrlist[n]; + assert(thr.m_thread != 0); + } + for (unsigned l = 0; par.m_loop == 0 || l < par.m_loop; l++) { + LL1("loop " << l); + for (unsigned i = 0; i < tcasecount; i++) { + const TCase& tcase = tcaselist[i]; + if (par.m_case != 0 && strchr(par.m_case, tcase.m_name[0]) == 0) + continue; + LL1("case " << tcase.m_name << " - " << tcase.m_desc); + for (unsigned j = 0; j < tabcount; j++) { + if (! usetable(j)) + continue; + const Tab& tab = tablist[j]; + par.m_tab = &tab; + Set set(tab, par.m_totrows); + par.m_set = &set; + LL1("table " << tab.m_name); + CHK(tcase.m_func(par) == 0); + } + } + } + for (unsigned n = 0; n < par.m_threads; n++) { + Thr& thr = *g_thrlist[n]; + thr.exit(); + } + for (unsigned n = 0; n < par.m_threads; n++) { + Thr& thr = *g_thrlist[n]; + thr.join(); + delete &thr; + } + delete [] g_thrlist; + g_thrlist = 0; + con.disconnect(); + LL1("done"); + return 0; +} + +NDB_COMMAND(testOIBasic, "testOIBasic", "testOIBasic", "testOIBasic", 65535) +{ + while (++argv, --argc > 0) { + const char* arg = argv[0]; + if (*arg != '-') { + ndbout << "testOIBasic: unknown argument " << arg; + goto usage; + } + if (strcmp(arg, "-case") == 0) { + if (++argv, --argc > 0) { + g_opt.m_case = strdup(argv[0]); + continue; + } + } + if (strcmp(arg, "-core") == 0) { + g_opt.m_core = true; + continue; + } + if (strcmp(arg, "-dups") == 0) { + g_opt.m_dups = true; + continue; + } + if (strcmp(arg, "-fragtype") == 0) { + if (++argv, --argc > 0) { + if (strcmp(argv[0], "single") == 0) { + g_opt.m_fragtype = NdbDictionary::Object::FragSingle; + continue; + } + if (strcmp(argv[0], "small") == 0) { + g_opt.m_fragtype = NdbDictionary::Object::FragAllSmall; + continue; + } + if (strcmp(argv[0], "medium") == 0) { + g_opt.m_fragtype = NdbDictionary::Object::FragAllMedium; + continue; + } + if (strcmp(argv[0], "large") == 0) { + g_opt.m_fragtype = NdbDictionary::Object::FragAllLarge; + continue; + } + } + } + if (strcmp(arg, "-index") == 0) { + if (++argv, --argc > 0) { + g_opt.m_index = strdup(argv[0]); + continue; + } + } + if (strcmp(arg, "-loop") == 0) { + if (++argv, --argc > 0) { + g_opt.m_loop = atoi(argv[0]); + continue; + } + } + if (strcmp(arg, "-rows") == 0) { + if (++argv, --argc > 0) { + g_opt.m_rows = atoi(argv[0]); + continue; + } + } + if (strcmp(arg, "-scanrd") == 0) { + if (++argv, --argc > 0) { + g_opt.m_scanrd = atoi(argv[0]); + continue; + } + } + if (strcmp(arg, "-scanex") == 0) { + if (++argv, --argc > 0) { + g_opt.m_scanex = atoi(argv[0]); + continue; + } + } + if (strcmp(arg, "-seed") == 0) { + if (++argv, --argc > 0) { + g_opt.m_seed = atoi(argv[0]); + continue; + } + } + if (strcmp(arg, "-subloop") == 0) { + if (++argv, --argc > 0) { + g_opt.m_subloop = atoi(argv[0]); + continue; + } + } + if (strcmp(arg, "-table") == 0) { + if (++argv, --argc > 0) { + g_opt.m_table = strdup(argv[0]); + continue; + } + } + if (strcmp(arg, "-threads") == 0) { + if (++argv, --argc > 0) { + g_opt.m_threads = atoi(argv[0]); + continue; + } + } + if (strcmp(arg, "-v") == 0) { + if (++argv, --argc > 0) { + g_opt.m_v = atoi(argv[0]); + continue; + } + } + if (strncmp(arg, "-v", 2) == 0 && isdigit(arg[2])) { + g_opt.m_v = atoi(&arg[2]); + continue; + } + if (strcmp(arg, "-h") == 0 || strcmp(arg, "-help") == 0) { + printhelp(); + goto wrongargs; + } + ndbout << "testOIBasic: unknown option " << arg; + goto usage; + } + { + Par par(g_opt); + if (runtest(par) < 0) + goto failed; + } + // always exit with NDBT code +ok: + return NDBT_ProgramExit(NDBT_OK); +failed: + return NDBT_ProgramExit(NDBT_FAILED); +usage: + ndbout << " (use -h for help)" << endl; +wrongargs: + return NDBT_ProgramExit(NDBT_WRONGARGS); +} + +// vim: set sw=2 et: diff --git a/ndb/test/ndbapi/testOIBasic/Makefile b/ndb/test/ndbapi/testOIBasic/Makefile deleted file mode 100644 index 1bbbcf1d17e..00000000000 --- a/ndb/test/ndbapi/testOIBasic/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -include .defs.mk - -TYPE = ndbapitest - -BIN_TARGET = testOIBasic - -SOURCES = testOIBasic.cpp - -ifeq ($(NDB_COMPILER),GCC) -CCFLAGS_WARNINGS += -Wno-unused -Wformat -endif - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/testOIBasic/testOIBasic.cpp b/ndb/test/ndbapi/testOIBasic/testOIBasic.cpp deleted file mode 100644 index a47d9d2099e..00000000000 --- a/ndb/test/ndbapi/testOIBasic/testOIBasic.cpp +++ /dev/null @@ -1,2767 +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 */ - -/* - * testOIBasic - ordered index test - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -// options - -struct Opt { - // common options - const char* m_case; - bool m_core; - bool m_dups; - NdbDictionary::Object::FragmentType m_fragtype; - const char* m_index; - unsigned m_loop; - unsigned m_rows; - unsigned m_scanrd; - unsigned m_scanex; - unsigned m_seed; - unsigned m_subloop; - const char* m_table; - unsigned m_threads; - unsigned m_v; - Opt() : - m_case(0), - m_core(false), - m_dups(false), - m_fragtype(NdbDictionary::Object::FragUndefined), - m_index(0), - m_loop(1), - m_rows(1000), - m_scanrd(240), - m_scanex(240), - m_seed(1), - m_subloop(4), - m_table(0), - m_threads(4), - m_v(1) { - } -}; - -static Opt g_opt; - -static void printcases(); -static void printtables(); - -static void -printhelp() -{ - Opt d; - ndbout - << "usage: testOIbasic [options]" << endl - << " -case abc only given test cases (letters a-z)" << endl - << " -core core dump on error [" << d.m_core << "]" << endl - << " -dups allow duplicate tuples from index scan [" << d.m_dups << "]" << endl - << " -fragtype T fragment type single/small/medium/large" << endl - << " -index xyz only given index numbers (digits 1-9)" << endl - << " -loop N loop count full suite forever=0 [" << d.m_loop << "]" << endl - << " -rows N rows per thread [" << d.m_rows << "]" << endl - << " -scanrd N scan read parallelism [" << d.m_scanrd << "]" << endl - << " -scanex N scan exclusive parallelism [" << d.m_scanex << "]" << endl - << " -seed N srandom seed [" << d.m_seed << "]" << endl - << " -subloop N subtest loop count [" << d.m_subloop << "]" << endl - << " -table xyz only given table numbers (digits 1-9)" << endl - << " -threads N number of threads [" << d.m_threads << "]" << endl - << " -vN verbosity [" << d.m_v << "]" << endl - << " -h or -help print this help text" << endl - ; - printcases(); - printtables(); -} - -// log and error macros - -static NdbMutex ndbout_mutex = NDB_MUTEX_INITIALIZER; - -static unsigned getthrno(); - -static const char* -getthrstr() -{ - static char buf[20]; - unsigned n = getthrno(); - if (n == (unsigned)-1) - strcpy(buf, ""); - else { - unsigned m = - g_opt.m_threads < 10 ? 1 : - g_opt.m_threads < 100 ? 2 : 3; - sprintf(buf, "[%0*u] ", m, n); - } - return buf; -} - -#define LLN(n, s) \ - do { \ - if ((n) > g_opt.m_v) break; \ - NdbMutex_Lock(&ndbout_mutex); \ - ndbout << getthrstr() << s << endl; \ - NdbMutex_Unlock(&ndbout_mutex); \ - } while(0) - -#define LL0(s) LLN(0, s) -#define LL1(s) LLN(1, s) -#define LL2(s) LLN(2, s) -#define LL3(s) LLN(3, s) -#define LL4(s) LLN(4, s) -#define LL5(s) LLN(5, s) - -// following check a condition and return -1 on failure - -#undef CHK // simple check -#undef CHKTRY // execute action (try-catch) on failure -#undef CHKMSG // print extra message on failure -#undef CHKCON // print NDB API errors on failure - -#define CHK(x) CHKTRY(x, ;) - -#define CHKTRY(x, act) \ - do { \ - if (x) break; \ - LL0("line " << __LINE__ << ": " << #x << " failed"); \ - if (g_opt.m_core) abort(); \ - act; \ - return -1; \ - } while (0) - -#define CHKMSG(x, msg) \ - do { \ - if (x) break; \ - LL0("line " << __LINE__ << ": " << #x << " failed: " << msg); \ - if (g_opt.m_core) abort(); \ - return -1; \ - } while (0) - -#define CHKCON(x, con) \ - do { \ - if (x) break; \ - LL0("line " << __LINE__ << ": " << #x << " failed"); \ - (con).printerror(ndbout); \ - if (g_opt.m_core) abort(); \ - return -1; \ - } while (0) - -// method parameters base class - -class Thr; -class Con; -class Tab; -class Set; - -struct Par : public Opt { - unsigned m_no; - Con* m_con; - Con& con() const { assert(m_con != 0); return *m_con; } - const Tab* m_tab; - const Tab& tab() const { assert(m_tab != 0); return *m_tab; } - Set* m_set; - Set& set() const { assert(m_set != 0); return *m_set; } - unsigned m_totrows; - unsigned m_batch; - // value calculation - unsigned m_pctnull; - unsigned m_range; - unsigned m_pctrange; - // do verify after read - bool m_verify; - // timer location - Par(const Opt& opt) : - Opt(opt), - m_no(0), - m_con(0), - m_tab(0), - m_set(0), - m_totrows(m_threads * m_rows), - m_batch(32), - m_pctnull(10), - m_range(m_rows), - m_pctrange(0), - m_verify(false) { - } -}; - -static bool -usetable(unsigned i) -{ - return g_opt.m_table == 0 || strchr(g_opt.m_table, '1' + i) != 0; -} - -static bool -useindex(unsigned i) -{ - return g_opt.m_index == 0 || strchr(g_opt.m_index, '1' + i) != 0; -} - -static unsigned -thrrow(Par par, unsigned j) -{ - return par.m_threads * j + par.m_no; -} - -static bool -isthrrow(Par par, unsigned i) -{ - return i % par.m_threads == par.m_no; -} - -// timer - -struct Tmr { - void clr(); - void on(); - void off(unsigned cnt = 0); - const char* time(); - const char* over(const Tmr& t1); - NDB_TICKS m_on; - unsigned m_ms; - unsigned m_cnt; - char m_time[100]; - char m_over[100]; - Tmr() { clr(); } -}; - -void -Tmr::clr() -{ - m_on = m_ms = m_cnt = m_time[0] = m_over[0] = 0; -} - -void -Tmr::on() -{ - assert(m_on == 0); - m_on = NdbTick_CurrentMillisecond(); -} - -void -Tmr::off(unsigned cnt) -{ - NDB_TICKS off = NdbTick_CurrentMillisecond(); - assert(m_on != 0 && off >= m_on); - m_ms += off - m_on; - m_cnt += cnt; - m_on = 0; -} - -const char* -Tmr::time() -{ - if (m_cnt == 0) { - sprintf(m_time, "%u ms", m_ms); - } else { - sprintf(m_time, "%u ms per %u ( %u ms per 1000 )", m_ms, m_cnt, (1000 * m_ms) / m_cnt); - } - return m_time; -} - -const char* -Tmr::over(const Tmr& t1) -{ - if (0 < t1.m_ms && t1.m_ms < m_ms) { - sprintf(m_over, "%u pct", (100 * (m_ms - t1.m_ms)) / t1.m_ms); - } else { - sprintf(m_over, "[cannot measure]"); - } - return m_over; -} - -// tables and indexes - -// Col - table column - -struct Col { - unsigned m_num; - const char* m_name; - bool m_pk; - NdbDictionary::Column::Type m_type; - unsigned m_length; - bool m_nullable; - void verify(const void* addr) const; -}; - -void -Col::verify(const void* addr) const -{ - switch (m_type) { - case NdbDictionary::Column::Unsigned: - break; - case NdbDictionary::Column::Varchar: - { - const unsigned char* p = (const unsigned char*)addr; - unsigned n = (p[0] << 8) | p[1]; - assert(n <= m_length); - for (unsigned i = 0; i < n; i++) { - assert(p[2 + i] != 0); - } - for (unsigned i = n; i < m_length; i++) { - assert(p[2 + i] == 0); - } - } - break; - default: - assert(false); - break; - } -} - -static NdbOut& -operator<<(NdbOut& out, const Col& col) -{ - out << "col " << col.m_num; - out << " " << col.m_name; - switch (col.m_type) { - case NdbDictionary::Column::Unsigned: - out << " unsigned"; - break; - case NdbDictionary::Column::Varchar: - out << " varchar(" << col.m_length << ")"; - break; - default: - out << "type" << (int)col.m_type; - assert(false); - break; - } - out << (col.m_pk ? " pk" : ""); - out << (col.m_nullable ? " nullable" : ""); - return out; -} - -// ICol - index column - -struct ICol { - unsigned m_num; - struct Col m_col; -}; - -// ITab - index - -struct ITab { - const char* m_name; - unsigned m_icols; - const ICol* m_icol; -}; - -static NdbOut& -operator<<(NdbOut& out, const ITab& itab) -{ - out << "itab " << itab.m_name << " " << itab.m_icols; - for (unsigned k = 0; k < itab.m_icols; k++) { - out << endl; - out << "icol " << k << " " << itab.m_icol[k].m_col; - } - return out; -} - -// Tab - table - -struct Tab { - const char* m_name; - unsigned m_cols; - const Col* m_col; - unsigned m_itabs; - const ITab* m_itab; -}; - -static NdbOut& -operator<<(NdbOut& out, const Tab& tab) -{ - out << "tab " << tab.m_name << " " << tab.m_cols; - for (unsigned k = 0; k < tab.m_cols; k++) { - out << endl; - out << tab.m_col[k]; - } - for (unsigned i = 0; i < tab.m_itabs; i++) { - if (! useindex(i)) - continue; - out << endl; - out << tab.m_itab[i]; - } - return out; -} - -// tt1 + tt1x1 tt1x2 tt1x3 tt1x4 - -static const Col -tt1col[] = { - { 0, "A", 1, NdbDictionary::Column::Unsigned, 1, 0 }, - { 1, "B", 0, NdbDictionary::Column::Unsigned, 1, 1 }, - { 2, "C", 0, NdbDictionary::Column::Unsigned, 1, 1 }, - { 3, "D", 0, NdbDictionary::Column::Unsigned, 1, 1 }, - { 4, "E", 0, NdbDictionary::Column::Unsigned, 1, 1 } -}; - -static const ICol -tt1x1col[] = { - { 0, tt1col[1] } -}; - -static const ICol -tt1x2col[] = { - { 0, tt1col[1] }, - { 1, tt1col[2] } -}; - -static const ICol -tt1x3col[] = { - { 0, tt1col[3] }, - { 1, tt1col[2] }, - { 2, tt1col[1] } -}; - -static const ICol -tt1x4col[] = { - { 0, tt1col[1] }, - { 1, tt1col[4] }, - { 2, tt1col[2] }, - { 3, tt1col[3] } -}; - -static const ITab -tt1x1 = { - "TT1X1", 1, tt1x1col -}; - -static const ITab -tt1x2 = { - "TT1X2", 2, tt1x2col -}; - -static const ITab -tt1x3 = { - "TT1X3", 3, tt1x3col -}; - -static const ITab -tt1x4 = { - "TT1X4", 4, tt1x4col -}; - -static const ITab -tt1itab[] = { - tt1x1, - tt1x2, - tt1x3, - tt1x4 -}; - -static const Tab -tt1 = { - "TT1", 5, tt1col, 4, tt1itab -}; - -// tt2 + tt2x1 tt2x2 tt2x3 - -static const Col -tt2col[] = { - { 0, "A", 1, NdbDictionary::Column::Unsigned, 1, 0 }, - { 1, "B", 0, NdbDictionary::Column::Unsigned, 1, 1 }, - { 2, "C", 0, NdbDictionary::Column::Varchar, 20, 1 }, - { 3, "D", 0, NdbDictionary::Column::Varchar, 5, 1 }, - { 4, "E", 0, NdbDictionary::Column::Varchar, 5, 1 } -}; - -static const ICol -tt2x1col[] = { - { 0, tt2col[1] }, - { 1, tt2col[2] } -}; - -static const ICol -tt2x2col[] = { - { 0, tt2col[2] }, - { 1, tt2col[1] } -}; - -static const ICol -tt2x3col[] = { - { 0, tt2col[3] }, - { 1, tt2col[4] } -}; - -static const ITab -tt2x1 = { - "TT2X1", 2, tt2x1col -}; - -static const ITab -tt2x2 = { - "TT2X2", 2, tt2x2col -}; - -static const ITab -tt2x3 = { - "TT2X3", 2, tt2x3col -}; - -static const ITab -tt2itab[] = { - tt2x1, - tt2x2, - tt2x3 -}; - -static const Tab -tt2 = { - "TT2", 5, tt2col, 3, tt2itab -}; - -// all tables - -static const Tab -tablist[] = { - tt1, - tt2 -}; - -static const unsigned -tabcount = sizeof(tablist) / sizeof(tablist[0]); - -// connections - -struct Con { - Ndb* m_ndb; - NdbDictionary::Dictionary* m_dic; - NdbConnection* m_tx; - NdbOperation* m_op; - NdbConnection* m_scantx; - NdbOperation* m_scanop; - enum ScanMode { ScanNo = 0, Committed, Latest, Exclusive }; - ScanMode m_scanmode; - enum ErrType { ErrNone = 0, ErrDeadlock, ErrOther }; - ErrType m_errtype; - Con() : - m_ndb(0), m_dic(0), m_tx(0), m_op(0), - m_scantx(0), m_scanop(0), m_scanmode(ScanNo), m_errtype(ErrNone) {} - int connect(); - void disconnect(); - int startTransaction(); - int startBuddyTransaction(const Con& con); - int getNdbOperation(const Tab& tab); - int getNdbOperation(const ITab& itab, const Tab& tab); - int equal(int num, const char* addr); - int getValue(int num, NdbRecAttr*& rec); - int setValue(int num, const char* addr); - int setBound(int num, int type, const void* value); - int execute(ExecType t); - int openScanRead(unsigned parallelism); - int openScanExclusive(unsigned parallelism); - int executeScan(); - int nextScanResult(); - int takeOverForUpdate(Con& scan); - int takeOverForDelete(Con& scan); - void closeTransaction(); - void printerror(NdbOut& out); - // flush dict cache - int bugger() { - //disconnect(); - //CHK(connect() == 0); - return 0; - } -}; - -int -Con::connect() -{ - assert(m_ndb == 0); - m_ndb = new Ndb("TEST_DB"); - CHKCON(m_ndb->init() == 0, *this); - CHKCON(m_ndb->waitUntilReady(30) == 0, *this); - m_dic = m_ndb->getDictionary(); - m_tx = 0, m_op = 0; - return 0; -} - -void -Con::disconnect() -{ - delete m_ndb; - m_ndb = 0, m_dic = 0, m_tx = 0, m_op = 0; -} - -int -Con::startTransaction() -{ - assert(m_ndb != 0 && m_tx == 0); - CHKCON((m_tx = m_ndb->startTransaction()) != 0, *this); - return 0; -} - -int -Con::startBuddyTransaction(const Con& con) -{ - assert(m_ndb != 0 && m_tx == 0 && con.m_ndb == m_ndb && con.m_tx != 0); - CHKCON((m_tx = m_ndb->hupp(con.m_tx)) != 0, *this); - return 0; -} - -int -Con::getNdbOperation(const Tab& tab) -{ - assert(m_tx != 0); - CHKCON((m_op = m_tx->getNdbOperation(tab.m_name)) != 0, *this); - return 0; -} - -int -Con::getNdbOperation(const ITab& itab, const Tab& tab) -{ - CHKCON((m_op = m_tx->getNdbOperation(itab.m_name, tab.m_name)) != 0, *this); - return 0; -} - -int -Con::equal(int num, const char* addr) -{ - assert(m_tx != 0 && m_op != 0); - CHKCON(m_op->equal(num, addr) == 0, *this); - return 0; -} - -int -Con::getValue(int num, NdbRecAttr*& rec) -{ - assert(m_tx != 0 && m_op != 0); - CHKCON((rec = m_op->getValue(num, 0)) != 0, *this); - return 0; -} - -int -Con::setValue(int num, const char* addr) -{ - assert(m_tx != 0 && m_op != 0); - CHKCON(m_op->setValue(num, addr) == 0, *this); - return 0; -} - -int -Con::setBound(int num, int type, const void* value) -{ - assert(m_tx != 0 && m_op != 0); - CHKCON(m_op->setBound(num, type, value) == 0, *this); - return 0; -} - -int -Con::execute(ExecType t) -{ - assert(m_tx != 0); - CHKCON(m_tx->execute(t) == 0, *this); - return 0; -} - -int -Con::openScanRead(unsigned parallelism) -{ - assert(m_tx != 0 && m_op != 0); - CHKCON(m_op->openScanRead(parallelism) == 0, *this); - return 0; -} - -int -Con::openScanExclusive(unsigned parallelism) -{ - assert(m_tx != 0 && m_op != 0); - CHKCON(m_op->openScanExclusive(parallelism) == 0, *this); - return 0; -} - -int -Con::executeScan() -{ - CHKCON(m_tx->executeScan() == 0, *this); - return 0; -} - -int -Con::nextScanResult() -{ - int ret; - CHKCON((ret = m_tx->nextScanResult()) != -1, *this); - assert(ret == 0 || ret == 1); - return ret; -} - -int -Con::takeOverForUpdate(Con& scan) -{ - assert(m_tx != 0 && scan.m_op != 0); - CHKCON((m_op = scan.m_op->takeOverForUpdate(m_tx)) != 0, scan); - return 0; -} - -int -Con::takeOverForDelete(Con& scan) -{ - assert(m_tx != 0 && scan.m_op != 0); - CHKCON((m_op = scan.m_op->takeOverForUpdate(m_tx)) != 0, scan); - return 0; -} - -void -Con::closeTransaction() -{ - assert(m_ndb != 0 && m_tx != 0); - m_ndb->closeTransaction(m_tx); - m_tx = 0, m_op = 0; -} - -void -Con::printerror(NdbOut& out) -{ - m_errtype = ErrOther; - unsigned any = 0; - int code; - if (m_ndb) { - if ((code = m_ndb->getNdbError().code) != 0) { - LL0(++any << " ndb: error " << m_ndb->getNdbError()); - } - if (m_dic && (code = m_dic->getNdbError().code) != 0) { - LL0(++any << " dic: error " << m_dic->getNdbError()); - } - if (m_tx) { - if ((code = m_tx->getNdbError().code) != 0) { - LL0(++any << " con: error " << m_tx->getNdbError()); - if (code == 266 || code == 274 || code == 296 || code == 297) - m_errtype = ErrDeadlock; - } - if (m_op && m_op->getNdbError().code != 0) { - LL0(++any << " op : error " << m_op->getNdbError()); - } - } - } - if (! any) { - LL0("failed but no NDB error code"); - } -} - -// dictionary operations - -static int -invalidateindex(Par par, const ITab& itab) -{ - Con& con = par.con(); - const Tab& tab = par.tab(); - con.m_dic->invalidateIndex(itab.m_name, tab.m_name); - return 0; -} - -static int -invalidateindex(Par par) -{ - Con& con = par.con(); - const Tab& tab = par.tab(); - for (unsigned i = 0; i < tab.m_itabs; i++) { - if (! useindex(i)) - continue; - const ITab& itab = tab.m_itab[i]; - invalidateindex(par, itab); - } - return 0; -} - -static int -invalidatetable(Par par) -{ - Con& con = par.con(); - const Tab& tab = par.tab(); - invalidateindex(par); - con.m_dic->invalidateTable(tab.m_name); - return 0; -} - -static int -droptable(Par par) -{ - Con& con = par.con(); - const Tab& tab = par.tab(); - if (con.m_dic->getTable(tab.m_name) == 0) { - // how to check for error - LL4("no table " << tab.m_name); - } else { - LL3("drop table " << tab.m_name); - CHKCON(con.m_dic->dropTable(tab.m_name) == 0, con); - } - return 0; -} - -static int -createtable(Par par) -{ - Con& con = par.con(); - CHK(con.bugger() == 0); - const Tab& tab = par.tab(); - LL3("create table " << tab.m_name); - LL4(tab); - NdbDictionary::Table t(tab.m_name); - if (par.m_fragtype != NdbDictionary::Object::FragUndefined) { - t.setFragmentType(par.m_fragtype); - } - for (unsigned k = 0; k < tab.m_cols; k++) { - const Col& col = tab.m_col[k]; - NdbDictionary::Column c(col.m_name); - c.setPrimaryKey(col.m_pk); - c.setType(col.m_type); - c.setLength(col.m_length); - c.setNullable(col.m_nullable); - t.addColumn(c); - } - CHKCON(con.m_dic->createTable(t) == 0, con); - return 0; -} - -static int -dropindex(Par par, const ITab& itab) -{ - Con& con = par.con(); - const Tab& tab = par.tab(); - if (con.m_dic->getIndex(itab.m_name, tab.m_name) == 0) { - // how to check for error - LL4("no index " << itab.m_name); - } else { - LL3("drop index " << itab.m_name); - CHKCON(con.m_dic->dropIndex(itab.m_name, tab.m_name) == 0, con); - } - return 0; -} - -static int -dropindex(Par par) -{ - const Tab& tab = par.tab(); - for (unsigned i = 0; i < tab.m_itabs; i++) { - if (! useindex(i)) - continue; - const ITab& itab = tab.m_itab[i]; - CHK(dropindex(par, itab) == 0); - } - return 0; -} - -static int -createindex(Par par, const ITab& itab) -{ - Con& con = par.con(); - CHK(con.bugger() == 0); - const Tab& tab = par.tab(); - LL3("create index " << itab.m_name); - LL4(itab); - NdbDictionary::Index x(itab.m_name); - x.setTable(tab.m_name); - x.setType(NdbDictionary::Index::OrderedIndex); - x.setLogging(false); - for (unsigned k = 0; k < itab.m_icols; k++) { - const Col& col = itab.m_icol[k].m_col; - x.addColumnName(col.m_name); - } - CHKCON(con.m_dic->createIndex(x) == 0, con); - return 0; -} - -static int -createindex(Par par) -{ - const Tab& tab = par.tab(); - for (unsigned i = 0; i < tab.m_itabs; i++) { - if (! useindex(i)) - continue; - const ITab& itab = tab.m_itab[i]; - CHK(createindex(par, itab) == 0); - } - return 0; -} - -// data sets - -static unsigned -urandom(unsigned n) -{ - if (n == 0) - return 0; - unsigned i = random() % n; - return i; -} - -static int -irandom(unsigned n) -{ - if (n == 0) - return 0; - int i = random() % n; - if (random() & 0x1) - i = -i; - return i; -} - -// Val - typed column value - -struct Val { - const Col& m_col; - union { - Uint32 m_uint32; - char* m_varchar; - }; - Val(const Col& col); - ~Val(); - void copy(const Val& val2); - void copy(const void* addr); - const void* dataaddr() const; - bool m_null; - int setval(Par par) const; - void calc(Par par, unsigned i); - int verify(const Val& val2) const; - int cmp(const Val& val2) const; -private: - Val& operator=(const Val& val2); -}; - -static NdbOut& -operator<<(NdbOut& out, const Val& val); - -Val::Val(const Col& col) : - m_col(col) -{ - switch (col.m_type) { - case NdbDictionary::Column::Unsigned: - break; - case NdbDictionary::Column::Varchar: - m_varchar = new char [2 + col.m_length]; - break; - default: - assert(false); - break; - } -} - -Val::~Val() -{ - const Col& col = m_col; - switch (col.m_type) { - case NdbDictionary::Column::Unsigned: - break; - case NdbDictionary::Column::Varchar: - delete [] m_varchar; - break; - default: - assert(false); - break; - } -} - -void -Val::copy(const Val& val2) -{ - const Col& col = m_col; - const Col& col2 = val2.m_col; - assert(col.m_type == col2.m_type && col.m_length == col2.m_length); - if (val2.m_null) { - m_null = true; - return; - } - copy(val2.dataaddr()); -} - -void -Val::copy(const void* addr) -{ - const Col& col = m_col; - switch (col.m_type) { - case NdbDictionary::Column::Unsigned: - m_uint32 = *(const Uint32*)addr; - break; - case NdbDictionary::Column::Varchar: - memcpy(m_varchar, addr, 2 + col.m_length); - break; - default: - assert(false); - break; - } - m_null = false; -} - -const void* -Val::dataaddr() const -{ - const Col& col = m_col; - switch (col.m_type) { - case NdbDictionary::Column::Unsigned: - return &m_uint32; - case NdbDictionary::Column::Varchar: - return m_varchar; - default: - break; - } - assert(false); - return 0; -} - -int -Val::setval(Par par) const -{ - Con& con = par.con(); - const Col& col = m_col; - const char* addr = (const char*)dataaddr(); - if (m_null) - addr = 0; - if (col.m_pk) - CHK(con.equal(col.m_num, addr) == 0); - else - CHK(con.setValue(col.m_num, addr) == 0); - LL5("setval [" << m_col << "] " << *this); - return 0; -} - -void -Val::calc(Par par, unsigned i) -{ - const Col& col = m_col; - m_null = false; - if (col.m_pk) { - m_uint32 = i; - return; - } - if (col.m_nullable && urandom(100) < par.m_pctnull) { - m_null = true; - return; - } - unsigned v = par.m_range + irandom((par.m_pctrange * par.m_range) / 100); - switch (col.m_type) { - case NdbDictionary::Column::Unsigned: - m_uint32 = v; - break; - case NdbDictionary::Column::Varchar: - { - unsigned n = 0; - while (n < col.m_length) { - if (urandom(1 + col.m_length) == 0) { - // nice distribution on lengths - break; - } - m_varchar[2 + n++] = 'a' + urandom((par.m_pctrange * 10) / 100); - } - m_varchar[0] = (n >> 8); - m_varchar[1] = (n & 0xff); - while (n < col.m_length) { - m_varchar[2 + n++] = 0; - } - } - break; - default: - assert(false); - break; - } - // verify format - col.verify(dataaddr()); -} - -int -Val::verify(const Val& val2) const -{ - CHK(cmp(val2) == 0); - return 0; -} - -int -Val::cmp(const Val& val2) const -{ - const Col& col = m_col; - const Col& col2 = val2.m_col; - assert(col.m_type == col2.m_type && col.m_length == col2.m_length); - if (m_null || val2.m_null) { - if (! m_null) - return -1; - if (! val2.m_null) - return +1; - return 0; - } - // verify data formats - col.verify(dataaddr()); - col.verify(val2.dataaddr()); - // compare - switch (col.m_type) { - case NdbDictionary::Column::Unsigned: - if (m_uint32 < val2.m_uint32) - return -1; - if (m_uint32 > val2.m_uint32) - return +1; - return 0; - case NdbDictionary::Column::Varchar: - return memcmp(&m_varchar[2], &val2.m_varchar[2], col.m_length); - default: - break; - } - assert(false); - return 0; -} - -static NdbOut& -operator<<(NdbOut& out, const Val& val) -{ - const Col& col = val.m_col; - if (val.m_null) { - out << "NULL"; - return out; - } - switch (col.m_type) { - case NdbDictionary::Column::Unsigned: - out << val.m_uint32; - break; - case NdbDictionary::Column::Varchar: - { - char buf[8000]; - unsigned n = (val.m_varchar[0] << 8) | val.m_varchar[1]; - assert(n <= col.m_length); - sprintf(buf, "'%.*s'[%d]", n, &val.m_varchar[2], n); - out << buf; - } - break; - default: - out << "type" << col.m_type; - assert(false); - break; - } - return out; -} - -// Row - table tuple - -struct Row { - const Tab& m_tab; - Val** m_val; - bool m_exist; - Row(const Tab& tab); - ~Row(); - void copy(const Row& row2); - void calc(Par par, unsigned i); - int verify(const Row& row2) const; - int insrow(Par par); - int updrow(Par par); - int delrow(Par par); - int selrow(Par par); - int setrow(Par par); - int cmp(const Row& row2) const; -private: - Row& operator=(const Row& row2); -}; - -Row::Row(const Tab& tab) : - m_tab(tab) -{ - m_val = new Val* [tab.m_cols]; - for (unsigned k = 0; k < tab.m_cols; k++) { - const Col& col = tab.m_col[k]; - m_val[k] = new Val(col); - } - m_exist = false; -} - -Row::~Row() -{ - const Tab& tab = m_tab; - for (unsigned k = 0; k < tab.m_cols; k++) { - delete m_val[k]; - } - delete [] m_val; -} - -void -Row::copy(const Row& row2) -{ - const Tab& tab = m_tab; - assert(&tab == &row2.m_tab); - for (unsigned k = 0; k < tab.m_cols; k++) { - Val& val = *m_val[k]; - const Val& val2 = *row2.m_val[k]; - val.copy(val2); - } -} - -void -Row::calc(Par par, unsigned i) -{ - const Tab& tab = m_tab; - for (unsigned k = 0; k < tab.m_cols; k++) { - Val& val = *m_val[k]; - val.calc(par, i); - } -} - -int -Row::verify(const Row& row2) const -{ - const Tab& tab = m_tab; - assert(&tab == &row2.m_tab); - for (unsigned k = 0; k < tab.m_cols; k++) { - const Val& val = *m_val[k]; - const Val& val2 = *row2.m_val[k]; - CHK(val.verify(val2) == 0); - } - return 0; -} - -int -Row::insrow(Par par) -{ - Con& con = par.con(); - const Tab& tab = m_tab; - assert(! m_exist); - CHK(con.getNdbOperation(tab) == 0); - CHKCON(con.m_op->insertTuple() == 0, con); - for (unsigned k = 0; k < tab.m_cols; k++) { - const Val& val = *m_val[k]; - CHK(val.setval(par) == 0); - } - m_exist = true; - return 0; -} - -int -Row::updrow(Par par) -{ - Con& con = par.con(); - const Tab& tab = m_tab; - assert(m_exist); - CHK(con.getNdbOperation(tab) == 0); - CHKCON(con.m_op->updateTuple() == 0, con); - for (unsigned k = 0; k < tab.m_cols; k++) { - const Val& val = *m_val[k]; - CHK(val.setval(par) == 0); - } - return 0; -} - -int -Row::delrow(Par par) -{ - Con& con = par.con(); - const Tab& tab = m_tab; - assert(m_exist); - CHK(con.getNdbOperation(m_tab) == 0); - CHKCON(con.m_op->deleteTuple() == 0, con); - for (unsigned k = 0; k < tab.m_cols; k++) { - const Val& val = *m_val[k]; - const Col& col = val.m_col; - if (col.m_pk) - CHK(val.setval(par) == 0); - } - m_exist = false; - return 0; -} - -int -Row::selrow(Par par) -{ - Con& con = par.con(); - const Tab& tab = m_tab; - CHK(con.getNdbOperation(m_tab) == 0); - CHKCON(con.m_op->readTuple() == 0, con); - for (unsigned k = 0; k < tab.m_cols; k++) { - const Val& val = *m_val[k]; - const Col& col = val.m_col; - if (col.m_pk) - CHK(val.setval(par) == 0); - } - m_exist = false; - return 0; -} - -int -Row::setrow(Par par) -{ - Con& con = par.con(); - const Tab& tab = m_tab; - for (unsigned k = 0; k < tab.m_cols; k++) { - const Val& val = *m_val[k]; - const Col& col = val.m_col; - if (! col.m_pk) - CHK(val.setval(par) == 0); - } - return 0; -} - -int -Row::cmp(const Row& row2) const -{ - const Tab& tab = m_tab; - assert(&tab == &row2.m_tab); - int c = 0; - for (unsigned k = 0; k < tab.m_cols; k++) { - const Val& val = *m_val[k]; - const Val& val2 = *row2.m_val[k]; - if ((c = val.cmp(val2)) != 0) - break; - } - return c; -} - -static NdbOut& -operator<<(NdbOut& out, const Row& row) -{ - const Tab& tab = row.m_tab; - for (unsigned i = 0; i < tab.m_cols; i++) { - if (i > 0) - out << " "; - out << *row.m_val[i]; - } - return out; -} - -// Set - set of table tuples - -struct Set { - const Tab& m_tab; - unsigned m_rows; - unsigned m_count; - Row** m_row; - Row** m_saverow; - Row* m_keyrow; - NdbRecAttr** m_rec; - Set(const Tab& tab, unsigned rows); - ~Set(); - // row methods - bool exist(unsigned i) const; - void calc(Par par, unsigned i); - int insrow(Par par, unsigned i); - int updrow(Par par, unsigned i); - int delrow(Par par, unsigned i); - int selrow(Par par, unsigned i); - int setrow(Par par, unsigned i); - int getval(Par par); - int getkey(Par par, unsigned* i); - int putval(unsigned i, bool force); - // set methods - int verify(const Set& set2) const; - void savepoint(); - void commit(); - void rollback(); - // locking (not perfect since ops may complete in different order) - NdbMutex* m_mutex; - void lock() { - NdbMutex_Lock(m_mutex); - } - void unlock() { - NdbMutex_Unlock(m_mutex); - } -private: - Set& operator=(const Set& set2); -}; - -Set::Set(const Tab& tab, unsigned rows) : - m_tab(tab) -{ - m_rows = rows; - m_count = 0; - m_row = new Row* [m_rows]; - for (unsigned i = 0; i < m_rows; i++) { - m_row[i] = 0; - } - m_saverow = 0; - m_keyrow = new Row(tab); - m_rec = new NdbRecAttr* [tab.m_cols]; - for (unsigned k = 0; k < tab.m_cols; k++) { - m_rec[k] = 0; - } - m_mutex = NdbMutex_Create(); - assert(m_mutex != 0); -} - -Set::~Set() -{ - for (unsigned i = 0; i < m_rows; i++) { - delete m_row[i]; - if (m_saverow != 0) - delete m_saverow[i]; - } - delete [] m_row; - delete [] m_saverow; - delete m_keyrow; - delete [] m_rec; - NdbMutex_Destroy(m_mutex); -} - -bool -Set::exist(unsigned i) const -{ - assert(i < m_rows); - return m_row[i] != 0 && m_row[i]->m_exist; -} - -void -Set::calc(Par par, unsigned i) -{ - const Tab& tab = m_tab; - if (m_row[i] == 0) - m_row[i] = new Row(tab); - Row& row = *m_row[i]; - // value generation parameters - par.m_pctnull = 10; - par.m_pctrange = 40; - row.calc(par, i); -} - -int -Set::insrow(Par par, unsigned i) -{ - assert(m_row[i] != 0 && m_count < m_rows); - CHK(m_row[i]->insrow(par) == 0); - m_count++; - return 0; -} - -int -Set::updrow(Par par, unsigned i) -{ - assert(m_row[i] != 0); - CHK(m_row[i]->updrow(par) == 0); - return 0; -} - -int -Set::delrow(Par par, unsigned i) -{ - assert(m_row[i] != 0 && m_count != 0); - CHK(m_row[i]->delrow(par) == 0); - m_count--; - return 0; -} - -int -Set::selrow(Par par, unsigned i) -{ - Con& con = par.con(); - m_keyrow->calc(par, i); - CHK(m_keyrow->selrow(par) == 0); - CHK(getval(par) == 0); - return 0; -} - -int -Set::setrow(Par par, unsigned i) -{ - Con& con = par.con(); - assert(m_row[i] != 0); - CHK(m_row[i]->setrow(par) == 0); - return 0; -} - -int -Set::getval(Par par) -{ - Con& con = par.con(); - const Tab& tab = m_tab; - for (unsigned k = 0; k < tab.m_cols; k++) { - CHK(con.getValue(k, m_rec[k]) == 0); - } - return 0; -} - -int -Set::getkey(Par par, unsigned* i) -{ - assert(m_rec[0] != 0); - const char* aRef0 = m_rec[0]->aRef(); - Uint32 key = *(const Uint32*)aRef0; - CHKMSG(key < m_rows, "key=" << key << " rows=" << m_rows); - *i = key; - return 0; -} - -int -Set::putval(unsigned i, bool force) -{ - const Tab& tab = m_tab; - if (m_row[i] == 0) - m_row[i] = new Row(tab); - Row& row = *m_row[i]; - CHK(! row.m_exist || force); - for (unsigned k = 0; k < tab.m_cols; k++) { - Val& val = *row.m_val[k]; - NdbRecAttr* rec = m_rec[k]; - assert(rec != 0); - if (rec->isNULL()) { - val.m_null = true; - continue; - } - const char* aRef = m_rec[k]->aRef(); - val.copy(aRef); - val.m_null = false; - } - if (! row.m_exist) { - row.m_exist = true; - m_count++; - } - return 0; -} - -int -Set::verify(const Set& set2) const -{ - const Tab& tab = m_tab; - assert(&tab == &set2.m_tab && m_rows == set2.m_rows); - CHKMSG(m_count == set2.m_count, "set=" << m_count << " set2=" << set2.m_count); - for (unsigned i = 0; i < m_rows; i++) { - CHK(exist(i) == set2.exist(i)); - if (! exist(i)) - continue; - Row& row = *m_row[i]; - Row& row2 = *set2.m_row[i]; - CHK(row.verify(row2) == 0); - } - return 0; -} - -void -Set::savepoint() -{ - const Tab& tab = m_tab; - assert(m_saverow == 0); - m_saverow = new Row* [m_rows]; - for (unsigned i = 0; i < m_rows; i++) { - if (m_row[i] == 0) - m_saverow[i] = 0; - else { - m_saverow[i] = new Row(tab); - m_saverow[i]->copy(*m_row[i]); - } - } -} - -void -Set::commit() -{ - delete [] m_saverow; - m_saverow = 0; -} - -void -Set::rollback() -{ - assert(m_saverow != 0); - m_row = m_saverow; - m_saverow = 0; -} - -static NdbOut& -operator<<(NdbOut& out, const Set& set) -{ - for (unsigned i = 0; i < set.m_rows; i++) { - const Row& row = *set.m_row[i]; - if (i > 0) - out << endl; - out << row; - } - return out; -} - -// BVal - range scan bound - -struct BVal : public Val { - const ICol& m_icol; - int m_type; - BVal(const ICol& icol); - int setbnd(Par par) const; -}; - -BVal::BVal(const ICol& icol) : - Val(icol.m_col), - m_icol(icol) -{ -} - -int -BVal::setbnd(Par par) const -{ - Con& con = par.con(); - const char* addr = (const char*)dataaddr(); - assert(! m_null); - const ICol& icol = m_icol; - CHK(con.setBound(icol.m_num, m_type, addr) == 0); - return 0; -} - -static NdbOut& -operator<<(NdbOut& out, const BVal& bval) -{ - const ICol& icol = bval.m_icol; - const Col& col = icol.m_col; - const Val& val = bval; - out << "type " << bval.m_type; - out << " icol " << icol.m_num; - out << " col " << col.m_name << "(" << col.m_num << ")"; - out << " value " << val; - return out; -} - -// BSet - set of bounds - -struct BSet { - const Tab& m_tab; - const ITab& m_itab; - unsigned m_alloc; - unsigned m_bvals; - BVal** m_bval; - BSet(const Tab& tab, const ITab& itab, unsigned rows); - void calc(Par par); - int setbnd(Par par) const; - void filter(const Set& set, Set& set2) const; -}; - -BSet::BSet(const Tab& tab, const ITab& itab, unsigned rows) : - m_tab(tab), - m_itab(itab), - m_alloc(2 * itab.m_icols), - m_bvals(0) -{ - m_bval = new BVal* [m_alloc]; -} - -void -BSet::calc(Par par) -{ - const ITab& itab = m_itab; - for (unsigned k = 0; k < itab.m_icols; k++) { - const ICol& icol = itab.m_icol[k]; - const Col& col = icol.m_col; - for (unsigned i = 0; i <= 1; i++) { - if (urandom(10) == 0) - return; - assert(m_bvals < m_alloc); - BVal& bval = *new BVal(icol); - m_bval[m_bvals++] = &bval; - bval.m_null = false; - // equality bound only on i==0 - unsigned sel = urandom(5 - i); - if (sel < 2) - bval.m_type = 0 | (1 << i); - else if (sel < 4) - bval.m_type = 1 | (1 << i); - else - bval.m_type = 4; - if (k + 1 < itab.m_icols) - bval.m_type = 4; - // value generation parammeters - par.m_pctnull = 0; - par.m_pctrange = 50; // bit higher - do { - bval.calc(par, 0); - if (i == 1) { - assert(m_bvals >= 2); - const BVal& bv1 = *m_bval[m_bvals - 2]; - const BVal& bv2 = *m_bval[m_bvals - 1]; - if (bv1.cmp(bv2) > 0 && urandom(100) != 0) - continue; - } - } while (0); - // equality bound only once - if (bval.m_type == 4) - break; - } - } -} - -int -BSet::setbnd(Par par) const -{ - for (unsigned j = 0; j < m_bvals; j++) { - const BVal& bval = *m_bval[j]; - CHK(bval.setbnd(par) == 0); - } - return 0; -} - -void -BSet::filter(const Set& set, Set& set2) const -{ - const Tab& tab = m_tab; - const ITab& itab = m_itab; - assert(&tab == &set2.m_tab && set.m_rows == set2.m_rows); - assert(set2.m_count == 0); - for (unsigned i = 0; i < set.m_rows; i++) { - if (! set.exist(i)) - continue; - const Row& row = *set.m_row[i]; - bool ok1 = false; - for (unsigned k = 0; k < itab.m_icols; k++) { - const ICol& icol = itab.m_icol[k]; - const Col& col = icol.m_col; - const Val& val = *row.m_val[col.m_num]; - if (! val.m_null) { - ok1 = true; - break; - } - } - if (! ok1) - continue; - bool ok2 = true; - for (unsigned j = 0; j < m_bvals; j++) { - const BVal& bval = *m_bval[j]; - const ICol& icol = bval.m_icol; - const Col& col = icol.m_col; - const Val& val = *row.m_val[col.m_num]; - int ret = bval.cmp(val); - if (bval.m_type == 0) - ok2 = (ret <= 0); - else if (bval.m_type == 1) - ok2 = (ret < 0); - else if (bval.m_type == 2) - ok2 = (ret >= 0); - else if (bval.m_type == 3) - ok2 = (ret > 0); - else if (bval.m_type == 4) - ok2 = (ret == 0); - else { - assert(false); - } - if (! ok2) - break; - } - if (! ok2) - continue; - if (set2.m_row[i] == 0) - set2.m_row[i] = new Row(tab); - Row& row2 = *set2.m_row[i]; - assert(! row2.m_exist); - row2.copy(row); - row2.m_exist = true; - set2.m_count++; - } -} - -static NdbOut& -operator<<(NdbOut& out, const BSet& bset) -{ - out << "bounds=" << bset.m_bvals; - for (unsigned j = 0; j < bset.m_bvals; j++) { - out << endl; - const BVal& bval = *bset.m_bval[j]; - out << "bound " << j << ": " << bval; - } - return out; -} - -// pk operations - -static int -pkinsert(Par par) -{ - Con& con = par.con(); - Set& set = par.set(); - LL3("pkinsert"); - CHK(con.startTransaction() == 0); - unsigned n = 0; - for (unsigned j = 0; j < par.m_rows; j++) { - unsigned i = thrrow(par, j); - set.lock(); - if (set.exist(i)) { - set.unlock(); - continue; - } - set.calc(par, i); - LL4("pkinsert " << i << ": " << *set.m_row[i]); - CHKTRY(set.insrow(par, i) == 0, set.unlock()); - set.unlock(); - if (++n == par.m_batch) { - CHK(con.execute(Commit) == 0); - con.closeTransaction(); - CHK(con.startTransaction() == 0); - n = 0; - } - } - if (n != 0) { - CHK(con.execute(Commit) == 0); - n = 0; - } - con.closeTransaction(); - return 0; -}; - -static int -pkupdate(Par par) -{ - Con& con = par.con(); - Set& set = par.set(); - LL3("pkupdate"); - CHK(con.startTransaction() == 0); - unsigned n = 0; - for (unsigned j = 0; j < par.m_rows; j++) { - unsigned i = thrrow(par, j); - set.lock(); - if (! set.exist(i)) { - set.unlock(); - continue; - } - set.calc(par, i); - LL4("pkupdate " << i << ": " << *set.m_row[i]); - CHKTRY(set.updrow(par, i) == 0, set.unlock()); - set.unlock(); - if (++n == par.m_batch) { - CHK(con.execute(Commit) == 0); - con.closeTransaction(); - CHK(con.startTransaction() == 0); - n = 0; - } - } - if (n != 0) { - CHK(con.execute(Commit) == 0); - n = 0; - } - con.closeTransaction(); - return 0; -}; - -static int -pkdelete(Par par) -{ - Con& con = par.con(); - Set& set = par.set(); - LL3("pkdelete"); - CHK(con.startTransaction() == 0); - unsigned n = 0; - for (unsigned j = 0; j < par.m_rows; j++) { - unsigned i = thrrow(par, j); - set.lock(); - if (! set.exist(i)) { - set.unlock(); - continue; - } - LL4("pkdelete " << i << ": " << *set.m_row[i]); - CHKTRY(set.delrow(par, i) == 0, set.unlock()); - set.unlock(); - if (++n == par.m_batch) { - CHK(con.execute(Commit) == 0); - con.closeTransaction(); - CHK(con.startTransaction() == 0); - n = 0; - } - } - if (n != 0) { - CHK(con.execute(Commit) == 0); - n = 0; - } - con.closeTransaction(); - return 0; -}; - -static int -pkread(Par par) -{ - Con& con = par.con(); - const Tab& tab = par.tab(); - const Set& set = par.set(); - LL3((par.m_verify ? "pkverify " : "pkread ") << tab.m_name); - // expected - const Set& set1 = set; - Set set2(tab, set.m_rows); - for (unsigned i = 0; i < set.m_rows; i++) { - if (! set.exist(i)) - continue; - CHK(con.startTransaction() == 0); - CHK(set2.selrow(par, i) == 0); - CHK(con.execute(Commit) == 0); - unsigned i2 = (unsigned)-1; - CHK(set2.getkey(par, &i2) == 0 && i == i2); - CHK(set2.putval(i, false) == 0); - LL4("row " << set2.m_count << ": " << *set2.m_row[i]); - con.closeTransaction(); - } - if (par.m_verify) - CHK(set1.verify(set2) == 0); - return 0; -} - -// scan read - -static int -scanreadtable(Par par) -{ - Con& con = par.con(); - const Tab& tab = par.tab(); - const Set& set = par.set(); - // expected - const Set& set1 = set; - LL3((par.m_verify ? "scanverify " : "scanread ") << tab.m_name); - Set set2(tab, set.m_rows); - CHK(con.startTransaction() == 0); - CHK(con.getNdbOperation(tab) == 0); - CHK(con.openScanRead(par.m_scanrd) == 0); - set2.getval(par); - CHK(con.executeScan() == 0); - while (1) { - int ret; - CHK((ret = con.nextScanResult()) == 0 || ret == 1); - if (ret == 1) - break; - unsigned i = (unsigned)-1; - CHK(set2.getkey(par, &i) == 0); - CHK(set2.putval(i, false) == 0); - LL4("row " << set2.m_count << ": " << *set2.m_row[i]); - } - con.closeTransaction(); - if (par.m_verify) - CHK(set1.verify(set2) == 0); - return 0; -} - -static int -scanreadindex(Par par, const ITab& itab, const BSet& bset) -{ - Con& con = par.con(); - const Tab& tab = par.tab(); - const Set& set = par.set(); - // expected - Set set1(tab, set.m_rows); - bset.filter(set, set1); - LL3((par.m_verify ? "scanverify " : "scanread ") << itab.m_name << " bounds=" << bset.m_bvals); - LL4(bset); - Set set2(tab, set.m_rows); - CHK(con.startTransaction() == 0); - CHK(con.getNdbOperation(itab, tab) == 0); - CHK(con.openScanRead(par.m_scanrd) == 0); - CHK(bset.setbnd(par) == 0); - set2.getval(par); - CHK(con.executeScan() == 0); - while (1) { - int ret; - CHK((ret = con.nextScanResult()) == 0 || ret == 1); - if (ret == 1) - break; - unsigned i = (unsigned)-1; - CHK(set2.getkey(par, &i) == 0); - LL4("key " << i); - CHK(set2.putval(i, par.m_dups) == 0); - LL4("row " << set2.m_count << ": " << *set2.m_row[i]); - } - con.closeTransaction(); - if (par.m_verify) - CHK(set1.verify(set2) == 0); - return 0; -} - -static int -scanreadindex(Par par, const ITab& itab) -{ - const Tab& tab = par.tab(); - for (unsigned i = 0; i < par.m_subloop; i++) { - BSet bset(tab, itab, par.m_rows); - bset.calc(par); - CHK(scanreadindex(par, itab, bset) == 0); - } - return 0; -} - -static int -scanreadindex(Par par) -{ - const Tab& tab = par.tab(); - for (unsigned i = 0; i < tab.m_itabs; i++) { - if (! useindex(i)) - continue; - const ITab& itab = tab.m_itab[i]; - CHK(scanreadindex(par, itab) == 0); - } - return 0; -} - -static int -scanreadall(Par par) -{ - if (par.m_no < 11) - CHK(scanreadtable(par) == 0); - CHK(scanreadindex(par) == 0); - return 0; -} - -// scan update - -static int -scanupdatetable(Par par) -{ - Con& con = par.con(); - const Tab& tab = par.tab(); - Set& set = par.set(); - LL3("scan update " << tab.m_name); - Set set2(tab, set.m_rows); - CHK(con.startTransaction() == 0); - CHK(con.getNdbOperation(tab) == 0); - CHK(con.openScanExclusive(par.m_scanex) == 0); - set2.getval(par); - CHK(con.executeScan() == 0); - unsigned count = 0; - // updating trans - Con con2; - con2.m_ndb = con.m_ndb; - CHK(con2.startBuddyTransaction(con) == 0); - while (1) { - int ret; - CHK((ret = con.nextScanResult()) == 0 || ret == 1); - if (ret == 1) - break; - unsigned i = (unsigned)-1; - CHK(set2.getkey(par, &i) == 0); - LL4("key " << i); - CHK(set2.putval(i, false) == 0); - CHK(con2.takeOverForUpdate(con) == 0); - Par par2 = par; - par2.m_con = &con2; - set.lock(); - set.calc(par, i); - LL4("scan update " << tab.m_name << ": " << *set.m_row[i]); - CHKTRY(set.setrow(par2, i) == 0, set.unlock()); - set.unlock(); - CHK(con2.execute(NoCommit) == 0); - count++; - } - CHK(con2.execute(Commit) == 0); - con2.closeTransaction(); - LL3("scan update " << tab.m_name << " rows updated=" << count); - con.closeTransaction(); - return 0; -} - -static int -scanupdateindex(Par par, const ITab& itab, const BSet& bset) -{ - Con& con = par.con(); - const Tab& tab = par.tab(); - Set& set = par.set(); - LL3("scan update " << itab.m_name); - Set set2(tab, set.m_rows); - CHK(con.startTransaction() == 0); - CHK(con.getNdbOperation(itab, tab) == 0); - CHK(con.openScanExclusive(par.m_scanex) == 0); - CHK(bset.setbnd(par) == 0); - set2.getval(par); - CHK(con.executeScan() == 0); - unsigned count = 0; - // updating trans - Con con2; - con2.m_ndb = con.m_ndb; - CHK(con2.startBuddyTransaction(con) == 0); - while (1) { - int ret; - CHK((ret = con.nextScanResult()) == 0 || ret == 1); - if (ret == 1) - break; - unsigned i = (unsigned)-1; - CHK(set2.getkey(par, &i) == 0); - LL4("key " << i); - CHK(set2.putval(i, par.m_dups) == 0); - // avoid deadlock for now - //if (! isthrrow(par, i)) - //continue; - CHK(con2.takeOverForUpdate(con) == 0); - Par par2 = par; - par2.m_con = &con2; - set.lock(); - set.calc(par, i); - LL4("scan update " << itab.m_name << ": " << *set.m_row[i]); - CHKTRY(set.setrow(par2, i) == 0, set.unlock()); - set.unlock(); - CHK(con2.execute(NoCommit) == 0); - count++; - } - CHK(con2.execute(Commit) == 0); - con2.closeTransaction(); - LL3("scan update " << itab.m_name << " rows updated=" << count); - con.closeTransaction(); - return 0; -} - -static int -scanupdateindex(Par par, const ITab& itab) -{ - const Tab& tab = par.tab(); - for (unsigned i = 0; i < par.m_subloop; i++) { - BSet bset(tab, itab, par.m_rows); - bset.calc(par); - CHK(scanupdateindex(par, itab, bset) == 0); - } - return 0; -} - -static int -scanupdateindex(Par par) -{ - const Tab& tab = par.tab(); - for (unsigned i = 0; i < tab.m_itabs; i++) { - if (! useindex(i)) - continue; - const ITab& itab = tab.m_itab[i]; - CHK(scanupdateindex(par, itab) == 0); - } - return 0; -} - -static int -scanupdateall(Par par) -{ - CHK(scanupdatetable(par) == 0); - CHK(scanupdateindex(par) == 0); - return 0; -} - -// medium level routines - -static bool -ignoreverifyerror(Par par) -{ - Con& con = par.con(); - bool b = par.m_threads > 1; - if (b) { - LL1("ignore verify error"); - if (con.m_tx != 0) - con.closeTransaction(); - return true; - } - return b; -} - -static int -readverify(Par par) -{ - par.m_verify = true; - CHK(pkread(par) == 0 || ignoreverifyerror(par)); - CHK(scanreadall(par) == 0 || ignoreverifyerror(par)); - return 0; -} - -static bool -ignoredeadlock(Par par) -{ - Con& con = par.con(); - if (con.m_errtype == Con::ErrDeadlock) { - LL1("ignore deadlock"); - con.closeTransaction(); - return true; - } - return false; -} - -static int -pkupdatescanread(Par par) -{ - par.m_dups = true; - unsigned sel = urandom(10); - if (sel < 5) { - CHK(pkupdate(par) == 0); - } else if (sel < 6) { - par.m_verify = false; - CHK(scanreadtable(par) == 0); - } else { - par.m_verify = false; - CHK(scanreadindex(par) == 0); - } - return 0; -} - -static int -mixedoperations(Par par) -{ - par.m_dups = true; - unsigned sel = urandom(10); - if (sel < 2) { - CHK(pkdelete(par) == 0 || ignoredeadlock(par)); - } else if (sel < 4) { - CHK(pkupdate(par) == 0 || ignoredeadlock(par)); - } else if (sel < 6) { - CHK(scanupdatetable(par) == 0 || ignoredeadlock(par)); - } else { - CHK(scanupdateindex(par) == 0 || ignoredeadlock(par)); - } - return 0; -} - -static int -pkupdateindexbuild(Par par) -{ - if (par.m_no == 0) { - CHK(createindex(par) == 0); - CHK(invalidateindex(par) == 0); - } else { - CHK(pkupdate(par) == 0); - } - return 0; -} - -// threads - -typedef int (*TFunc)(Par par); -enum TMode { ST = 1, MT = 2 }; - -extern "C" { static void* runthread(void* arg); } - -struct Thr { - enum State { Wait, Start, Stop, Stopped, Exit }; - State m_state; - Par m_par; - Uint64 m_id; - NdbThread* m_thread; - NdbMutex* m_mutex; - NdbCondition* m_cond; - TFunc m_func; - int m_ret; - void* m_status; - Thr(Par par, unsigned n); - ~Thr(); - int run(); - void start(); - void stop(); - void stopped(); - void exit(); - // - void lock() { - NdbMutex_Lock(m_mutex); - } - void unlock() { - NdbMutex_Unlock(m_mutex); - } - void wait() { - NdbCondition_Wait(m_cond, m_mutex); - } - void signal() { - NdbCondition_Signal(m_cond); - } - void join() { - NdbThread_WaitFor(m_thread, &m_status); - m_thread = 0; - } -}; - -Thr::Thr(Par par, unsigned n) : - m_state(Wait), - m_par(par), - m_id(0), - m_thread(0), - m_mutex(0), - m_cond(0), - m_func(0), - m_ret(0), - m_status(0) -{ - m_par.m_no = n; - char buf[10]; - sprintf(buf, "thr%03u", par.m_no); - const char* name = strcpy(new char[10], buf); - // mutex - m_mutex = NdbMutex_Create(); - m_cond = NdbCondition_Create(); - assert(m_mutex != 0 && m_cond != 0); - // run - const unsigned stacksize = 256 * 1024; - const NDB_THREAD_PRIO prio = NDB_THREAD_PRIO_LOW; - m_thread = NdbThread_Create(runthread, (void**)this, stacksize, name, prio); -} - -Thr::~Thr() -{ - if (m_thread != 0) { - NdbThread_Destroy(&m_thread); - m_thread = 0; - } - if (m_cond != 0) { - NdbCondition_Destroy(m_cond); - m_cond = 0; - } - if (m_mutex != 0) { - NdbMutex_Destroy(m_mutex); - m_mutex = 0; - } -} - -static void* -runthread(void* arg) -{ - Thr& thr = *(Thr*)arg; - thr.m_id = (Uint64)pthread_self(); - if (thr.run() < 0) { - LL1("exit on error"); - } else { - LL4("exit ok"); - } - return 0; -} - -int -Thr::run() -{ - LL4("run"); - Con con; - CHK(con.connect() == 0); - m_par.m_con = &con; - LL4("connected"); - while (1) { - lock(); - while (m_state != Start && m_state != Exit) { - LL4("wait"); - wait(); - } - if (m_state == Exit) { - LL4("exit"); - unlock(); - break; - } - LL4("start"); - CHK(con.bugger() == 0); - assert(m_state == Start); - m_ret = (*m_func)(m_par); - m_state = Stopped; - LL4("stop"); - signal(); - unlock(); - CHK(m_ret == 0); - } - con.disconnect(); - return 0; -} - -void -Thr::start() -{ - lock(); - m_state = Start; - signal(); - unlock(); -} - -void -Thr::stop() -{ - lock(); - m_state = Stop; - signal(); - unlock(); -} - -void -Thr::stopped() -{ - lock(); - while (m_state != Stopped) - wait(); - m_state = Wait; - unlock(); -} - -void -Thr::exit() -{ - lock(); - m_state = Exit; - signal(); - unlock(); -} - -// test run - -static Thr** g_thrlist = 0; - -static unsigned -getthrno() -{ - if (g_thrlist != 0) { - Uint64 id = (Uint64)pthread_self(); - for (unsigned n = 0; n < g_opt.m_threads; n++) { - if (g_thrlist[n] != 0) { - const Thr& thr = *g_thrlist[n]; - if (thr.m_id == id) - return thr.m_par.m_no; - } - } - } - return (unsigned)-1; -} - -static int -runstep(Par par, const char* fname, TFunc func, unsigned mode) -{ - LL2(fname); - const int threads = (mode & ST ? 1 : par.m_threads); - for (int n = 0; n < threads; n++) { - LL4("start " << n); - Thr& thr = *g_thrlist[n]; - thr.m_par.m_tab = par.m_tab; - thr.m_par.m_set = par.m_set; - thr.m_func = func; - thr.start(); - } - unsigned errs = 0; - for (int n = threads - 1; n >= 0; n--) { - LL4("stop " << n); - Thr& thr = *g_thrlist[n]; - thr.stopped(); - if (thr.m_ret != 0) - errs++; - } - CHK(errs == 0); - return 0; -} - -#define RUNSTEP(par, func, mode) CHK(runstep(par, #func, func, mode) == 0) - -static int -tbuild(Par par) -{ - RUNSTEP(par, droptable, ST); - RUNSTEP(par, createtable, ST); - RUNSTEP(par, invalidatetable, MT); - for (unsigned i = 0; i < par.m_subloop; i++) { - if (i % 2 == 0) { - RUNSTEP(par, createindex, ST); - RUNSTEP(par, invalidateindex, MT); - RUNSTEP(par, pkinsert, MT); - } else { - RUNSTEP(par, pkinsert, MT); - RUNSTEP(par, createindex, ST); - RUNSTEP(par, invalidateindex, MT); - } - RUNSTEP(par, readverify, MT); - RUNSTEP(par, pkdelete, MT); - RUNSTEP(par, readverify, MT); - RUNSTEP(par, dropindex, ST); - } - return 0; -} - -static int -tpkops(Par par) -{ - RUNSTEP(par, droptable, ST); - RUNSTEP(par, createtable, ST); - RUNSTEP(par, invalidatetable, MT); - RUNSTEP(par, pkinsert, MT); - RUNSTEP(par, createindex, ST); - RUNSTEP(par, invalidateindex, MT); - RUNSTEP(par, readverify, MT); - for (unsigned i = 0; i < par.m_subloop; i++) { - RUNSTEP(par, pkupdatescanread, MT); - RUNSTEP(par, readverify, MT); - } - RUNSTEP(par, pkdelete, MT); - RUNSTEP(par, readverify, MT); - return 0; -} - -static int -tmixedops(Par par) -{ - RUNSTEP(par, droptable, ST); - RUNSTEP(par, createtable, ST); - RUNSTEP(par, invalidatetable, MT); - RUNSTEP(par, pkinsert, MT); - RUNSTEP(par, createindex, ST); - RUNSTEP(par, invalidateindex, MT); - RUNSTEP(par, readverify, MT); - for (unsigned i = 0; i < par.m_subloop; i++) { - RUNSTEP(par, mixedoperations, MT); - RUNSTEP(par, readverify, MT); - } - return 0; -} - -static int -tbusybuild(Par par) -{ - RUNSTEP(par, droptable, ST); - RUNSTEP(par, createtable, ST); - RUNSTEP(par, invalidatetable, MT); - RUNSTEP(par, pkinsert, MT); - for (unsigned i = 0; i < par.m_subloop; i++) { - RUNSTEP(par, pkupdateindexbuild, MT); - RUNSTEP(par, readverify, MT); - RUNSTEP(par, dropindex, ST); - } - return 0; -} - -static int -ttiming(Par par) -{ - Tmr t0, t1, t2; - RUNSTEP(par, droptable, ST); - RUNSTEP(par, createtable, ST); - RUNSTEP(par, invalidatetable, MT); - for (unsigned i = 0; i < par.m_subloop; i++) { - RUNSTEP(par, pkinsert, MT); - t1.on(); - RUNSTEP(par, pkupdate, MT); - t1.off(par.m_totrows); - t0.on(); - RUNSTEP(par, createindex, ST); - RUNSTEP(par, invalidateindex, MT); - t0.off(par.m_totrows); - t2.on(); - RUNSTEP(par, pkupdate, MT); - t2.off(par.m_totrows); - RUNSTEP(par, dropindex, ST); - } - LL1("build index - " << t0.time()); - LL1("update - " << t1.time()); - LL1("update indexed - " << t2.time()); - LL1("overhead - " << t2.over(t1)); - return 0; -} - -static int -tdrop(Par par) -{ - RUNSTEP(par, droptable, ST); - return 0; -} - -struct TCase { - const char* m_name; - TFunc m_func; - const char* m_desc; - TCase(const char* name, TFunc func, const char* desc) : - m_name(name), - m_func(func), - m_desc(desc) { - } -}; - -static const TCase -tcaselist[] = { - TCase("a", tbuild, "index build"), - TCase("b", tpkops, "pk operations and scan reads"), - TCase("c", tmixedops, "pk operations and scan operations"), - TCase("d", tbusybuild, "pk operations and index build"), - TCase("t", ttiming, "time index build and maintenance"), - TCase("z", tdrop, "drop test tables") -}; - -static const unsigned -tcasecount = sizeof(tcaselist) / sizeof(tcaselist[0]); - -static void -printcases() -{ - ndbout << "test cases:" << endl; - for (unsigned i = 0; i < tcasecount; i++) { - const TCase& tcase = tcaselist[i]; - ndbout << " " << tcase.m_name << " - " << tcase.m_desc << endl; - } -} - -static void -printtables() -{ - ndbout << "tables and indexes:" << endl; - for (unsigned j = 0; j < tabcount; j++) { - const Tab& tab = tablist[j]; - ndbout << " " << tab.m_name; - for (unsigned i = 0; i < tab.m_itabs; i++) { - const ITab& itab = tab.m_itab[i]; - ndbout << " " << itab.m_name; - } - ndbout << endl; - } -} - -static int -runtest(Par par) -{ - LL1("start"); - srandom(par.m_seed); - Con con; - CHK(con.connect() == 0); - par.m_con = &con; - g_thrlist = new Thr* [par.m_threads]; - for (unsigned n = 0; n < par.m_threads; n++) { - g_thrlist[n] = 0; - } - for (unsigned n = 0; n < par.m_threads; n++) { - g_thrlist[n] = new Thr(par, n); - Thr& thr = *g_thrlist[n]; - assert(thr.m_thread != 0); - } - for (unsigned l = 0; par.m_loop == 0 || l < par.m_loop; l++) { - LL1("loop " << l); - for (unsigned i = 0; i < tcasecount; i++) { - const TCase& tcase = tcaselist[i]; - if (par.m_case != 0 && strchr(par.m_case, tcase.m_name[0]) == 0) - continue; - LL1("case " << tcase.m_name << " - " << tcase.m_desc); - for (unsigned j = 0; j < tabcount; j++) { - if (! usetable(j)) - continue; - const Tab& tab = tablist[j]; - par.m_tab = &tab; - Set set(tab, par.m_totrows); - par.m_set = &set; - LL1("table " << tab.m_name); - CHK(tcase.m_func(par) == 0); - } - } - } - for (unsigned n = 0; n < par.m_threads; n++) { - Thr& thr = *g_thrlist[n]; - thr.exit(); - } - for (unsigned n = 0; n < par.m_threads; n++) { - Thr& thr = *g_thrlist[n]; - thr.join(); - delete &thr; - } - delete [] g_thrlist; - g_thrlist = 0; - con.disconnect(); - LL1("done"); - return 0; -} - -NDB_COMMAND(testOIBasic, "testOIBasic", "testOIBasic", "testOIBasic", 65535) -{ - while (++argv, --argc > 0) { - const char* arg = argv[0]; - if (*arg != '-') { - ndbout << "testOIBasic: unknown argument " << arg; - goto usage; - } - if (strcmp(arg, "-case") == 0) { - if (++argv, --argc > 0) { - g_opt.m_case = strdup(argv[0]); - continue; - } - } - if (strcmp(arg, "-core") == 0) { - g_opt.m_core = true; - continue; - } - if (strcmp(arg, "-dups") == 0) { - g_opt.m_dups = true; - continue; - } - if (strcmp(arg, "-fragtype") == 0) { - if (++argv, --argc > 0) { - if (strcmp(argv[0], "single") == 0) { - g_opt.m_fragtype = NdbDictionary::Object::FragSingle; - continue; - } - if (strcmp(argv[0], "small") == 0) { - g_opt.m_fragtype = NdbDictionary::Object::FragAllSmall; - continue; - } - if (strcmp(argv[0], "medium") == 0) { - g_opt.m_fragtype = NdbDictionary::Object::FragAllMedium; - continue; - } - if (strcmp(argv[0], "large") == 0) { - g_opt.m_fragtype = NdbDictionary::Object::FragAllLarge; - continue; - } - } - } - if (strcmp(arg, "-index") == 0) { - if (++argv, --argc > 0) { - g_opt.m_index = strdup(argv[0]); - continue; - } - } - if (strcmp(arg, "-loop") == 0) { - if (++argv, --argc > 0) { - g_opt.m_loop = atoi(argv[0]); - continue; - } - } - if (strcmp(arg, "-rows") == 0) { - if (++argv, --argc > 0) { - g_opt.m_rows = atoi(argv[0]); - continue; - } - } - if (strcmp(arg, "-scanrd") == 0) { - if (++argv, --argc > 0) { - g_opt.m_scanrd = atoi(argv[0]); - continue; - } - } - if (strcmp(arg, "-scanex") == 0) { - if (++argv, --argc > 0) { - g_opt.m_scanex = atoi(argv[0]); - continue; - } - } - if (strcmp(arg, "-seed") == 0) { - if (++argv, --argc > 0) { - g_opt.m_seed = atoi(argv[0]); - continue; - } - } - if (strcmp(arg, "-subloop") == 0) { - if (++argv, --argc > 0) { - g_opt.m_subloop = atoi(argv[0]); - continue; - } - } - if (strcmp(arg, "-table") == 0) { - if (++argv, --argc > 0) { - g_opt.m_table = strdup(argv[0]); - continue; - } - } - if (strcmp(arg, "-threads") == 0) { - if (++argv, --argc > 0) { - g_opt.m_threads = atoi(argv[0]); - continue; - } - } - if (strcmp(arg, "-v") == 0) { - if (++argv, --argc > 0) { - g_opt.m_v = atoi(argv[0]); - continue; - } - } - if (strncmp(arg, "-v", 2) == 0 && isdigit(arg[2])) { - g_opt.m_v = atoi(&arg[2]); - continue; - } - if (strcmp(arg, "-h") == 0 || strcmp(arg, "-help") == 0) { - printhelp(); - goto wrongargs; - } - ndbout << "testOIBasic: unknown option " << arg; - goto usage; - } - { - Par par(g_opt); - if (runtest(par) < 0) - goto failed; - } - // always exit with NDBT code -ok: - return NDBT_ProgramExit(NDBT_OK); -failed: - return NDBT_ProgramExit(NDBT_FAILED); -usage: - ndbout << " (use -h for help)" << endl; -wrongargs: - return NDBT_ProgramExit(NDBT_WRONGARGS); -} - -// vim: set sw=2 et: diff --git a/ndb/test/ndbapi/testOIBasic/times.txt b/ndb/test/ndbapi/testOIBasic/times.txt deleted file mode 100644 index 641e9ddb4bf..00000000000 --- a/ndb/test/ndbapi/testOIBasic/times.txt +++ /dev/null @@ -1,8 +0,0 @@ -one db-node -testOIBasic -case t -table 1 -index 1 -fragtype small -threads 10 -rows 5000 -subloop 1 ------------------------------------------------------------- -040331 -build index - 5769 ms per 50000 ( 115 ms per 1000 ) -update - 5962 ms per 50000 ( 119 ms per 1000 ) -update indexed - 14851 ms per 50000 ( 297 ms per 1000 ) -overhead - 149 pct diff --git a/ndb/test/ndbapi/testOperations.cpp b/ndb/test/ndbapi/testOperations.cpp new file mode 100644 index 00000000000..bb58e69e898 --- /dev/null +++ b/ndb/test/ndbapi/testOperations.cpp @@ -0,0 +1,271 @@ +/* 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 */ + +#include "NDBT_Test.hpp" +#include "NDBT_ReturnCodes.h" +#include "HugoTransactions.hpp" +#include "UtilTransactions.hpp" + +struct OperationTestCase { + const char * name; + bool preCond; // start transaction | insert | commit + + // start transaction + const char * op1; + const int res1; + const int val1; + + // no commit + + const char * op2; + const int res2; + const int val2; + // Commit + + // start transaction + // op3 = READ + const int res3; + const int val3; + // commit transaction +}; + +OperationTestCase matrix[] = { + { "ReadRead", true, "READ", 0, 0, "READ", 0, 0, 0, 0 }, + { "ReadReadEx", true, "READ", 0, 0, "READ-EX", 0, 0, 0, 0 }, + { "ReadSimpleRead", true, "READ", 0, 0, "S-READ", 0, 0, 0, 0 }, + { "ReadDirtyRead", true, "READ", 0, 0, "D-READ", 0, 0, 0, 0 }, + { "ReadInsert", true, "READ", 0, 0, "INSERT", 630, 1, 0, 0 }, + { "ReadUpdate", true, "READ", 0, 0, "UPDATE", 0, 1, 0, 1 }, + { "ReadDelete", true, "READ", 0, 0, "DELETE", 0, 0, 626, 0 }, + + { "FReadRead", false, "READ", 626, 0, "READ", 626, 0, 626, 0 }, + { "FReadReadEx", false, "READ", 626, 0, "READ-EX", 626, 0, 626, 0 }, + { "FReadSimpleRead", false, "READ", 626, 0, "S-READ", 626, 0, 626, 0 }, + { "FReadDirtyRead", false, "READ", 626, 0, "D-READ", 626, 0, 626, 0 }, + { "FReadInsert", false, "READ", 626, 0, "INSERT", 0, 1, 0, 1 }, + { "FReadUpdate", false, "READ", 626, 0, "UPDATE", 626, 0, 626, 0 }, + { "FReadDelete", false, "READ", 626, 0, "DELETE", 626, 0, 626, 0 }, + + { "ReadExRead", true, "READ-EX", 0, 0, "READ", 0, 0, 0, 0 }, + { "ReadExReadEx", true, "READ-EX", 0, 0, "READ-EX", 0, 0, 0, 0 }, + { "ReadExSimpleRead", true, "READ-EX", 0, 0, "S-READ", 0, 0, 0, 0 }, + { "ReadExDirtyRead", true, "READ-EX", 0, 0, "D-READ", 0, 0, 0, 0 }, + { "ReadExInsert", true, "READ-EX", 0, 0, "INSERT", 630, 1, 0, 0 }, + { "ReadExUpdate", true, "READ-EX", 0, 0, "UPDATE", 0, 1, 0, 1 }, + { "ReadExDelete", true, "READ-EX", 0, 0, "DELETE", 0, 0, 626, 0 }, + + { "InsertRead", false, "INSERT", 0, 0, "READ", 0, 0, 0, 0 }, + { "InsertReadEx", false, "INSERT", 0, 0, "READ-EX", 0, 0, 0, 0 }, + { "InsertSimpleRead",false, "INSERT", 0, 0, "S-READ", 0, 0, 0, 0 }, + { "InsertDirtyRead", false, "INSERT", 0, 0, "D-READ", 0, 0, 0, 0 }, + { "InsertInsert", false, "INSERT", 0, 0, "INSERT", 630, 0, 626, 0 }, + { "InsertUpdate", false, "INSERT", 0, 0, "UPDATE", 0, 1, 0, 1 }, + { "InsertDelete", false, "INSERT", 0, 0, "DELETE", 0, 0, 626, 0 }, + + { "UpdateRead", true, "UPDATE", 0, 1, "READ", 0, 1, 0, 1 }, + { "UpdateReadEx", true, "UPDATE", 0, 1, "READ-EX", 0, 1, 0, 1 }, + { "UpdateSimpleRead", true, "UPDATE", 0, 1, "S-READ", 0, 1, 0, 1 }, + { "UpdateDirtyRead", true, "UPDATE", 0, 1, "D-READ", 0, 1, 0, 1 }, + { "UpdateInsert", true, "UPDATE", 0, 1, "INSERT", 630, 0, 0, 0 }, + { "UpdateUpdate", true, "UPDATE", 0, 1, "UPDATE", 0, 2, 0, 2 }, + { "UpdateDelete", true, "UPDATE", 0, 1, "DELETE", 0, 0, 626, 0 }, + + { "DeleteRead", true, "DELETE", 0, 0, "READ", 626, 0, 0, 0 }, + { "DeleteReadEx", true, "DELETE", 0, 0, "READ-EX", 626, 0, 0, 0 }, + { "DeleteSimpleRead", true, "DELETE", 0, 0, "S-READ", 626, 0, 0, 0 }, + { "DeleteDirtyRead", true, "DELETE", 0, 0, "D-READ", 626, 0, 0, 0 }, + { "DeleteInsert", true, "DELETE", 0, 0, "INSERT", 0, 1, 0, 1 }, + { "DeleteUpdate", true, "DELETE", 0, 0, "UPDATE", 626, 1, 0, 0 }, + { "DeleteDelete", true, "DELETE", 0, 0, "DELETE", 626, 0, 0, 0 } +}; + +#define CHECK(b) if (!(b)) { \ + g_err << "ERR: "<< step->getName() \ + << " failed on line " << __LINE__ << endl; \ + result = NDBT_FAILED; \ + break; } + +int +runOp(HugoOperations & hugoOps, + Ndb * pNdb, + const char * op, + int value){ + +#define C2(x, y) { int r = (x); int s = (y); if(r != s) {\ + g_err << "ERR: failed on line " << __LINE__ << ": " \ + << r << " != " << s << endl; \ + return NDBT_FAILED; }} + + if(strcmp(op, "READ") == 0){ + C2(hugoOps.pkReadRecord(pNdb, 1, false, 1), 0); + } else if(strcmp(op, "READ-EX") == 0){ + C2(hugoOps.pkReadRecord(pNdb, 1, true, 1), 0); + } else if(strcmp(op, "S-READ") == 0){ + C2(hugoOps.pkSimpleReadRecord(pNdb, 1, 1), 0); + } else if(strcmp(op, "D-READ") == 0){ + C2(hugoOps.pkDirtyReadRecord(pNdb, 1, 1), 0); + } else if(strcmp(op, "INSERT") == 0){ + C2(hugoOps.pkInsertRecord(pNdb, 1, 1, value), 0); + } else if(strcmp(op, "UPDATE") == 0){ + C2(hugoOps.pkUpdateRecord(pNdb, 1, 1, value), 0); + } else if(strcmp(op, "DELETE") == 0){ + C2(hugoOps.pkDeleteRecord(pNdb, 1, 1), 0); + } else { + g_err << __FILE__ << " - " << __LINE__ + << ": Unknown operation" << op << endl; + return NDBT_FAILED; + } + + return NDBT_OK; +} + +int +checkVal(HugoOperations & hugoOps, + const char * op, + int value, + int result){ + if(result != 0) + return NDBT_OK; + + if(strcmp(op, "READ") == 0){ + } else if(strcmp(op, "READ-EX") == 0){ + } else if(strcmp(op, "S-READ") == 0){ + } else if(strcmp(op, "D-READ") == 0){ + } else { + return NDBT_OK; + } + + return hugoOps.verifyUpdatesValue(value); +} + +int +runTwoOperations(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + + const char * op1 = ctx->getProperty("op1", "NONE"); + const int val1 = ctx->getProperty("val1", ~0); + const int res1 = ctx->getProperty("res1", ~0); + const char * op2 = ctx->getProperty("op2", "NONE"); + const int res2 = ctx->getProperty("res2", ~0); + const int val2 = ctx->getProperty("val2", ~0); + + const int res3 = ctx->getProperty("res3", ~0); + const int val3 = ctx->getProperty("val3", ~0); + + do { + // Insert, read + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(runOp(hugoOps, pNdb, op1, val1) == 0); + AbortOption oa = (res1 == 0) ? AbortOnError : IgnoreError; + CHECK(hugoOps.execute_NoCommit(pNdb, oa) == res1); + CHECK(checkVal(hugoOps, op1, val1, res1) == 0); + + ndbout_c("-- running op 2"); + + CHECK(runOp(hugoOps, pNdb, op2, val2) == 0); + CHECK(hugoOps.execute_Commit(pNdb) == res2); + CHECK(checkVal(hugoOps, op2, val2, res2) == 0); + + } while(false); + hugoOps.closeTransaction(pNdb); + + if(result != NDBT_OK) + return result; + + do { + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(runOp(hugoOps, pNdb, "READ", 0) == 0); + CHECK(hugoOps.execute_Commit(pNdb) == res3); + CHECK(checkVal(hugoOps, "READ", val3, res3) == 0); + } while(false); + hugoOps.closeTransaction(pNdb); + + return result; +} + +int +runInsertRecord(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + + do{ + // Insert, insert + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0); + CHECK(hugoOps.execute_Commit(pNdb) == 0); + + } while(false); + + hugoOps.closeTransaction(pNdb); + + return result; +} + +int +runClearTable(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + + UtilTransactions utilTrans(*ctx->getTab()); + if (utilTrans.clearTable2(GETNDB(step), records, 240) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int +main(int argc, const char** argv){ + + NDBT_TestSuite ts("testOperations"); + for(Uint32 i = 0; iaddInitializer(new NDBT_Initializer(pt, + "runClearTable", + runClearTable)); + + if(matrix[i].preCond){ + pt->addInitializer(new NDBT_Initializer(pt, + "runInsertRecord", + runInsertRecord)); + } + + pt->setProperty("op1", matrix[i].op1); + pt->setProperty("res1", matrix[i].res1); + pt->setProperty("val1", matrix[i].val1); + + pt->setProperty("op2", matrix[i].op2); + pt->setProperty("res2", matrix[i].res2); + pt->setProperty("val2", matrix[i].val2); + + pt->setProperty("res3", matrix[i].res3); + pt->setProperty("val3", matrix[i].val3); + + pt->addStep(new NDBT_ParallelStep(pt, + matrix[i].name, + runTwoOperations)); + pt->addFinalizer(new NDBT_Finalizer(pt, + "runClearTable", + runClearTable)); + + ts.addTest(pt); + } + + return ts.execute(argc, argv); +} + diff --git a/ndb/test/ndbapi/testOperations/Makefile b/ndb/test/ndbapi/testOperations/Makefile deleted file mode 100644 index 25546ade639..00000000000 --- a/ndb/test/ndbapi/testOperations/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := testOperations - -SOURCES := testOperations.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/testOperations/testOperations.cpp b/ndb/test/ndbapi/testOperations/testOperations.cpp deleted file mode 100644 index bb58e69e898..00000000000 --- a/ndb/test/ndbapi/testOperations/testOperations.cpp +++ /dev/null @@ -1,271 +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 */ - -#include "NDBT_Test.hpp" -#include "NDBT_ReturnCodes.h" -#include "HugoTransactions.hpp" -#include "UtilTransactions.hpp" - -struct OperationTestCase { - const char * name; - bool preCond; // start transaction | insert | commit - - // start transaction - const char * op1; - const int res1; - const int val1; - - // no commit - - const char * op2; - const int res2; - const int val2; - // Commit - - // start transaction - // op3 = READ - const int res3; - const int val3; - // commit transaction -}; - -OperationTestCase matrix[] = { - { "ReadRead", true, "READ", 0, 0, "READ", 0, 0, 0, 0 }, - { "ReadReadEx", true, "READ", 0, 0, "READ-EX", 0, 0, 0, 0 }, - { "ReadSimpleRead", true, "READ", 0, 0, "S-READ", 0, 0, 0, 0 }, - { "ReadDirtyRead", true, "READ", 0, 0, "D-READ", 0, 0, 0, 0 }, - { "ReadInsert", true, "READ", 0, 0, "INSERT", 630, 1, 0, 0 }, - { "ReadUpdate", true, "READ", 0, 0, "UPDATE", 0, 1, 0, 1 }, - { "ReadDelete", true, "READ", 0, 0, "DELETE", 0, 0, 626, 0 }, - - { "FReadRead", false, "READ", 626, 0, "READ", 626, 0, 626, 0 }, - { "FReadReadEx", false, "READ", 626, 0, "READ-EX", 626, 0, 626, 0 }, - { "FReadSimpleRead", false, "READ", 626, 0, "S-READ", 626, 0, 626, 0 }, - { "FReadDirtyRead", false, "READ", 626, 0, "D-READ", 626, 0, 626, 0 }, - { "FReadInsert", false, "READ", 626, 0, "INSERT", 0, 1, 0, 1 }, - { "FReadUpdate", false, "READ", 626, 0, "UPDATE", 626, 0, 626, 0 }, - { "FReadDelete", false, "READ", 626, 0, "DELETE", 626, 0, 626, 0 }, - - { "ReadExRead", true, "READ-EX", 0, 0, "READ", 0, 0, 0, 0 }, - { "ReadExReadEx", true, "READ-EX", 0, 0, "READ-EX", 0, 0, 0, 0 }, - { "ReadExSimpleRead", true, "READ-EX", 0, 0, "S-READ", 0, 0, 0, 0 }, - { "ReadExDirtyRead", true, "READ-EX", 0, 0, "D-READ", 0, 0, 0, 0 }, - { "ReadExInsert", true, "READ-EX", 0, 0, "INSERT", 630, 1, 0, 0 }, - { "ReadExUpdate", true, "READ-EX", 0, 0, "UPDATE", 0, 1, 0, 1 }, - { "ReadExDelete", true, "READ-EX", 0, 0, "DELETE", 0, 0, 626, 0 }, - - { "InsertRead", false, "INSERT", 0, 0, "READ", 0, 0, 0, 0 }, - { "InsertReadEx", false, "INSERT", 0, 0, "READ-EX", 0, 0, 0, 0 }, - { "InsertSimpleRead",false, "INSERT", 0, 0, "S-READ", 0, 0, 0, 0 }, - { "InsertDirtyRead", false, "INSERT", 0, 0, "D-READ", 0, 0, 0, 0 }, - { "InsertInsert", false, "INSERT", 0, 0, "INSERT", 630, 0, 626, 0 }, - { "InsertUpdate", false, "INSERT", 0, 0, "UPDATE", 0, 1, 0, 1 }, - { "InsertDelete", false, "INSERT", 0, 0, "DELETE", 0, 0, 626, 0 }, - - { "UpdateRead", true, "UPDATE", 0, 1, "READ", 0, 1, 0, 1 }, - { "UpdateReadEx", true, "UPDATE", 0, 1, "READ-EX", 0, 1, 0, 1 }, - { "UpdateSimpleRead", true, "UPDATE", 0, 1, "S-READ", 0, 1, 0, 1 }, - { "UpdateDirtyRead", true, "UPDATE", 0, 1, "D-READ", 0, 1, 0, 1 }, - { "UpdateInsert", true, "UPDATE", 0, 1, "INSERT", 630, 0, 0, 0 }, - { "UpdateUpdate", true, "UPDATE", 0, 1, "UPDATE", 0, 2, 0, 2 }, - { "UpdateDelete", true, "UPDATE", 0, 1, "DELETE", 0, 0, 626, 0 }, - - { "DeleteRead", true, "DELETE", 0, 0, "READ", 626, 0, 0, 0 }, - { "DeleteReadEx", true, "DELETE", 0, 0, "READ-EX", 626, 0, 0, 0 }, - { "DeleteSimpleRead", true, "DELETE", 0, 0, "S-READ", 626, 0, 0, 0 }, - { "DeleteDirtyRead", true, "DELETE", 0, 0, "D-READ", 626, 0, 0, 0 }, - { "DeleteInsert", true, "DELETE", 0, 0, "INSERT", 0, 1, 0, 1 }, - { "DeleteUpdate", true, "DELETE", 0, 0, "UPDATE", 626, 1, 0, 0 }, - { "DeleteDelete", true, "DELETE", 0, 0, "DELETE", 626, 0, 0, 0 } -}; - -#define CHECK(b) if (!(b)) { \ - g_err << "ERR: "<< step->getName() \ - << " failed on line " << __LINE__ << endl; \ - result = NDBT_FAILED; \ - break; } - -int -runOp(HugoOperations & hugoOps, - Ndb * pNdb, - const char * op, - int value){ - -#define C2(x, y) { int r = (x); int s = (y); if(r != s) {\ - g_err << "ERR: failed on line " << __LINE__ << ": " \ - << r << " != " << s << endl; \ - return NDBT_FAILED; }} - - if(strcmp(op, "READ") == 0){ - C2(hugoOps.pkReadRecord(pNdb, 1, false, 1), 0); - } else if(strcmp(op, "READ-EX") == 0){ - C2(hugoOps.pkReadRecord(pNdb, 1, true, 1), 0); - } else if(strcmp(op, "S-READ") == 0){ - C2(hugoOps.pkSimpleReadRecord(pNdb, 1, 1), 0); - } else if(strcmp(op, "D-READ") == 0){ - C2(hugoOps.pkDirtyReadRecord(pNdb, 1, 1), 0); - } else if(strcmp(op, "INSERT") == 0){ - C2(hugoOps.pkInsertRecord(pNdb, 1, 1, value), 0); - } else if(strcmp(op, "UPDATE") == 0){ - C2(hugoOps.pkUpdateRecord(pNdb, 1, 1, value), 0); - } else if(strcmp(op, "DELETE") == 0){ - C2(hugoOps.pkDeleteRecord(pNdb, 1, 1), 0); - } else { - g_err << __FILE__ << " - " << __LINE__ - << ": Unknown operation" << op << endl; - return NDBT_FAILED; - } - - return NDBT_OK; -} - -int -checkVal(HugoOperations & hugoOps, - const char * op, - int value, - int result){ - if(result != 0) - return NDBT_OK; - - if(strcmp(op, "READ") == 0){ - } else if(strcmp(op, "READ-EX") == 0){ - } else if(strcmp(op, "S-READ") == 0){ - } else if(strcmp(op, "D-READ") == 0){ - } else { - return NDBT_OK; - } - - return hugoOps.verifyUpdatesValue(value); -} - -int -runTwoOperations(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - HugoOperations hugoOps(*ctx->getTab()); - Ndb* pNdb = GETNDB(step); - - const char * op1 = ctx->getProperty("op1", "NONE"); - const int val1 = ctx->getProperty("val1", ~0); - const int res1 = ctx->getProperty("res1", ~0); - const char * op2 = ctx->getProperty("op2", "NONE"); - const int res2 = ctx->getProperty("res2", ~0); - const int val2 = ctx->getProperty("val2", ~0); - - const int res3 = ctx->getProperty("res3", ~0); - const int val3 = ctx->getProperty("val3", ~0); - - do { - // Insert, read - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(runOp(hugoOps, pNdb, op1, val1) == 0); - AbortOption oa = (res1 == 0) ? AbortOnError : IgnoreError; - CHECK(hugoOps.execute_NoCommit(pNdb, oa) == res1); - CHECK(checkVal(hugoOps, op1, val1, res1) == 0); - - ndbout_c("-- running op 2"); - - CHECK(runOp(hugoOps, pNdb, op2, val2) == 0); - CHECK(hugoOps.execute_Commit(pNdb) == res2); - CHECK(checkVal(hugoOps, op2, val2, res2) == 0); - - } while(false); - hugoOps.closeTransaction(pNdb); - - if(result != NDBT_OK) - return result; - - do { - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(runOp(hugoOps, pNdb, "READ", 0) == 0); - CHECK(hugoOps.execute_Commit(pNdb) == res3); - CHECK(checkVal(hugoOps, "READ", val3, res3) == 0); - } while(false); - hugoOps.closeTransaction(pNdb); - - return result; -} - -int -runInsertRecord(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - HugoOperations hugoOps(*ctx->getTab()); - Ndb* pNdb = GETNDB(step); - - do{ - // Insert, insert - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0); - CHECK(hugoOps.execute_Commit(pNdb) == 0); - - } while(false); - - hugoOps.closeTransaction(pNdb); - - return result; -} - -int -runClearTable(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - - UtilTransactions utilTrans(*ctx->getTab()); - if (utilTrans.clearTable2(GETNDB(step), records, 240) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int -main(int argc, const char** argv){ - - NDBT_TestSuite ts("testOperations"); - for(Uint32 i = 0; iaddInitializer(new NDBT_Initializer(pt, - "runClearTable", - runClearTable)); - - if(matrix[i].preCond){ - pt->addInitializer(new NDBT_Initializer(pt, - "runInsertRecord", - runInsertRecord)); - } - - pt->setProperty("op1", matrix[i].op1); - pt->setProperty("res1", matrix[i].res1); - pt->setProperty("val1", matrix[i].val1); - - pt->setProperty("op2", matrix[i].op2); - pt->setProperty("res2", matrix[i].res2); - pt->setProperty("val2", matrix[i].val2); - - pt->setProperty("res3", matrix[i].res3); - pt->setProperty("val3", matrix[i].val3); - - pt->addStep(new NDBT_ParallelStep(pt, - matrix[i].name, - runTwoOperations)); - pt->addFinalizer(new NDBT_Finalizer(pt, - "runClearTable", - runClearTable)); - - ts.addTest(pt); - } - - return ts.execute(argc, argv); -} - diff --git a/ndb/test/ndbapi/testOrderedIndex.cpp b/ndb/test/ndbapi/testOrderedIndex.cpp new file mode 100644 index 00000000000..51cc53c9975 --- /dev/null +++ b/ndb/test/ndbapi/testOrderedIndex.cpp @@ -0,0 +1,224 @@ +/* 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 */ + +#include +#include +#include +#include +#include +#include +#include + +const unsigned MaxTableAttrs = NDB_MAX_ATTRIBUTES_IN_TABLE; +const unsigned MaxIndexAttrs = NDB_MAX_ATTRIBUTES_IN_INDEX; +const unsigned MaxIndexes = 20; + +static unsigned +urandom(unsigned n) +{ + unsigned i = random(); + return i % n; +} + +static int +runDropIndex(NDBT_Context* ctx, NDBT_Step* step) +{ + const NdbDictionary::Table* pTab = ctx->getTab(); + Ndb* pNdb = GETNDB(step); + NdbDictionary::Dictionary* pDic = pNdb->getDictionary(); + NdbDictionary::Dictionary::List list; + if (pDic->listIndexes(list, pTab->getName()) != 0) { + g_err << pTab->getName() << ": listIndexes failed" << endl; + ERR(pDic->getNdbError()); + return NDBT_FAILED; + } + for (unsigned i = 0; i < list.count; i++) { + NDBT_Index* pInd = new NDBT_Index(list.elements[i].name); + pInd->setTable(pTab->getName()); + g_info << "Drop index:" << endl << *pInd; + if (pInd->dropIndexInDb(pNdb) != 0) { + return NDBT_FAILED; + } + } + return NDBT_OK; +} + +static Uint32 workaround[1000]; + +static void +setTableProperty(NDBT_Context* ctx, NDBT_Table* pTab, const char* name, Uint32 num) +{ + char key[200]; + sprintf(key, "%s-%s", name, pTab->getName()); + //ctx->setProperty(key, num); + workaround[pTab->getTableId()] = num; +} + +static Uint32 +getTableProperty(NDBT_Context* ctx, NDBT_Table* pTab, const char* name) +{ + char key[200]; + sprintf(key, "%s-%s", name, pTab->getName()); + //Uint32 num = ctx->getProperty(key, (Uint32)-1); + Uint32 num = workaround[pTab->getTableId()]; + assert(num != (Uint32)-1); + return num; +} + +static int +runCreateIndex(NDBT_Context* ctx, NDBT_Step* step) +{ + srandom(1); + NDBT_Table* pTab = ctx->getTab(); + Ndb* pNdb = GETNDB(step); + unsigned numTabAttrs = pTab->getNumAttributes(); + unsigned numIndex = 0; + while (numIndex < MaxIndexes) { + if (numIndex != 0 && urandom(10) == 0) + break; + char buf[200]; + sprintf(buf, "%s_X%03d", pTab->getName(), numIndex); + NDBT_Index* pInd = new NDBT_Index(buf); + pInd->setTable(pTab->getName()); + pInd->setType(NdbDictionary::Index::OrderedIndex); + pInd->setLogging(false); + unsigned numAttrs = 0; + while (numAttrs < MaxIndexAttrs) { + if (numAttrs != 0 && urandom(5) == 0) + break; + unsigned i = urandom(numTabAttrs); + const NDBT_Attribute* pAttr = pTab->getAttribute(i); + bool found = false; + for (unsigned j = 0; j < numAttrs; j++) { + if (strcmp(pAttr->getName(), pInd->getAttribute(j)->getName()) == 0) { + found = true; + break; + } + } + if (found) + continue; + pInd->addAttribute(*pAttr); + numAttrs++; + } + g_info << "Create index:" << endl << *pInd; + if (pInd->createIndexInDb(pNdb, false) != 0) + continue; + numIndex++; + } + setTableProperty(ctx, pTab, "numIndex", numIndex); + g_info << "Created " << numIndex << " indexes on " << pTab->getName() << endl; + return NDBT_OK; +} + +static int +runInsertUpdate(NDBT_Context* ctx, NDBT_Step* step) +{ + NDBT_Table* pTab = ctx->getTab(); + Ndb* pNdb = GETNDB(step); + int ret; + g_info << "Insert: " << pTab->getName() << endl; + HugoTransactions hugoTrans(*pTab); + ret = hugoTrans.loadTable(pNdb, ctx->getNumRecords(), 100); + if (ret != 0) { + g_err << "ERR: " << step->getName() << "failed" << endl; + return NDBT_FAILED; + } + return NDBT_OK; +} + +static int +runFullScan(NDBT_Context* ctx, NDBT_Step* step) +{ + NDBT_Table* pTab = ctx->getTab(); + Ndb* pNdb = GETNDB(step); + unsigned cntIndex = getTableProperty(ctx, pTab, "numIndex"); + for (unsigned numIndex = 0; numIndex < cntIndex; numIndex++) { + char buf[200]; + sprintf(buf, "%s_X%03d", pTab->getName(), numIndex); + NDBT_Index* pInd = NDBT_Index::discoverIndexFromDb(pNdb, buf, pTab->getName()); + assert(pInd != 0); + g_info << "Scan index:" << pInd->getName() << endl << *pInd; + NdbConnection* pCon = pNdb->startTransaction(); + if (pCon == 0) { + ERR(pNdb->getNdbError()); + return NDBT_FAILED; + } + NdbOperation* pOp = pCon->getNdbOperation(pInd->getName(), + pTab->getName()); + if (pOp == 0) { + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + return NDBT_FAILED; + } + if (pOp->openScanRead() != 0) { + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + return NDBT_FAILED; + } + if (pCon->executeScan() != 0) { + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + return NDBT_FAILED; + } + unsigned rows = 0; + while (1) { + int ret = pCon->nextScanResult(); + if (ret == 0) { + rows++; + } else if (ret == 1) { + break; + } else { + ERR(pCon->getNdbError()); + pNdb->closeTransaction(pCon); + return NDBT_FAILED; + } + } + pNdb->closeTransaction(pCon); + g_info << "Scanned " << rows << " rows" << endl; + } + return NDBT_OK; +} + +NDBT_TESTSUITE(testOrderedIndex); +TESTCASE( + "DropIndex", + "Drop any old indexes") { + INITIALIZER(runDropIndex); +} +TESTCASE( + "CreateIndex", + "Create ordered indexes") { + INITIALIZER(runCreateIndex); +} +TESTCASE( + "InsertUpdate", + "Run inserts and updates") { + INITIALIZER(runInsertUpdate); +} +TESTCASE( + "FullScan", + "Full scan on each ordered index") { + INITIALIZER(runFullScan); +} +NDBT_TESTSUITE_END(testOrderedIndex); + +int +main(int argc, const char** argv) +{ + return testOrderedIndex.execute(argc, argv); +} + +// vim: set sw=2: diff --git a/ndb/test/ndbapi/testOrderedIndex/Makefile b/ndb/test/ndbapi/testOrderedIndex/Makefile deleted file mode 100644 index d8899a37895..00000000000 --- a/ndb/test/ndbapi/testOrderedIndex/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include .defs.mk - -TYPE = ndbapitest - -BIN_TARGET = testOrderedIndex - -SOURCES = testOrderedIndex.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/testOrderedIndex/testOrderedIndex.cpp b/ndb/test/ndbapi/testOrderedIndex/testOrderedIndex.cpp deleted file mode 100644 index 51cc53c9975..00000000000 --- a/ndb/test/ndbapi/testOrderedIndex/testOrderedIndex.cpp +++ /dev/null @@ -1,224 +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 */ - -#include -#include -#include -#include -#include -#include -#include - -const unsigned MaxTableAttrs = NDB_MAX_ATTRIBUTES_IN_TABLE; -const unsigned MaxIndexAttrs = NDB_MAX_ATTRIBUTES_IN_INDEX; -const unsigned MaxIndexes = 20; - -static unsigned -urandom(unsigned n) -{ - unsigned i = random(); - return i % n; -} - -static int -runDropIndex(NDBT_Context* ctx, NDBT_Step* step) -{ - const NdbDictionary::Table* pTab = ctx->getTab(); - Ndb* pNdb = GETNDB(step); - NdbDictionary::Dictionary* pDic = pNdb->getDictionary(); - NdbDictionary::Dictionary::List list; - if (pDic->listIndexes(list, pTab->getName()) != 0) { - g_err << pTab->getName() << ": listIndexes failed" << endl; - ERR(pDic->getNdbError()); - return NDBT_FAILED; - } - for (unsigned i = 0; i < list.count; i++) { - NDBT_Index* pInd = new NDBT_Index(list.elements[i].name); - pInd->setTable(pTab->getName()); - g_info << "Drop index:" << endl << *pInd; - if (pInd->dropIndexInDb(pNdb) != 0) { - return NDBT_FAILED; - } - } - return NDBT_OK; -} - -static Uint32 workaround[1000]; - -static void -setTableProperty(NDBT_Context* ctx, NDBT_Table* pTab, const char* name, Uint32 num) -{ - char key[200]; - sprintf(key, "%s-%s", name, pTab->getName()); - //ctx->setProperty(key, num); - workaround[pTab->getTableId()] = num; -} - -static Uint32 -getTableProperty(NDBT_Context* ctx, NDBT_Table* pTab, const char* name) -{ - char key[200]; - sprintf(key, "%s-%s", name, pTab->getName()); - //Uint32 num = ctx->getProperty(key, (Uint32)-1); - Uint32 num = workaround[pTab->getTableId()]; - assert(num != (Uint32)-1); - return num; -} - -static int -runCreateIndex(NDBT_Context* ctx, NDBT_Step* step) -{ - srandom(1); - NDBT_Table* pTab = ctx->getTab(); - Ndb* pNdb = GETNDB(step); - unsigned numTabAttrs = pTab->getNumAttributes(); - unsigned numIndex = 0; - while (numIndex < MaxIndexes) { - if (numIndex != 0 && urandom(10) == 0) - break; - char buf[200]; - sprintf(buf, "%s_X%03d", pTab->getName(), numIndex); - NDBT_Index* pInd = new NDBT_Index(buf); - pInd->setTable(pTab->getName()); - pInd->setType(NdbDictionary::Index::OrderedIndex); - pInd->setLogging(false); - unsigned numAttrs = 0; - while (numAttrs < MaxIndexAttrs) { - if (numAttrs != 0 && urandom(5) == 0) - break; - unsigned i = urandom(numTabAttrs); - const NDBT_Attribute* pAttr = pTab->getAttribute(i); - bool found = false; - for (unsigned j = 0; j < numAttrs; j++) { - if (strcmp(pAttr->getName(), pInd->getAttribute(j)->getName()) == 0) { - found = true; - break; - } - } - if (found) - continue; - pInd->addAttribute(*pAttr); - numAttrs++; - } - g_info << "Create index:" << endl << *pInd; - if (pInd->createIndexInDb(pNdb, false) != 0) - continue; - numIndex++; - } - setTableProperty(ctx, pTab, "numIndex", numIndex); - g_info << "Created " << numIndex << " indexes on " << pTab->getName() << endl; - return NDBT_OK; -} - -static int -runInsertUpdate(NDBT_Context* ctx, NDBT_Step* step) -{ - NDBT_Table* pTab = ctx->getTab(); - Ndb* pNdb = GETNDB(step); - int ret; - g_info << "Insert: " << pTab->getName() << endl; - HugoTransactions hugoTrans(*pTab); - ret = hugoTrans.loadTable(pNdb, ctx->getNumRecords(), 100); - if (ret != 0) { - g_err << "ERR: " << step->getName() << "failed" << endl; - return NDBT_FAILED; - } - return NDBT_OK; -} - -static int -runFullScan(NDBT_Context* ctx, NDBT_Step* step) -{ - NDBT_Table* pTab = ctx->getTab(); - Ndb* pNdb = GETNDB(step); - unsigned cntIndex = getTableProperty(ctx, pTab, "numIndex"); - for (unsigned numIndex = 0; numIndex < cntIndex; numIndex++) { - char buf[200]; - sprintf(buf, "%s_X%03d", pTab->getName(), numIndex); - NDBT_Index* pInd = NDBT_Index::discoverIndexFromDb(pNdb, buf, pTab->getName()); - assert(pInd != 0); - g_info << "Scan index:" << pInd->getName() << endl << *pInd; - NdbConnection* pCon = pNdb->startTransaction(); - if (pCon == 0) { - ERR(pNdb->getNdbError()); - return NDBT_FAILED; - } - NdbOperation* pOp = pCon->getNdbOperation(pInd->getName(), - pTab->getName()); - if (pOp == 0) { - ERR(pCon->getNdbError()); - pNdb->closeTransaction(pCon); - return NDBT_FAILED; - } - if (pOp->openScanRead() != 0) { - ERR(pCon->getNdbError()); - pNdb->closeTransaction(pCon); - return NDBT_FAILED; - } - if (pCon->executeScan() != 0) { - ERR(pCon->getNdbError()); - pNdb->closeTransaction(pCon); - return NDBT_FAILED; - } - unsigned rows = 0; - while (1) { - int ret = pCon->nextScanResult(); - if (ret == 0) { - rows++; - } else if (ret == 1) { - break; - } else { - ERR(pCon->getNdbError()); - pNdb->closeTransaction(pCon); - return NDBT_FAILED; - } - } - pNdb->closeTransaction(pCon); - g_info << "Scanned " << rows << " rows" << endl; - } - return NDBT_OK; -} - -NDBT_TESTSUITE(testOrderedIndex); -TESTCASE( - "DropIndex", - "Drop any old indexes") { - INITIALIZER(runDropIndex); -} -TESTCASE( - "CreateIndex", - "Create ordered indexes") { - INITIALIZER(runCreateIndex); -} -TESTCASE( - "InsertUpdate", - "Run inserts and updates") { - INITIALIZER(runInsertUpdate); -} -TESTCASE( - "FullScan", - "Full scan on each ordered index") { - INITIALIZER(runFullScan); -} -NDBT_TESTSUITE_END(testOrderedIndex); - -int -main(int argc, const char** argv) -{ - return testOrderedIndex.execute(argc, argv); -} - -// vim: set sw=2: diff --git a/ndb/test/ndbapi/testRestartGci.cpp b/ndb/test/ndbapi/testRestartGci.cpp new file mode 100644 index 00000000000..1e36368ba62 --- /dev/null +++ b/ndb/test/ndbapi/testRestartGci.cpp @@ -0,0 +1,218 @@ +/* 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 */ + +#include "NDBT_Test.hpp" +#include "NDBT_ReturnCodes.h" +#include "HugoTransactions.hpp" +#include "UtilTransactions.hpp" +#include "NdbRestarter.hpp" + + +/** + * Global vector to keep track of + * records stored in db + */ + +struct SavedRecord { + int m_gci; + BaseString m_str; + SavedRecord(int _gci, BaseString _str){ + m_gci = _gci; + m_str.assign(_str); + } + SavedRecord(){ + m_gci = 0; + m_str = ""; + }; +}; +Vector savedRecords; + + +#define CHECK(b) if (!(b)) { \ + ndbout << "ERR: "<< step->getName() \ + << " failed on line " << __LINE__ << endl; \ + result = NDBT_FAILED; \ + break; } + +int runInsertRememberGci(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int records = ctx->getNumRecords(); + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + int i = 0; + + while(ctx->isTestStopped() == false && i < records){ + // Insert record and read it in same transaction + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkInsertRecord(pNdb, i) == 0); + if (hugoOps.execute_NoCommit(pNdb) != 0){ + ndbout << "Could not insert record " << i << endl; + result = NDBT_FAILED; + break; + } + CHECK(hugoOps.pkReadRecord(pNdb, i, false) == 0); + if (hugoOps.execute_Commit(pNdb) != 0){ + ndbout << "Did not find record in DB " << i << endl; + result = NDBT_FAILED; + break; + } + savedRecords.push_back(SavedRecord(hugoOps.getRecordGci(0), + hugoOps.getRecordStr(0))); + + CHECK(hugoOps.closeTransaction(pNdb) == 0); + i++; + }; + + return result; +} + +int runRestartGciControl(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + Ndb* pNdb = GETNDB(step); + UtilTransactions utilTrans(*ctx->getTab()); + NdbRestarter restarter; + + // Wait until we have enough records in db + int count = 0; + while (count < records){ + if (utilTrans.selectCount(pNdb, 64, &count) != 0){ + ctx->stopTest(); + return NDBT_FAILED; + } + } + + // Restart cluster with abort + if (restarter.restartAll(false, false, true) != 0){ + ctx->stopTest(); + return NDBT_FAILED; + } + + // Stop the other thread + ctx->stopTest(); + + if (restarter.waitClusterStarted(300) != 0){ + return NDBT_FAILED; + } + + if (pNdb->waitUntilReady() != 0){ + return NDBT_FAILED; + } + + return NDBT_OK; +} + +int runVerifyInserts(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + Ndb* pNdb = GETNDB(step); + UtilTransactions utilTrans(*ctx->getTab()); + HugoOperations hugoOps(*ctx->getTab()); + NdbRestarter restarter; + + int restartGCI = pNdb->NdbTamper(ReadRestartGCI, 0); + + ndbout << "restartGCI = " << restartGCI << endl; + int count = 0; + if (utilTrans.selectCount(pNdb, 64, &count) != 0){ + return NDBT_FAILED; + } + + // RULE1: The vector with saved records should have exactly as many + // records with lower or same gci as there are in DB + int recordsWithLowerOrSameGci = 0; + for (unsigned i = 0; i < savedRecords.size(); i++){ + if (savedRecords[i].m_gci <= restartGCI) + recordsWithLowerOrSameGci++; + } + if (recordsWithLowerOrSameGci != count){ + ndbout << "ERR: Wrong number of expected records" << endl; + result = NDBT_FAILED; + } + + + // RULE2: The records found in db should have same or lower + // gci as in the vector + for (unsigned i = 0; i < savedRecords.size(); i++){ + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, i, false) == 0); + if (hugoOps.execute_Commit(pNdb) != 0){ + // Record was not found in db' + + // Check record gci + if (savedRecords[i].m_gci <= restartGCI){ + ndbout << "ERR: Record "< restartGCI){ + ndbout << "ERR: Record "<getNumRecords(); + + UtilTransactions utilTrans(*ctx->getTab()); + if (utilTrans.clearTable2(GETNDB(step), records, 240) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + + +NDBT_TESTSUITE(testRestartGci); +TESTCASE("InsertRestartGci", + "Verify that only expected records are still in NDB\n" + "after a restart" ){ + INITIALIZER(runClearTable); + INITIALIZER(runClearGlobals); + STEP(runInsertRememberGci); + STEP(runRestartGciControl); + VERIFIER(runVerifyInserts); + FINALIZER(runClearTable); +} +NDBT_TESTSUITE_END(testRestartGci); + +int main(int argc, const char** argv){ + return testRestartGci.execute(argc, argv); +} diff --git a/ndb/test/ndbapi/testRestartGci/Makefile b/ndb/test/ndbapi/testRestartGci/Makefile deleted file mode 100644 index 24f449b747d..00000000000 --- a/ndb/test/ndbapi/testRestartGci/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := testRestartGci - -SOURCES := testRestartGci.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/testRestartGci/testRestartGci.cpp b/ndb/test/ndbapi/testRestartGci/testRestartGci.cpp deleted file mode 100644 index 1e36368ba62..00000000000 --- a/ndb/test/ndbapi/testRestartGci/testRestartGci.cpp +++ /dev/null @@ -1,218 +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 */ - -#include "NDBT_Test.hpp" -#include "NDBT_ReturnCodes.h" -#include "HugoTransactions.hpp" -#include "UtilTransactions.hpp" -#include "NdbRestarter.hpp" - - -/** - * Global vector to keep track of - * records stored in db - */ - -struct SavedRecord { - int m_gci; - BaseString m_str; - SavedRecord(int _gci, BaseString _str){ - m_gci = _gci; - m_str.assign(_str); - } - SavedRecord(){ - m_gci = 0; - m_str = ""; - }; -}; -Vector savedRecords; - - -#define CHECK(b) if (!(b)) { \ - ndbout << "ERR: "<< step->getName() \ - << " failed on line " << __LINE__ << endl; \ - result = NDBT_FAILED; \ - break; } - -int runInsertRememberGci(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - int records = ctx->getNumRecords(); - HugoOperations hugoOps(*ctx->getTab()); - Ndb* pNdb = GETNDB(step); - int i = 0; - - while(ctx->isTestStopped() == false && i < records){ - // Insert record and read it in same transaction - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkInsertRecord(pNdb, i) == 0); - if (hugoOps.execute_NoCommit(pNdb) != 0){ - ndbout << "Could not insert record " << i << endl; - result = NDBT_FAILED; - break; - } - CHECK(hugoOps.pkReadRecord(pNdb, i, false) == 0); - if (hugoOps.execute_Commit(pNdb) != 0){ - ndbout << "Did not find record in DB " << i << endl; - result = NDBT_FAILED; - break; - } - savedRecords.push_back(SavedRecord(hugoOps.getRecordGci(0), - hugoOps.getRecordStr(0))); - - CHECK(hugoOps.closeTransaction(pNdb) == 0); - i++; - }; - - return result; -} - -int runRestartGciControl(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - Ndb* pNdb = GETNDB(step); - UtilTransactions utilTrans(*ctx->getTab()); - NdbRestarter restarter; - - // Wait until we have enough records in db - int count = 0; - while (count < records){ - if (utilTrans.selectCount(pNdb, 64, &count) != 0){ - ctx->stopTest(); - return NDBT_FAILED; - } - } - - // Restart cluster with abort - if (restarter.restartAll(false, false, true) != 0){ - ctx->stopTest(); - return NDBT_FAILED; - } - - // Stop the other thread - ctx->stopTest(); - - if (restarter.waitClusterStarted(300) != 0){ - return NDBT_FAILED; - } - - if (pNdb->waitUntilReady() != 0){ - return NDBT_FAILED; - } - - return NDBT_OK; -} - -int runVerifyInserts(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - Ndb* pNdb = GETNDB(step); - UtilTransactions utilTrans(*ctx->getTab()); - HugoOperations hugoOps(*ctx->getTab()); - NdbRestarter restarter; - - int restartGCI = pNdb->NdbTamper(ReadRestartGCI, 0); - - ndbout << "restartGCI = " << restartGCI << endl; - int count = 0; - if (utilTrans.selectCount(pNdb, 64, &count) != 0){ - return NDBT_FAILED; - } - - // RULE1: The vector with saved records should have exactly as many - // records with lower or same gci as there are in DB - int recordsWithLowerOrSameGci = 0; - for (unsigned i = 0; i < savedRecords.size(); i++){ - if (savedRecords[i].m_gci <= restartGCI) - recordsWithLowerOrSameGci++; - } - if (recordsWithLowerOrSameGci != count){ - ndbout << "ERR: Wrong number of expected records" << endl; - result = NDBT_FAILED; - } - - - // RULE2: The records found in db should have same or lower - // gci as in the vector - for (unsigned i = 0; i < savedRecords.size(); i++){ - CHECK(hugoOps.startTransaction(pNdb) == 0); - CHECK(hugoOps.pkReadRecord(pNdb, i, false) == 0); - if (hugoOps.execute_Commit(pNdb) != 0){ - // Record was not found in db' - - // Check record gci - if (savedRecords[i].m_gci <= restartGCI){ - ndbout << "ERR: Record "< restartGCI){ - ndbout << "ERR: Record "<getNumRecords(); - - UtilTransactions utilTrans(*ctx->getTab()); - if (utilTrans.clearTable2(GETNDB(step), records, 240) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - - -NDBT_TESTSUITE(testRestartGci); -TESTCASE("InsertRestartGci", - "Verify that only expected records are still in NDB\n" - "after a restart" ){ - INITIALIZER(runClearTable); - INITIALIZER(runClearGlobals); - STEP(runInsertRememberGci); - STEP(runRestartGciControl); - VERIFIER(runVerifyInserts); - FINALIZER(runClearTable); -} -NDBT_TESTSUITE_END(testRestartGci); - -int main(int argc, const char** argv){ - return testRestartGci.execute(argc, argv); -} diff --git a/ndb/test/ndbapi/testScan.cpp b/ndb/test/ndbapi/testScan.cpp new file mode 100644 index 00000000000..dbf91f016d8 --- /dev/null +++ b/ndb/test/ndbapi/testScan.cpp @@ -0,0 +1,1311 @@ +/* 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 */ + +#include +#include +#include +#include +#include +#include +#include "ScanFunctions.hpp" +#include + +const NdbDictionary::Table * +getTable(Ndb* pNdb, int i){ + const NdbDictionary::Table* t = NDBT_Tables::getTable(i); + if (t == NULL){ + return 0; + } + return pNdb->getDictionary()->getTable(t->getName()); +} + + +int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ + + int records = ctx->getNumRecords(); + HugoTransactions hugoTrans(*ctx->getTab()); + if (hugoTrans.loadTable(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + + +int runCreateAllTables(NDBT_Context* ctx, NDBT_Step* step){ + + int a = NDBT_Tables::createAllTables(GETNDB(step), false, true); + return a; +} + +int runDropAllTablesExceptTestTable(NDBT_Context* ctx, NDBT_Step* step){ + + for (int i=0; i < NDBT_Tables::getNumTables(); i++){ + + const NdbDictionary::Table* tab = NDBT_Tables::getTable(i); + if (tab == NULL){ + return NDBT_ProgramExit(NDBT_FAILED); + } + + // Don't drop test table + if (strcmp(tab->getName(), ctx->getTab()->getName()) == 0){ + continue; + } + + int res = GETNDB(step)->getDictionary()->dropTable(tab->getName()); + if(res != -1){ + return NDBT_FAILED; + } + } + return NDBT_OK; +} + + +int runLoadAllTables(NDBT_Context* ctx, NDBT_Step* step){ + + int records = ctx->getNumRecords(); + for (int i=0; i < NDBT_Tables::getNumTables(); i++){ + + const NdbDictionary::Table* tab = getTable(GETNDB(step), i); + if (tab == NULL){ + return NDBT_FAILED; + } + HugoTransactions hugoTrans(*tab); + if (hugoTrans.loadTable(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + } + return NDBT_OK; +} + +int runScanReadRandomTable(NDBT_Context* ctx, NDBT_Step* step){ + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + int parallelism = ctx->getProperty("Parallelism", 240); + int abort = ctx->getProperty("AbortProb"); + + int i = 0; + while (igetName() << endl; + HugoTransactions hugoTrans(*tab); + + g_info << i << ": "; + if (hugoTrans.scanReadRecords(GETNDB(step), records, abort, parallelism) != 0){ + return NDBT_FAILED; + } + i++; + } + return NDBT_OK; +} + +int runInsertUntilStopped(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + int i = 0; + HugoTransactions hugoTrans(*ctx->getTab()); + while (ctx->isTestStopped() == false) { + g_info << i << ": "; + if (hugoTrans.loadTable(GETNDB(step), records, 1) != 0){ + return NDBT_FAILED; + } + i++; + } + return NDBT_OK; +} + +int runInsertDelete(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int records = ctx->getNumRecords(); + int loops = ctx->getNumLoops(); + int i = 0; + HugoTransactions hugoTrans(*ctx->getTab()); + UtilTransactions utilTrans(*ctx->getTab()); + while (istopTest(); + + return result; +} + +int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + + UtilTransactions utilTrans(*ctx->getTab()); + if (utilTrans.clearTable2(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runScanDelete(NDBT_Context* ctx, NDBT_Step* step){ + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + + int i = 0; + UtilTransactions utilTrans(*ctx->getTab()); + HugoTransactions hugoTrans(*ctx->getTab()); + while (igetNumLoops(); + int records = ctx->getNumRecords(); + + int i = 0; + UtilTransactions utilTrans(*ctx->getTab()); + HugoTransactions hugoTrans(*ctx->getTab()); + + while (igetNumLoops(); + int records = ctx->getNumRecords(); + int parallelism = ctx->getProperty("Parallelism", 240); + int abort = ctx->getProperty("AbortProb"); + + int i = 0; + HugoTransactions hugoTrans(*ctx->getTab()); + while (iisTestStopped()) { + g_info << i << ": "; + if (hugoTrans.scanReadRecords(GETNDB(step), records, abort, parallelism) != 0){ + return NDBT_FAILED; + } + i++; + } + return NDBT_OK; +} + +int runScanReadCommitted(NDBT_Context* ctx, NDBT_Step* step){ + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + int parallelism = ctx->getProperty("Parallelism", 240); + int abort = ctx->getProperty("AbortProb"); + + int i = 0; + HugoTransactions hugoTrans(*ctx->getTab()); + while (iisTestStopped()) { + g_info << i << ": "; + if (hugoTrans.scanReadCommittedRecords(GETNDB(step), records, + abort, parallelism) != 0){ + return NDBT_FAILED; + } + i++; + } + return NDBT_OK; +} + +int runScanReadError(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + int parallelism = 240; // Max parallelism + int error = ctx->getProperty("ErrorCode"); + NdbRestarter restarter; + + int i = 0; + HugoTransactions hugoTrans(*ctx->getTab()); + while (iisTestStopped()) { + g_info << i << ": "; + + ndbout << "insertErrorInAllNodes("<getNumLoops(); + int records = ctx->getNumRecords(); + int parallelism = 240; // Max parallelism + int error = ctx->getProperty("ErrorCode"); + NdbRestarter restarter; + int lastId = 0; + + if (restarter.getNumDbNodes() < 2){ + ctx->stopTest(); + return NDBT_OK; + } + + int i = 0; + HugoTransactions hugoTrans(*ctx->getTab()); + while (igetNumRecords(); + int i = 0; + + int parallelism = ctx->getProperty("Parallelism", 240); + int para = parallelism; + + HugoTransactions hugoTrans(*ctx->getTab()); + while (ctx->isTestStopped() == false) { + if (parallelism == RANDOM_PARALLELISM) + para = myRandom48(239)+1; + + g_info << i << ": "; + if (hugoTrans.scanReadRecords(GETNDB(step), records, 0, para) != 0){ + return NDBT_FAILED; + } + i++; + } + return NDBT_OK; +} + +int runScanReadUntilStoppedNoCount(NDBT_Context* ctx, NDBT_Step* step){ + int i = 0; + HugoTransactions hugoTrans(*ctx->getTab()); + while (ctx->isTestStopped() == false) { + g_info << i << ": "; + if (hugoTrans.scanReadRecords(GETNDB(step), 0) != 0){ + return NDBT_FAILED; + } + i++; + } + return NDBT_OK; +} + + +int runPkRead(NDBT_Context* ctx, NDBT_Step* step){ + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + int i = 0; + HugoTransactions hugoTrans(*ctx->getTab()); + while (igetNumLoops(); + int records = ctx->getNumRecords(); + int parallelism = ctx->getProperty("Parallelism", 1); + int abort = ctx->getProperty("AbortProb"); + int i = 0; + HugoTransactions hugoTrans(*ctx->getTab()); + while (igetNumRecords(); + int i = 0; + + int parallelism = ctx->getProperty("Parallelism", 240); + int para = parallelism; + + HugoTransactions hugoTrans(*ctx->getTab()); + while (ctx->isTestStopped() == false) { + if (parallelism == RANDOM_PARALLELISM) + para = myRandom48(239)+1; + + g_info << i << ": "; + if (hugoTrans.scanUpdateRecords(GETNDB(step), records, 0, para) == NDBT_FAILED){ + return NDBT_FAILED; + } + i++; + } + return NDBT_OK; +} + + +int runScanUpdate2(NDBT_Context* ctx, NDBT_Step* step){ + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + int parallelism = ctx->getProperty("Parallelism", 240); + int abort = ctx->getProperty("AbortProb"); + int i = 0; + HugoTransactions hugoTrans(*ctx->getTab()); + while (igetNumRecords(); + HugoTransactions hugoTrans(*ctx->getTab()); + + if (hugoTrans.lockRecords(GETNDB(step), records, 5, 500) != 0){ + result = NDBT_FAILED; + } + ctx->stopTest(); + + return result; +} + +int runRestarter(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int loops = ctx->getNumLoops(); + NdbRestarter restarter; + int i = 0; + int lastId = 0; + int timeout = 240; + + if (restarter.getNumDbNodes() < 2){ + ctx->stopTest(); + return NDBT_OK; + } + while(istopTest(); + + return result; +} + +int runRestarter9999(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int loops = ctx->getNumLoops(); + NdbRestarter restarter; + int i = 0; + int lastId = 0; + + if (restarter.getNumDbNodes() < 2){ + ctx->stopTest(); + return NDBT_OK; + } + while(istopTest(); + + return result; +} + + +int runCheckGetValue(NDBT_Context* ctx, NDBT_Step* step){ + const NdbDictionary::Table* pTab = ctx->getTab(); + int parallelism = ctx->getProperty("Parallelism", 1); + int records = ctx->getNumRecords(); + int numFailed = 0; + AttribList alist; + alist.buildAttribList(pTab); + UtilTransactions utilTrans(*pTab); + for(size_t i = 0; i < alist.attriblist.size(); i++){ + g_info << (unsigned)i << endl; + if(utilTrans.scanReadRecords(GETNDB(step), + parallelism, + false, + records, + alist.attriblist[i]->numAttribs, + alist.attriblist[i]->attribs) != 0){ + numFailed++; + } + if(utilTrans.scanReadRecords(GETNDB(step), + parallelism, + true, + records, + alist.attriblist[i]->numAttribs, + alist.attriblist[i]->attribs) != 0){ + numFailed++; + } + } + + if(numFailed > 0) + return NDBT_FAILED; + else + return NDBT_OK; +} + +int runCloseWithoutStop(NDBT_Context* ctx, NDBT_Step* step){ + const NdbDictionary::Table* pTab = ctx->getTab(); + int records = ctx->getNumRecords(); + int numFailed = 0; + ScanFunctions scanF(*pTab); + // Iterate over all possible parallelism valuse + for (int p = 1; p<240; p++){ + g_info << p << " CloseWithoutStop openScan" << endl; + if (scanF.scanReadFunctions(GETNDB(step), + records, + p, + ScanFunctions::CloseWithoutStop, + false) != 0){ + numFailed++; + } + g_info << p << " CloseWithoutStop openScanExclusive" << endl; + if (scanF.scanReadFunctions(GETNDB(step), + records, + p, + ScanFunctions::CloseWithoutStop, + true) != 0){ + numFailed++; + } + } + + if(numFailed > 0) + return NDBT_FAILED; + else + return NDBT_OK; +} + +int runNextScanWhenNoMore(NDBT_Context* ctx, NDBT_Step* step){ + const NdbDictionary::Table* pTab = ctx->getTab(); + int records = ctx->getNumRecords(); + int numFailed = 0; + ScanFunctions scanF(*pTab); + if (scanF.scanReadFunctions(GETNDB(step), + records, + 6, + ScanFunctions::NextScanWhenNoMore, + false) != 0){ + numFailed++; + } + if (scanF.scanReadFunctions(GETNDB(step), + records, + 6, + ScanFunctions::NextScanWhenNoMore, + true) != 0){ + numFailed++; + } + + + if(numFailed > 0) + return NDBT_FAILED; + else + return NDBT_OK; +} + +int runEqualAfterOpenScan(NDBT_Context* ctx, NDBT_Step* step){ + const NdbDictionary::Table* pTab = ctx->getTab(); + int records = ctx->getNumRecords(); + int numFailed = 0; + ScanFunctions scanF(*pTab); + if (scanF.scanReadFunctions(GETNDB(step), + records, + 6, + ScanFunctions::EqualAfterOpenScan, + false) == NDBT_OK){ + numFailed++; + } + if (scanF.scanReadFunctions(GETNDB(step), + records, + 6, + ScanFunctions::EqualAfterOpenScan, + true) == NDBT_OK){ + numFailed++; + } + + + if(numFailed > 0) + return NDBT_FAILED; + else + return NDBT_OK; +} + +int runOnlyOpenScanOnce(NDBT_Context* ctx, NDBT_Step* step){ + const NdbDictionary::Table* pTab = ctx->getTab(); + int records = ctx->getNumRecords(); + int numFailed = 0; + ScanFunctions scanF(*pTab); + g_info << "OnlyOpenScanOnce openScanRead" << endl; + if (scanF.scanReadFunctions(GETNDB(step), + records, + 6, + ScanFunctions::OnlyOpenScanOnce, + false) == 0){ + numFailed++; + } + g_info << "OnlyOpenScanOnce openScanExclusive" << endl; + if (scanF.scanReadFunctions(GETNDB(step), + records, + 6, + ScanFunctions::OnlyOpenScanOnce, + true) == 0){ + numFailed++; + } + + + if(numFailed > 0) + return NDBT_FAILED; + else + return NDBT_OK; +} + +int runOnlyOneOpInScanTrans(NDBT_Context* ctx, NDBT_Step* step){ + const NdbDictionary::Table* pTab = ctx->getTab(); + int records = ctx->getNumRecords(); + int numFailed = 0; + + ScanFunctions scanF(*pTab); + if (scanF.scanReadFunctions(GETNDB(step), + records, + 6, + ScanFunctions::OnlyOneOpInScanTrans, + false) == 0){ + numFailed++; + } + if (scanF.scanReadFunctions(GETNDB(step), + records, + 6, + ScanFunctions::OnlyOneOpInScanTrans, + true) == 0){ + numFailed++; + } + + + if(numFailed > 0) + return NDBT_FAILED; + else + return NDBT_OK; + +} + +int runExecuteScanWithoutOpenScan(NDBT_Context* ctx, NDBT_Step* step){ + const NdbDictionary::Table* pTab = ctx->getTab(); + int records = ctx->getNumRecords(); + int numFailed = 0; + ScanFunctions scanF(*pTab); + if (scanF.scanReadFunctions(GETNDB(step), + records, + 1, + ScanFunctions::ExecuteScanWithOutOpenScan, + false) == 0){ + numFailed++; + } + + if(numFailed > 0) + return NDBT_FAILED; + else + return NDBT_OK; +} + + + +int runOnlyOneOpBeforeOpenScan(NDBT_Context* ctx, NDBT_Step* step){ + const NdbDictionary::Table* pTab = ctx->getTab(); + int records = ctx->getNumRecords(); + int numFailed = 0; + + ScanFunctions scanF(*pTab); + if (scanF.scanReadFunctions(GETNDB(step), + records, + 6, + ScanFunctions::OnlyOneOpBeforeOpenScan, + false) == 0){ + numFailed++; + } + if (scanF.scanReadFunctions(GETNDB(step), + records, + 6, + ScanFunctions::OnlyOneOpBeforeOpenScan, + true) == 0){ + numFailed++; + } + + if(numFailed > 0) + return NDBT_FAILED; + else + return NDBT_OK; + +} +int runOnlyOneScanPerTrans(NDBT_Context* ctx, NDBT_Step* step){ + const NdbDictionary::Table* pTab = ctx->getTab(); + int records = ctx->getNumRecords(); + int numFailed = 0; + + ScanFunctions scanF(*pTab); + if (scanF.scanReadFunctions(GETNDB(step), + records, + 6, + ScanFunctions::OnlyOneScanPerTrans, + false) == 0){ + numFailed++; + } + if (scanF.scanReadFunctions(GETNDB(step), + records, + 6, + ScanFunctions::OnlyOneScanPerTrans, + true) == 0){ + numFailed++; + } + + if(numFailed > 0) + return NDBT_FAILED; + else + return NDBT_OK; + +} + +int runNoCloseTransaction(NDBT_Context* ctx, NDBT_Step* step){ + const NdbDictionary::Table* pTab = ctx->getTab(); + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + int numFailed = 0; + + ScanFunctions scanF(*pTab); + int l = 0; + while(l < loops){ + if (scanF.scanReadFunctions(GETNDB(step), + records, + 6, + ScanFunctions::NoCloseTransaction, + false) != 0){ + numFailed++; + } + if (scanF.scanReadFunctions(GETNDB(step), + records, + 6, + ScanFunctions::NoCloseTransaction, + true) != 0){ + numFailed++; + } + l++; + } + + + if(numFailed > 0) + return NDBT_FAILED; + else + return NDBT_OK; + +} + +int runCheckInactivityTimeOut(NDBT_Context* ctx, NDBT_Step* step){ + const NdbDictionary::Table* pTab = ctx->getTab(); + int records = ctx->getNumRecords(); + int numFailed = 0; + + ScanFunctions scanF(*pTab); + if (scanF.scanReadFunctions(GETNDB(step), + records, + 1, + ScanFunctions::CheckInactivityTimeOut, + false) != NDBT_OK){ + numFailed++; + } + if (scanF.scanReadFunctions(GETNDB(step), + records, + 240, + ScanFunctions::CheckInactivityTimeOut, + true) != NDBT_OK){ + numFailed++; + } + + if(numFailed > 0) + return NDBT_FAILED; + else + return NDBT_OK; + +} + +int runCheckInactivityBeforeClose(NDBT_Context* ctx, NDBT_Step* step){ + const NdbDictionary::Table* pTab = ctx->getTab(); + int records = ctx->getNumRecords(); + int numFailed = 0; + + ScanFunctions scanF(*pTab); + if (scanF.scanReadFunctions(GETNDB(step), + records, + 16, + ScanFunctions::CheckInactivityBeforeClose, + false) != 0){ + numFailed++; + } + if (scanF.scanReadFunctions(GETNDB(step), + records, + 240, + ScanFunctions::CheckInactivityBeforeClose, + true) != 0){ + numFailed++; + } + + if(numFailed > 0) + return NDBT_FAILED; + else + return NDBT_OK; + +} + + + +NDBT_TESTSUITE(testScan); +TESTCASE("ScanRead", + "Verify scan requirement: It should be possible "\ + "to read all records in a table without knowing their "\ + "primary key."){ + INITIALIZER(runLoadTable); + TC_PROPERTY("Parallelism", 1); + STEP(runScanRead); + FINALIZER(runClearTable); +} +TESTCASE("ScanRead16", + "Verify scan requirement: It should be possible to scan read "\ + "with parallelism, test with parallelism 16"){ + INITIALIZER(runLoadTable); + TC_PROPERTY("Parallelism", 16); + STEP(runScanRead); + FINALIZER(runClearTable); +} +TESTCASE("ScanRead240", + "Verify scan requirement: It should be possible to scan read with "\ + "parallelism, test with parallelism 240(240 would automatically be "\ + "downgraded to the maximum parallelism value for the current config)"){ + INITIALIZER(runLoadTable); + TC_PROPERTY("Parallelism", 240); + STEP(runScanRead); + FINALIZER(runClearTable); +} +TESTCASE("ScanReadCommitted240", + "Verify scan requirement: It should be possible to scan read committed with "\ + "parallelism, test with parallelism 240(240 would automatically be "\ + "downgraded to the maximum parallelism value for the current config)"){ + INITIALIZER(runLoadTable); + TC_PROPERTY("Parallelism", 240); + STEP(runScanReadCommitted); + FINALIZER(runClearTable); +} +TESTCASE("ScanUpdate", + "Verify scan requirement: It should be possible "\ + "to update all records in a table without knowing their"\ + " primary key."){ + INITIALIZER(runLoadTable); + STEP(runScanUpdate); + FINALIZER(runClearTable); +} +TESTCASE("ScanUpdate2", + "Verify scan requirement: It should be possible "\ + "to update all records in a table without knowing their"\ + " primary key. Do this efficently by calling nextScanResult(false) "\ + "in order to update the records already fetched to the api in one batch."){ + INITIALIZER(runLoadTable); + TC_PROPERTY("Parallelism", 240); + STEP(runScanUpdate2); + FINALIZER(runClearTable); +} +TESTCASE("ScanDelete", + "Verify scan requirement: It should be possible "\ + "to delete all records in a table without knowing their"\ + " primary key."){ + INITIALIZER(runLoadTable); + STEP(runScanDelete); + FINALIZER(runClearTable); +} +TESTCASE("ScanDelete2", + "Verify scan requirement: It should be possible "\ + "to delete all records in a table without knowing their"\ + " primary key. Do this efficently by calling nextScanResult(false) "\ + "in order to delete the records already fetched to the api in one batch."){ + INITIALIZER(runLoadTable); + TC_PROPERTY("Parallelism", 240); + STEP(runScanDelete2); + FINALIZER(runClearTable); +} +TESTCASE("ScanUpdateAndScanRead", + "Verify scan requirement: It should be possible to run "\ + "scan read and scan update at the same time"){ + INITIALIZER(runLoadTable); + TC_PROPERTY("Parallelism", 16); + STEP(runScanRead); + STEP(runScanUpdate); + FINALIZER(runClearTable); +} +TESTCASE("ScanReadAndLocker", + "Verify scan requirement: The locks are not kept throughout "\ + "the entire scan operation. This means that a scan does not "\ + "lock the entire table, only the records it's currently "\ + "operating on. This will test how scan performs when there are "\ + " a number of 1 second locks in the table"){ + INITIALIZER(runLoadTable); + STEP(runScanReadUntilStopped); + STEP(runLocker); + FINALIZER(runClearTable); +} +TESTCASE("ScanReadAndPkRead", + "Verify scan requirement: The locks are not kept throughout "\ + "the entire scan operation. This means that a scan does not "\ + "lock the entire table, only the records it's currently "\ + "operating on. This will test how scan performs when there are "\ + " a pk reads "){ + INITIALIZER(runLoadTable); + STEPS(runScanRead, 2); + STEPS(runPkRead, 2); + FINALIZER(runClearTable); +} +TESTCASE("ScanRead488", + "Verify scan requirement: It's only possible to have 11 concurrent "\ + "scans per fragment running in Ndb kernel at the same time. "\ + "When this limit is exceeded the scan will be aborted with errorcode "\ + "488."){ + INITIALIZER(runLoadTable); + STEPS(runScanRead, 70); + FINALIZER(runClearTable); +} +TESTCASE("ScanRead488Timeout", + ""){ + INITIALIZER(runLoadTable); + TC_PROPERTY("ErrorCode", 5034); + STEPS(runScanRead, 30); + STEP(runScanReadError); + FINALIZER(runClearTable); +} +TESTCASE("ScanRead40", + "Verify scan requirement: Scan with 40 simultaneous threads"){ + INITIALIZER(runLoadTable); + STEPS(runScanRead, 40); + FINALIZER(runClearTable); +} +TESTCASE("ScanRead100", + "Verify scan requirement: Scan with 100 simultaneous threads"){ + INITIALIZER(runLoadTable); + STEPS(runScanRead, 100); + FINALIZER(runClearTable); +} +TESTCASE("ScanRead40RandomTable", + "Verify scan requirement: Scan with 40 simultaneous threads. "\ + "Use random table for the scan"){ + INITIALIZER(runCreateAllTables); + INITIALIZER(runLoadAllTables); + STEPS(runScanReadRandomTable, 40); + FINALIZER(runDropAllTablesExceptTestTable); +} +TESTCASE("ScanRead100RandomTable", + "Verify scan requirement: Scan with 100 simultaneous threads. "\ + "Use random table for the scan"){ + INITIALIZER(runCreateAllTables); + INITIALIZER(runLoadAllTables); + STEPS(runScanReadRandomTable, 100); + FINALIZER(runDropAllTablesExceptTestTable); +} +TESTCASE("ScanReadRandomPrepare", + "Create and load tables for ScanRead40RandomNoTableCreate."){ + INITIALIZER(runCreateAllTables); + INITIALIZER(runLoadAllTables); +} +TESTCASE("ScanRead40RandomNoTableCreate", + "Verify scan requirement: Scan with 40 simultaneous threads. "\ + "Use random table for the scan. Dont create or load the tables."){ + STEPS(runScanReadRandomTable, 40); +} +TESTCASE("ScanRead100RandomNoTableCreate", + "Verify scan requirement: Scan with 100 simultaneous threads. "\ + "Use random table for the scan. Dont create or load the tables."){ + STEPS(runScanReadRandomTable, 100); +} +TESTCASE("ScanWithLocksAndInserts", + "TR457: This test is added to verify that an insert of a records "\ + "that is already in the database does not delete the record"){ + INITIALIZER(runLoadTable); + STEPS(runScanReadUntilStopped, 2); + STEP(runLocker); + STEP(runInsertUntilStopped); + FINALIZER(runClearTable); +} +TESTCASE("ScanReadAbort", + "Scan requirement: A scan may be aborted by the application "\ + "at any time. This can be performed even if there are more "\ + "tuples to scan."){ + INITIALIZER(runLoadTable); + TC_PROPERTY("AbortProb", 90); + STEPS(runScanRead, 3); + FINALIZER(runClearTable); +} +TESTCASE("ScanReadAbort15", + "Scan requirement: A scan may be aborted by the application "\ + "at any time. This can be performed even if there are more "\ + "tuples to scan. Use parallelism 15"){ + INITIALIZER(runLoadTable); + TC_PROPERTY("Parallelism", 15); + TC_PROPERTY("AbortProb", 90); + STEPS(runScanRead, 3); + FINALIZER(runClearTable); +} +TESTCASE("ScanReadAbort240", + "Scan requirement: A scan may be aborted by the application "\ + "at any time. This can be performed even if there are more "\ + "tuples to scan. Use parallelism 240(it will be downgraded to max para for this config)"){ + INITIALIZER(runLoadTable); + TC_PROPERTY("Parallelism", 240); + TC_PROPERTY("AbortProb", 90); + STEPS(runScanRead, 3); + FINALIZER(runClearTable); +} +TESTCASE("ScanUpdateAbort16", + "Scan requirement: A scan may be aborted by the application "\ + "at any time. This can be performed even if there are more "\ + "tuples to scan. Use parallelism 16"){ + INITIALIZER(runLoadTable); + TC_PROPERTY("Parallelism", 16); + TC_PROPERTY("AbortProb", 90); + STEPS(runScanUpdate, 3); + FINALIZER(runClearTable); +} +TESTCASE("ScanUpdateAbort240", + "Scan requirement: A scan may be aborted by the application "\ + "at any time. This can be performed even if there are more "\ + "tuples to scan. Use parallelism 240(it will be downgraded to max para for this config)"){ + INITIALIZER(runLoadTable); + TC_PROPERTY("Parallelism", 240); + TC_PROPERTY("AbortProb", 90); + STEPS(runScanUpdate, 3); + FINALIZER(runClearTable); +} +TESTCASE("CheckGetValue", + "Check that we can call getValue to read attributes"\ + "Especially interesting to see if we can read only the"\ + " first, last or any two attributes from the table"){ + INITIALIZER(runLoadTable); + STEP(runCheckGetValue); + VERIFIER(runScanRead); + FINALIZER(runClearTable); +} +TESTCASE("CloseWithoutStop", + "Check that we can close the scanning transaction without calling "\ + "stopScan"){ + INITIALIZER(runLoadTable); + STEP(runCloseWithoutStop); + VERIFIER(runScanRead); + FINALIZER(runClearTable); +} +TESTCASE("NextScanWhenNoMore", + "Check that we can call nextScanResult when there are no more "\ + "records, and that it returns a valid value"){ + INITIALIZER(runLoadTable); + STEP(runNextScanWhenNoMore); + VERIFIER(runScanRead); + FINALIZER(runClearTable); +} +TESTCASE("EqualAfterOpenScan", + "Check that we can't call equal after openScan"){ + STEP(runEqualAfterOpenScan); +} +TESTCASE("ExecuteScanWithoutOpenScan", + "Check that we can't call executeScan without defining a scan "\ + "with openScan"){ + INITIALIZER(runLoadTable); + STEP(runExecuteScanWithoutOpenScan); + VERIFIER(runScanRead); + FINALIZER(runClearTable); +} +TESTCASE("OnlyOpenScanOnce", + "Check that we may only call openScan once in the same trans"){ + INITIALIZER(runLoadTable); + STEP(runOnlyOpenScanOnce); + VERIFIER(runScanRead); + FINALIZER(runClearTable); +} +TESTCASE("OnlyOneOpInScanTrans", + "Check that we can have only one operation in a scan trans"){ + INITIALIZER(runLoadTable); + STEP(runOnlyOneOpInScanTrans); + VERIFIER(runScanRead); + FINALIZER(runClearTable); +} +TESTCASE("OnlyOneOpBeforeOpenScan", + "Check that we can have only one operation in a trans defined "\ + "when calling openScan "){ + INITIALIZER(runLoadTable); + STEP(runOnlyOneOpBeforeOpenScan); + VERIFIER(runScanRead); + FINALIZER(runClearTable); +} +TESTCASE("OnlyOneScanPerTrans", + "Check that we can have only one scan operation in a trans"){ + INITIALIZER(runLoadTable); + STEP(runOnlyOneScanPerTrans); + VERIFIER(runScanRead); + FINALIZER(runClearTable); +} +TESTCASE("NoCloseTransaction", + "Check behaviour when close transaction is not called "){ + INITIALIZER(runLoadTable); + STEP(runNoCloseTransaction); + VERIFIER(runScanRead); + FINALIZER(runClearTable); +} +TESTCASE("CheckInactivityTimeOut", + "Check behaviour when the api sleeps for a long time before continuing scan "){ + INITIALIZER(runLoadTable); + STEP(runCheckInactivityTimeOut); + VERIFIER(runScanRead); + FINALIZER(runClearTable); +} +TESTCASE("CheckInactivityBeforeClose", + "Check behaviour when the api sleeps for a long time before calling close scan "){ + INITIALIZER(runLoadTable); + STEP(runCheckInactivityBeforeClose); + VERIFIER(runScanRead); + FINALIZER(runClearTable); +} +TESTCASE("ScanReadError5021", + "Scan and insert error 5021, one node is expected to crash"){ + INITIALIZER(runLoadTable); + TC_PROPERTY("ErrorCode", 5021); + STEP(runScanReadErrorOneNode); + FINALIZER(runClearTable); +} +TESTCASE("ScanReadError5022", + "Scan and insert error 5022, one node is expected to crash"){ + INITIALIZER(runLoadTable); + TC_PROPERTY("ErrorCode", 5022); + TC_PROPERTY("NodeNumber", 2); + STEP(runScanReadErrorOneNode); + FINALIZER(runClearTable); +} +TESTCASE("ScanReadError5023", + "Scan and insert error 5023"){ + INITIALIZER(runLoadTable); + TC_PROPERTY("ErrorCode", 5023); + STEP(runScanReadError); + FINALIZER(runClearTable); +} +TESTCASE("ScanReadError5024", + "Scan and insert error 5024"){ + INITIALIZER(runLoadTable); + TC_PROPERTY("ErrorCode", 5024); + STEP(runScanReadError); + FINALIZER(runClearTable); +} +TESTCASE("ScanReadError5025", + "Scan and insert error 5025"){ + INITIALIZER(runLoadTable); + TC_PROPERTY("ErrorCode", 5025); + STEP(runScanReadError); + FINALIZER(runClearTable); +} +TESTCASE("ScanReadError5030", + "Scan and insert error 5030."\ + "Drop all SCAN_NEXTREQ signals in LQH until the node is "\ + "shutdown with SYSTEM_ERROR because of scan fragment timeout"){ + INITIALIZER(runLoadTable); + TC_PROPERTY("ErrorCode", 5030); + STEP(runScanReadErrorOneNode); + FINALIZER(runClearTable); +} +TESTCASE("ScanReadRestart", + "Scan requirement:A scan should be able to start and "\ + "complete during node recovery and when one or more nodes "\ + "in the cluster is down.Use random parallelism "){ + INITIALIZER(runLoadTable); + TC_PROPERTY("Parallelism", RANDOM_PARALLELISM); // Random + STEP(runScanReadUntilStopped); + STEP(runRestarter); + FINALIZER(runClearTable); +} +TESTCASE("ScanUpdateRestart", + "Scan requirement:A scan should be able to start and "\ + "complete during node recovery and when one or more nodes "\ + "in the cluster is down. Use random parallelism"){ + INITIALIZER(runLoadTable); + TC_PROPERTY("Parallelism", RANDOM_PARALLELISM); // Random + STEP(runScanUpdateUntilStopped); + STEP(runRestarter); + FINALIZER(runClearTable); +} +#if 0 +TESTCASE("ScanReadRestart9999", + "Scan requirement:A scan should be able to start and "\ + "complete during node recovery and when one or more nodes "\ + "in the cluster is down. Use parallelism 240."\ + "Restart using error insert 9999"){ + INITIALIZER(runLoadTable); + TC_PROPERTY("Parallelism", 240); + STEP(runScanReadUntilStopped); + STEP(runRestarter9999); + FINALIZER(runClearTable); +} +TESTCASE("ScanUpdateRestart9999", + "Scan requirement:A scan should be able to start and "\ + "complete during node recovery and when one or more nodes "\ + "in the cluster is down. Use parallelism 240."\ + "Restart using error insert 9999"){ + INITIALIZER(runLoadTable); + TC_PROPERTY("Parallelism", 240); + STEP(runScanReadUntilStopped); + STEP(runScanUpdateUntilStopped); + STEP(runRestarter9999); + FINALIZER(runClearTable); +} +#endif +TESTCASE("InsertDelete", + "Load and delete all while scan updating and scan reading\n"\ + "Alexander Lukas special"){ + INITIALIZER(runClearTable); + STEP(runScanReadUntilStoppedNoCount); + STEP(runScanUpdateUntilStopped); + STEP(runInsertDelete); + FINALIZER(runClearTable); +} +TESTCASE("CheckAfterTerror", + "Check that we can still scan read after this terror of NdbApi"){ + INITIALIZER(runLoadTable); + STEPS(runScanRead, 5); + FINALIZER(runClearTable); +} +NDBT_TESTSUITE_END(testScan); + +int main(int argc, const char** argv){ + myRandom48Init(NdbTick_CurrentMillisecond()); + return testScan.execute(argc, argv); +} + diff --git a/ndb/test/ndbapi/testScan/Makefile b/ndb/test/ndbapi/testScan/Makefile deleted file mode 100644 index fe48f5bc926..00000000000 --- a/ndb/test/ndbapi/testScan/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include .defs.mk - -TYPE = ndbapitest - -BIN_TARGET = testScan - -SOURCES = testScan.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/testScan/ScanFunctions.hpp b/ndb/test/ndbapi/testScan/ScanFunctions.hpp deleted file mode 100644 index 36d01909861..00000000000 --- a/ndb/test/ndbapi/testScan/ScanFunctions.hpp +++ /dev/null @@ -1,392 +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 */ - -#include -#include - - - -struct Attrib { - int numAttribs; - int attribs[1024]; -}; -class AttribList { -public: - AttribList(){}; - ~AttribList(){ - for(size_t i = 0; i < attriblist.size(); i++){ - delete attriblist[i]; - } - }; - void buildAttribList(const NdbDictionary::Table* pTab); - Vector attriblist; -}; - - -// Functions that help out in testing that we may call -// scan functions in wrong order etc -// and receive a proper errormessage -class ScanFunctions { -public: - ScanFunctions(const NdbDictionary::Table& _tab) : tab(_tab){ - } - enum ActionType { - CloseWithoutStop, - NextScanWhenNoMore, - ExecuteScanWithOutOpenScan, - OnlyOneScanPerTrans, - OnlyOneOpBeforeOpenScan, - OnlyOpenScanOnce, - OnlyOneOpInScanTrans, - CheckInactivityTimeOut, - CheckInactivityBeforeClose , - NoCloseTransaction, - EqualAfterOpenScan - }; - - - int scanReadFunctions(Ndb* pNdb, - int records, - int parallelism, - ActionType action, - bool exclusive); -private: - const NdbDictionary::Table& tab; -}; - - -inline -int -ScanFunctions::scanReadFunctions(Ndb* pNdb, - int records, - int parallelism, - ActionType action, - bool exclusive){ - int retryAttempt = 0; - const int retryMax = 100; - int sleepTime = 10; - int check; - NdbConnection *pTrans; - NdbOperation *pOp; - - while (true){ - if (retryAttempt >= retryMax){ - g_err << "ERROR: has retried this operation " << retryAttempt - << " times, failing!" << endl; - return NDBT_FAILED; - } - - pTrans = pNdb->startTransaction(); - if (pTrans == NULL) { - const NdbError err = pNdb->getNdbError(); - if (err.status == NdbError::TemporaryError){ - ERR(err); - NdbSleep_MilliSleep(50); - retryAttempt++; - continue; - } - ERR(err); - return NDBT_FAILED; - } - - // Execute the scan without defining a scan operation - if(action != ExecuteScanWithOutOpenScan){ - - if (action == OnlyOneOpBeforeOpenScan){ - // There can only be one operation defined when calling openScan - NdbOperation* pOp3; - pOp3 = pTrans->getNdbOperation(tab.getName()); - if (pOp3 == NULL) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - } - - pOp = pTrans->getNdbOperation(tab.getName()); - if (pOp == NULL) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - - if (exclusive == true) - check = pOp->openScanExclusive(parallelism); - else - check = pOp->openScanRead(parallelism); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - - - if (action == OnlyOneScanPerTrans){ - // There can only be one operation in a scan transaction - NdbOperation* pOp4; - pOp4 = pTrans->getNdbOperation(tab.getName()); - if (pOp4 == NULL) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - } - - if (action == OnlyOpenScanOnce){ - // Call openScan one more time when it's already defined - check = pOp->openScanRead(parallelism); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - } - - if (action == OnlyOneOpInScanTrans){ - // Try to add another op to this scanTransaction - NdbOperation* pOp2; - pOp2 = pTrans->getNdbOperation(tab.getName()); - if (pOp2 == NULL) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - } - - - if (action==EqualAfterOpenScan){ - check = pOp->equal(tab.getColumn(0)->getName(), 10); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - } - - check = pOp->interpret_exit_ok(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - - for(int a = 0; agetValue(tab.getColumn(a)->getName()) == NULL) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - } - } - check = pTrans->executeScan(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - - - int abortCount = records / 10; - bool abortTrans = (action==CloseWithoutStop); - int eof; - int rows = 0; - eof = pTrans->nextScanResult(); - - while(eof == 0){ - rows++; - - if (abortCount == rows && abortTrans == true){ - g_info << "Scan is aborted after "<stopScan(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - } - - - pNdb->closeTransaction(pTrans); - return NDBT_OK; - } - - if(action == CheckInactivityTimeOut){ - if ((rows % (records / 10)) == 0){ - // Sleep for a long time before calling nextScanResult - if (sleepTime > 1) - sleepTime--; - g_info << "Sleeping "<nextScanResult(); - } - if (eof == -1) { - const NdbError err = pTrans->getNdbError(); - - if (err.status == NdbError::TemporaryError){ - ERR(err); - - // Be cruel, call nextScanResult after error - for(int i=0; i<10; i++){ - eof =pTrans->nextScanResult(); - if(eof == 0){ - g_err << "nextScanResult returned eof = " << eof << endl - << " That is an error when there are no more records" << endl; - return NDBT_FAILED; - } - } - // Be cruel end - - pNdb->closeTransaction(pTrans); - NdbSleep_MilliSleep(50); - retryAttempt++; - g_info << "Starting over" << endl; - - // If test is CheckInactivityTimeOut - // error 296 is expected - if ((action == CheckInactivityTimeOut) && - (err.code == 296)) - return NDBT_OK; - - continue; - } - ERR(err); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - - if (action == NextScanWhenNoMore){ - g_info << "Calling nextScanresult when there are no more records" << endl; - for(int i=0; i<10; i++){ - eof =pTrans->nextScanResult(); - if(eof == 0){ - g_err << "nextScanResult returned eof = " << eof << endl - << " That is an error when there are no more records" << endl; - return NDBT_FAILED; - } - } - - } - if(action ==CheckInactivityBeforeClose){ - // Sleep for a long time before calling close - g_info << "NdbSleep_SecSleep(5) before close transaction" << endl; - NdbSleep_SecSleep(5); - } - if(action == NoCloseTransaction) - g_info << "Forgetting to close transaction" << endl; - else - pNdb->closeTransaction(pTrans); - - g_info << rows << " rows have been read" << endl; - if (records != 0 && rows != records){ - g_err << "Check expected number of records failed" << endl - << " expected=" << records <<", " << endl - << " read=" << rows << endl; - return NDBT_FAILED; - } - - return NDBT_OK; - } - return NDBT_FAILED; - - -} - -void AttribList::buildAttribList(const NdbDictionary::Table* pTab){ - attriblist.clear(); - - Attrib* attr; - // Build attrib definitions that describes which attributes to read - // Try to build strange combinations, not just "all" or all PK's - - // Scan without reading any attributes - attr = new Attrib; - attr->numAttribs = 0; - attriblist.push_back(attr); - - for(int i = 1; i < pTab->getNoOfColumns(); i++){ - attr = new Attrib; - attr->numAttribs = i; - for(int a = 0; aattribs[a] = a; - attriblist.push_back(attr); - } - for(int i = pTab->getNoOfColumns()-1; i > 0; i--){ - attr = new Attrib; - attr->numAttribs = i; - for(int a = 0; aattribs[a] = a; - attriblist.push_back(attr); - } - for(int i = pTab->getNoOfColumns(); i > 0; i--){ - attr = new Attrib; - attr->numAttribs = pTab->getNoOfColumns() - i; - for(int a = 0; agetNoOfColumns() - i; a++) - attr->attribs[a] = pTab->getNoOfColumns()-a-1; - attriblist.push_back(attr); - } - for(int i = 1; i < pTab->getNoOfColumns(); i++){ - attr = new Attrib; - attr->numAttribs = pTab->getNoOfColumns() - i; - for(int a = 0; agetNoOfColumns() - i; a++) - attr->attribs[a] = pTab->getNoOfColumns()-a-1; - attriblist.push_back(attr); - } - for(int i = 1; i < pTab->getNoOfColumns(); i++){ - attr = new Attrib; - attr->numAttribs = 2; - for(int a = 0; a<2; a++){ - attr->attribs[a] = i%pTab->getNoOfColumns(); - } - attriblist.push_back(attr); - } - - // Last - attr = new Attrib; - attr->numAttribs = 1; - attr->attribs[0] = pTab->getNoOfColumns()-1; - attriblist.push_back(attr); - - // Last and first - attr = new Attrib; - attr->numAttribs = 2; - attr->attribs[0] = pTab->getNoOfColumns()-1; - attr->attribs[1] = 0; - attriblist.push_back(attr); - - // First and last - attr = new Attrib; - attr->numAttribs = 2; - attr->attribs[0] = 0; - attr->attribs[1] = pTab->getNoOfColumns()-1; - attriblist.push_back(attr); - -#if 1 - for(size_t i = 0; i < attriblist.size(); i++){ - - g_info << attriblist[i]->numAttribs << ": " ; - for(int a = 0; a < attriblist[i]->numAttribs; a++) - g_info << attriblist[i]->attribs[a] << ", "; - g_info << endl; - } -#endif - -} diff --git a/ndb/test/ndbapi/testScan/testScan.cpp b/ndb/test/ndbapi/testScan/testScan.cpp deleted file mode 100644 index dbf91f016d8..00000000000 --- a/ndb/test/ndbapi/testScan/testScan.cpp +++ /dev/null @@ -1,1311 +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 */ - -#include -#include -#include -#include -#include -#include -#include "ScanFunctions.hpp" -#include - -const NdbDictionary::Table * -getTable(Ndb* pNdb, int i){ - const NdbDictionary::Table* t = NDBT_Tables::getTable(i); - if (t == NULL){ - return 0; - } - return pNdb->getDictionary()->getTable(t->getName()); -} - - -int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ - - int records = ctx->getNumRecords(); - HugoTransactions hugoTrans(*ctx->getTab()); - if (hugoTrans.loadTable(GETNDB(step), records) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - - -int runCreateAllTables(NDBT_Context* ctx, NDBT_Step* step){ - - int a = NDBT_Tables::createAllTables(GETNDB(step), false, true); - return a; -} - -int runDropAllTablesExceptTestTable(NDBT_Context* ctx, NDBT_Step* step){ - - for (int i=0; i < NDBT_Tables::getNumTables(); i++){ - - const NdbDictionary::Table* tab = NDBT_Tables::getTable(i); - if (tab == NULL){ - return NDBT_ProgramExit(NDBT_FAILED); - } - - // Don't drop test table - if (strcmp(tab->getName(), ctx->getTab()->getName()) == 0){ - continue; - } - - int res = GETNDB(step)->getDictionary()->dropTable(tab->getName()); - if(res != -1){ - return NDBT_FAILED; - } - } - return NDBT_OK; -} - - -int runLoadAllTables(NDBT_Context* ctx, NDBT_Step* step){ - - int records = ctx->getNumRecords(); - for (int i=0; i < NDBT_Tables::getNumTables(); i++){ - - const NdbDictionary::Table* tab = getTable(GETNDB(step), i); - if (tab == NULL){ - return NDBT_FAILED; - } - HugoTransactions hugoTrans(*tab); - if (hugoTrans.loadTable(GETNDB(step), records) != 0){ - return NDBT_FAILED; - } - } - return NDBT_OK; -} - -int runScanReadRandomTable(NDBT_Context* ctx, NDBT_Step* step){ - int loops = ctx->getNumLoops(); - int records = ctx->getNumRecords(); - int parallelism = ctx->getProperty("Parallelism", 240); - int abort = ctx->getProperty("AbortProb"); - - int i = 0; - while (igetName() << endl; - HugoTransactions hugoTrans(*tab); - - g_info << i << ": "; - if (hugoTrans.scanReadRecords(GETNDB(step), records, abort, parallelism) != 0){ - return NDBT_FAILED; - } - i++; - } - return NDBT_OK; -} - -int runInsertUntilStopped(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - int i = 0; - HugoTransactions hugoTrans(*ctx->getTab()); - while (ctx->isTestStopped() == false) { - g_info << i << ": "; - if (hugoTrans.loadTable(GETNDB(step), records, 1) != 0){ - return NDBT_FAILED; - } - i++; - } - return NDBT_OK; -} - -int runInsertDelete(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - int records = ctx->getNumRecords(); - int loops = ctx->getNumLoops(); - int i = 0; - HugoTransactions hugoTrans(*ctx->getTab()); - UtilTransactions utilTrans(*ctx->getTab()); - while (istopTest(); - - return result; -} - -int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - - UtilTransactions utilTrans(*ctx->getTab()); - if (utilTrans.clearTable2(GETNDB(step), records) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runScanDelete(NDBT_Context* ctx, NDBT_Step* step){ - int loops = ctx->getNumLoops(); - int records = ctx->getNumRecords(); - - int i = 0; - UtilTransactions utilTrans(*ctx->getTab()); - HugoTransactions hugoTrans(*ctx->getTab()); - while (igetNumLoops(); - int records = ctx->getNumRecords(); - - int i = 0; - UtilTransactions utilTrans(*ctx->getTab()); - HugoTransactions hugoTrans(*ctx->getTab()); - - while (igetNumLoops(); - int records = ctx->getNumRecords(); - int parallelism = ctx->getProperty("Parallelism", 240); - int abort = ctx->getProperty("AbortProb"); - - int i = 0; - HugoTransactions hugoTrans(*ctx->getTab()); - while (iisTestStopped()) { - g_info << i << ": "; - if (hugoTrans.scanReadRecords(GETNDB(step), records, abort, parallelism) != 0){ - return NDBT_FAILED; - } - i++; - } - return NDBT_OK; -} - -int runScanReadCommitted(NDBT_Context* ctx, NDBT_Step* step){ - int loops = ctx->getNumLoops(); - int records = ctx->getNumRecords(); - int parallelism = ctx->getProperty("Parallelism", 240); - int abort = ctx->getProperty("AbortProb"); - - int i = 0; - HugoTransactions hugoTrans(*ctx->getTab()); - while (iisTestStopped()) { - g_info << i << ": "; - if (hugoTrans.scanReadCommittedRecords(GETNDB(step), records, - abort, parallelism) != 0){ - return NDBT_FAILED; - } - i++; - } - return NDBT_OK; -} - -int runScanReadError(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - int loops = ctx->getNumLoops(); - int records = ctx->getNumRecords(); - int parallelism = 240; // Max parallelism - int error = ctx->getProperty("ErrorCode"); - NdbRestarter restarter; - - int i = 0; - HugoTransactions hugoTrans(*ctx->getTab()); - while (iisTestStopped()) { - g_info << i << ": "; - - ndbout << "insertErrorInAllNodes("<getNumLoops(); - int records = ctx->getNumRecords(); - int parallelism = 240; // Max parallelism - int error = ctx->getProperty("ErrorCode"); - NdbRestarter restarter; - int lastId = 0; - - if (restarter.getNumDbNodes() < 2){ - ctx->stopTest(); - return NDBT_OK; - } - - int i = 0; - HugoTransactions hugoTrans(*ctx->getTab()); - while (igetNumRecords(); - int i = 0; - - int parallelism = ctx->getProperty("Parallelism", 240); - int para = parallelism; - - HugoTransactions hugoTrans(*ctx->getTab()); - while (ctx->isTestStopped() == false) { - if (parallelism == RANDOM_PARALLELISM) - para = myRandom48(239)+1; - - g_info << i << ": "; - if (hugoTrans.scanReadRecords(GETNDB(step), records, 0, para) != 0){ - return NDBT_FAILED; - } - i++; - } - return NDBT_OK; -} - -int runScanReadUntilStoppedNoCount(NDBT_Context* ctx, NDBT_Step* step){ - int i = 0; - HugoTransactions hugoTrans(*ctx->getTab()); - while (ctx->isTestStopped() == false) { - g_info << i << ": "; - if (hugoTrans.scanReadRecords(GETNDB(step), 0) != 0){ - return NDBT_FAILED; - } - i++; - } - return NDBT_OK; -} - - -int runPkRead(NDBT_Context* ctx, NDBT_Step* step){ - int loops = ctx->getNumLoops(); - int records = ctx->getNumRecords(); - int i = 0; - HugoTransactions hugoTrans(*ctx->getTab()); - while (igetNumLoops(); - int records = ctx->getNumRecords(); - int parallelism = ctx->getProperty("Parallelism", 1); - int abort = ctx->getProperty("AbortProb"); - int i = 0; - HugoTransactions hugoTrans(*ctx->getTab()); - while (igetNumRecords(); - int i = 0; - - int parallelism = ctx->getProperty("Parallelism", 240); - int para = parallelism; - - HugoTransactions hugoTrans(*ctx->getTab()); - while (ctx->isTestStopped() == false) { - if (parallelism == RANDOM_PARALLELISM) - para = myRandom48(239)+1; - - g_info << i << ": "; - if (hugoTrans.scanUpdateRecords(GETNDB(step), records, 0, para) == NDBT_FAILED){ - return NDBT_FAILED; - } - i++; - } - return NDBT_OK; -} - - -int runScanUpdate2(NDBT_Context* ctx, NDBT_Step* step){ - int loops = ctx->getNumLoops(); - int records = ctx->getNumRecords(); - int parallelism = ctx->getProperty("Parallelism", 240); - int abort = ctx->getProperty("AbortProb"); - int i = 0; - HugoTransactions hugoTrans(*ctx->getTab()); - while (igetNumRecords(); - HugoTransactions hugoTrans(*ctx->getTab()); - - if (hugoTrans.lockRecords(GETNDB(step), records, 5, 500) != 0){ - result = NDBT_FAILED; - } - ctx->stopTest(); - - return result; -} - -int runRestarter(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - int loops = ctx->getNumLoops(); - NdbRestarter restarter; - int i = 0; - int lastId = 0; - int timeout = 240; - - if (restarter.getNumDbNodes() < 2){ - ctx->stopTest(); - return NDBT_OK; - } - while(istopTest(); - - return result; -} - -int runRestarter9999(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - int loops = ctx->getNumLoops(); - NdbRestarter restarter; - int i = 0; - int lastId = 0; - - if (restarter.getNumDbNodes() < 2){ - ctx->stopTest(); - return NDBT_OK; - } - while(istopTest(); - - return result; -} - - -int runCheckGetValue(NDBT_Context* ctx, NDBT_Step* step){ - const NdbDictionary::Table* pTab = ctx->getTab(); - int parallelism = ctx->getProperty("Parallelism", 1); - int records = ctx->getNumRecords(); - int numFailed = 0; - AttribList alist; - alist.buildAttribList(pTab); - UtilTransactions utilTrans(*pTab); - for(size_t i = 0; i < alist.attriblist.size(); i++){ - g_info << (unsigned)i << endl; - if(utilTrans.scanReadRecords(GETNDB(step), - parallelism, - false, - records, - alist.attriblist[i]->numAttribs, - alist.attriblist[i]->attribs) != 0){ - numFailed++; - } - if(utilTrans.scanReadRecords(GETNDB(step), - parallelism, - true, - records, - alist.attriblist[i]->numAttribs, - alist.attriblist[i]->attribs) != 0){ - numFailed++; - } - } - - if(numFailed > 0) - return NDBT_FAILED; - else - return NDBT_OK; -} - -int runCloseWithoutStop(NDBT_Context* ctx, NDBT_Step* step){ - const NdbDictionary::Table* pTab = ctx->getTab(); - int records = ctx->getNumRecords(); - int numFailed = 0; - ScanFunctions scanF(*pTab); - // Iterate over all possible parallelism valuse - for (int p = 1; p<240; p++){ - g_info << p << " CloseWithoutStop openScan" << endl; - if (scanF.scanReadFunctions(GETNDB(step), - records, - p, - ScanFunctions::CloseWithoutStop, - false) != 0){ - numFailed++; - } - g_info << p << " CloseWithoutStop openScanExclusive" << endl; - if (scanF.scanReadFunctions(GETNDB(step), - records, - p, - ScanFunctions::CloseWithoutStop, - true) != 0){ - numFailed++; - } - } - - if(numFailed > 0) - return NDBT_FAILED; - else - return NDBT_OK; -} - -int runNextScanWhenNoMore(NDBT_Context* ctx, NDBT_Step* step){ - const NdbDictionary::Table* pTab = ctx->getTab(); - int records = ctx->getNumRecords(); - int numFailed = 0; - ScanFunctions scanF(*pTab); - if (scanF.scanReadFunctions(GETNDB(step), - records, - 6, - ScanFunctions::NextScanWhenNoMore, - false) != 0){ - numFailed++; - } - if (scanF.scanReadFunctions(GETNDB(step), - records, - 6, - ScanFunctions::NextScanWhenNoMore, - true) != 0){ - numFailed++; - } - - - if(numFailed > 0) - return NDBT_FAILED; - else - return NDBT_OK; -} - -int runEqualAfterOpenScan(NDBT_Context* ctx, NDBT_Step* step){ - const NdbDictionary::Table* pTab = ctx->getTab(); - int records = ctx->getNumRecords(); - int numFailed = 0; - ScanFunctions scanF(*pTab); - if (scanF.scanReadFunctions(GETNDB(step), - records, - 6, - ScanFunctions::EqualAfterOpenScan, - false) == NDBT_OK){ - numFailed++; - } - if (scanF.scanReadFunctions(GETNDB(step), - records, - 6, - ScanFunctions::EqualAfterOpenScan, - true) == NDBT_OK){ - numFailed++; - } - - - if(numFailed > 0) - return NDBT_FAILED; - else - return NDBT_OK; -} - -int runOnlyOpenScanOnce(NDBT_Context* ctx, NDBT_Step* step){ - const NdbDictionary::Table* pTab = ctx->getTab(); - int records = ctx->getNumRecords(); - int numFailed = 0; - ScanFunctions scanF(*pTab); - g_info << "OnlyOpenScanOnce openScanRead" << endl; - if (scanF.scanReadFunctions(GETNDB(step), - records, - 6, - ScanFunctions::OnlyOpenScanOnce, - false) == 0){ - numFailed++; - } - g_info << "OnlyOpenScanOnce openScanExclusive" << endl; - if (scanF.scanReadFunctions(GETNDB(step), - records, - 6, - ScanFunctions::OnlyOpenScanOnce, - true) == 0){ - numFailed++; - } - - - if(numFailed > 0) - return NDBT_FAILED; - else - return NDBT_OK; -} - -int runOnlyOneOpInScanTrans(NDBT_Context* ctx, NDBT_Step* step){ - const NdbDictionary::Table* pTab = ctx->getTab(); - int records = ctx->getNumRecords(); - int numFailed = 0; - - ScanFunctions scanF(*pTab); - if (scanF.scanReadFunctions(GETNDB(step), - records, - 6, - ScanFunctions::OnlyOneOpInScanTrans, - false) == 0){ - numFailed++; - } - if (scanF.scanReadFunctions(GETNDB(step), - records, - 6, - ScanFunctions::OnlyOneOpInScanTrans, - true) == 0){ - numFailed++; - } - - - if(numFailed > 0) - return NDBT_FAILED; - else - return NDBT_OK; - -} - -int runExecuteScanWithoutOpenScan(NDBT_Context* ctx, NDBT_Step* step){ - const NdbDictionary::Table* pTab = ctx->getTab(); - int records = ctx->getNumRecords(); - int numFailed = 0; - ScanFunctions scanF(*pTab); - if (scanF.scanReadFunctions(GETNDB(step), - records, - 1, - ScanFunctions::ExecuteScanWithOutOpenScan, - false) == 0){ - numFailed++; - } - - if(numFailed > 0) - return NDBT_FAILED; - else - return NDBT_OK; -} - - - -int runOnlyOneOpBeforeOpenScan(NDBT_Context* ctx, NDBT_Step* step){ - const NdbDictionary::Table* pTab = ctx->getTab(); - int records = ctx->getNumRecords(); - int numFailed = 0; - - ScanFunctions scanF(*pTab); - if (scanF.scanReadFunctions(GETNDB(step), - records, - 6, - ScanFunctions::OnlyOneOpBeforeOpenScan, - false) == 0){ - numFailed++; - } - if (scanF.scanReadFunctions(GETNDB(step), - records, - 6, - ScanFunctions::OnlyOneOpBeforeOpenScan, - true) == 0){ - numFailed++; - } - - if(numFailed > 0) - return NDBT_FAILED; - else - return NDBT_OK; - -} -int runOnlyOneScanPerTrans(NDBT_Context* ctx, NDBT_Step* step){ - const NdbDictionary::Table* pTab = ctx->getTab(); - int records = ctx->getNumRecords(); - int numFailed = 0; - - ScanFunctions scanF(*pTab); - if (scanF.scanReadFunctions(GETNDB(step), - records, - 6, - ScanFunctions::OnlyOneScanPerTrans, - false) == 0){ - numFailed++; - } - if (scanF.scanReadFunctions(GETNDB(step), - records, - 6, - ScanFunctions::OnlyOneScanPerTrans, - true) == 0){ - numFailed++; - } - - if(numFailed > 0) - return NDBT_FAILED; - else - return NDBT_OK; - -} - -int runNoCloseTransaction(NDBT_Context* ctx, NDBT_Step* step){ - const NdbDictionary::Table* pTab = ctx->getTab(); - int loops = ctx->getNumLoops(); - int records = ctx->getNumRecords(); - int numFailed = 0; - - ScanFunctions scanF(*pTab); - int l = 0; - while(l < loops){ - if (scanF.scanReadFunctions(GETNDB(step), - records, - 6, - ScanFunctions::NoCloseTransaction, - false) != 0){ - numFailed++; - } - if (scanF.scanReadFunctions(GETNDB(step), - records, - 6, - ScanFunctions::NoCloseTransaction, - true) != 0){ - numFailed++; - } - l++; - } - - - if(numFailed > 0) - return NDBT_FAILED; - else - return NDBT_OK; - -} - -int runCheckInactivityTimeOut(NDBT_Context* ctx, NDBT_Step* step){ - const NdbDictionary::Table* pTab = ctx->getTab(); - int records = ctx->getNumRecords(); - int numFailed = 0; - - ScanFunctions scanF(*pTab); - if (scanF.scanReadFunctions(GETNDB(step), - records, - 1, - ScanFunctions::CheckInactivityTimeOut, - false) != NDBT_OK){ - numFailed++; - } - if (scanF.scanReadFunctions(GETNDB(step), - records, - 240, - ScanFunctions::CheckInactivityTimeOut, - true) != NDBT_OK){ - numFailed++; - } - - if(numFailed > 0) - return NDBT_FAILED; - else - return NDBT_OK; - -} - -int runCheckInactivityBeforeClose(NDBT_Context* ctx, NDBT_Step* step){ - const NdbDictionary::Table* pTab = ctx->getTab(); - int records = ctx->getNumRecords(); - int numFailed = 0; - - ScanFunctions scanF(*pTab); - if (scanF.scanReadFunctions(GETNDB(step), - records, - 16, - ScanFunctions::CheckInactivityBeforeClose, - false) != 0){ - numFailed++; - } - if (scanF.scanReadFunctions(GETNDB(step), - records, - 240, - ScanFunctions::CheckInactivityBeforeClose, - true) != 0){ - numFailed++; - } - - if(numFailed > 0) - return NDBT_FAILED; - else - return NDBT_OK; - -} - - - -NDBT_TESTSUITE(testScan); -TESTCASE("ScanRead", - "Verify scan requirement: It should be possible "\ - "to read all records in a table without knowing their "\ - "primary key."){ - INITIALIZER(runLoadTable); - TC_PROPERTY("Parallelism", 1); - STEP(runScanRead); - FINALIZER(runClearTable); -} -TESTCASE("ScanRead16", - "Verify scan requirement: It should be possible to scan read "\ - "with parallelism, test with parallelism 16"){ - INITIALIZER(runLoadTable); - TC_PROPERTY("Parallelism", 16); - STEP(runScanRead); - FINALIZER(runClearTable); -} -TESTCASE("ScanRead240", - "Verify scan requirement: It should be possible to scan read with "\ - "parallelism, test with parallelism 240(240 would automatically be "\ - "downgraded to the maximum parallelism value for the current config)"){ - INITIALIZER(runLoadTable); - TC_PROPERTY("Parallelism", 240); - STEP(runScanRead); - FINALIZER(runClearTable); -} -TESTCASE("ScanReadCommitted240", - "Verify scan requirement: It should be possible to scan read committed with "\ - "parallelism, test with parallelism 240(240 would automatically be "\ - "downgraded to the maximum parallelism value for the current config)"){ - INITIALIZER(runLoadTable); - TC_PROPERTY("Parallelism", 240); - STEP(runScanReadCommitted); - FINALIZER(runClearTable); -} -TESTCASE("ScanUpdate", - "Verify scan requirement: It should be possible "\ - "to update all records in a table without knowing their"\ - " primary key."){ - INITIALIZER(runLoadTable); - STEP(runScanUpdate); - FINALIZER(runClearTable); -} -TESTCASE("ScanUpdate2", - "Verify scan requirement: It should be possible "\ - "to update all records in a table without knowing their"\ - " primary key. Do this efficently by calling nextScanResult(false) "\ - "in order to update the records already fetched to the api in one batch."){ - INITIALIZER(runLoadTable); - TC_PROPERTY("Parallelism", 240); - STEP(runScanUpdate2); - FINALIZER(runClearTable); -} -TESTCASE("ScanDelete", - "Verify scan requirement: It should be possible "\ - "to delete all records in a table without knowing their"\ - " primary key."){ - INITIALIZER(runLoadTable); - STEP(runScanDelete); - FINALIZER(runClearTable); -} -TESTCASE("ScanDelete2", - "Verify scan requirement: It should be possible "\ - "to delete all records in a table without knowing their"\ - " primary key. Do this efficently by calling nextScanResult(false) "\ - "in order to delete the records already fetched to the api in one batch."){ - INITIALIZER(runLoadTable); - TC_PROPERTY("Parallelism", 240); - STEP(runScanDelete2); - FINALIZER(runClearTable); -} -TESTCASE("ScanUpdateAndScanRead", - "Verify scan requirement: It should be possible to run "\ - "scan read and scan update at the same time"){ - INITIALIZER(runLoadTable); - TC_PROPERTY("Parallelism", 16); - STEP(runScanRead); - STEP(runScanUpdate); - FINALIZER(runClearTable); -} -TESTCASE("ScanReadAndLocker", - "Verify scan requirement: The locks are not kept throughout "\ - "the entire scan operation. This means that a scan does not "\ - "lock the entire table, only the records it's currently "\ - "operating on. This will test how scan performs when there are "\ - " a number of 1 second locks in the table"){ - INITIALIZER(runLoadTable); - STEP(runScanReadUntilStopped); - STEP(runLocker); - FINALIZER(runClearTable); -} -TESTCASE("ScanReadAndPkRead", - "Verify scan requirement: The locks are not kept throughout "\ - "the entire scan operation. This means that a scan does not "\ - "lock the entire table, only the records it's currently "\ - "operating on. This will test how scan performs when there are "\ - " a pk reads "){ - INITIALIZER(runLoadTable); - STEPS(runScanRead, 2); - STEPS(runPkRead, 2); - FINALIZER(runClearTable); -} -TESTCASE("ScanRead488", - "Verify scan requirement: It's only possible to have 11 concurrent "\ - "scans per fragment running in Ndb kernel at the same time. "\ - "When this limit is exceeded the scan will be aborted with errorcode "\ - "488."){ - INITIALIZER(runLoadTable); - STEPS(runScanRead, 70); - FINALIZER(runClearTable); -} -TESTCASE("ScanRead488Timeout", - ""){ - INITIALIZER(runLoadTable); - TC_PROPERTY("ErrorCode", 5034); - STEPS(runScanRead, 30); - STEP(runScanReadError); - FINALIZER(runClearTable); -} -TESTCASE("ScanRead40", - "Verify scan requirement: Scan with 40 simultaneous threads"){ - INITIALIZER(runLoadTable); - STEPS(runScanRead, 40); - FINALIZER(runClearTable); -} -TESTCASE("ScanRead100", - "Verify scan requirement: Scan with 100 simultaneous threads"){ - INITIALIZER(runLoadTable); - STEPS(runScanRead, 100); - FINALIZER(runClearTable); -} -TESTCASE("ScanRead40RandomTable", - "Verify scan requirement: Scan with 40 simultaneous threads. "\ - "Use random table for the scan"){ - INITIALIZER(runCreateAllTables); - INITIALIZER(runLoadAllTables); - STEPS(runScanReadRandomTable, 40); - FINALIZER(runDropAllTablesExceptTestTable); -} -TESTCASE("ScanRead100RandomTable", - "Verify scan requirement: Scan with 100 simultaneous threads. "\ - "Use random table for the scan"){ - INITIALIZER(runCreateAllTables); - INITIALIZER(runLoadAllTables); - STEPS(runScanReadRandomTable, 100); - FINALIZER(runDropAllTablesExceptTestTable); -} -TESTCASE("ScanReadRandomPrepare", - "Create and load tables for ScanRead40RandomNoTableCreate."){ - INITIALIZER(runCreateAllTables); - INITIALIZER(runLoadAllTables); -} -TESTCASE("ScanRead40RandomNoTableCreate", - "Verify scan requirement: Scan with 40 simultaneous threads. "\ - "Use random table for the scan. Dont create or load the tables."){ - STEPS(runScanReadRandomTable, 40); -} -TESTCASE("ScanRead100RandomNoTableCreate", - "Verify scan requirement: Scan with 100 simultaneous threads. "\ - "Use random table for the scan. Dont create or load the tables."){ - STEPS(runScanReadRandomTable, 100); -} -TESTCASE("ScanWithLocksAndInserts", - "TR457: This test is added to verify that an insert of a records "\ - "that is already in the database does not delete the record"){ - INITIALIZER(runLoadTable); - STEPS(runScanReadUntilStopped, 2); - STEP(runLocker); - STEP(runInsertUntilStopped); - FINALIZER(runClearTable); -} -TESTCASE("ScanReadAbort", - "Scan requirement: A scan may be aborted by the application "\ - "at any time. This can be performed even if there are more "\ - "tuples to scan."){ - INITIALIZER(runLoadTable); - TC_PROPERTY("AbortProb", 90); - STEPS(runScanRead, 3); - FINALIZER(runClearTable); -} -TESTCASE("ScanReadAbort15", - "Scan requirement: A scan may be aborted by the application "\ - "at any time. This can be performed even if there are more "\ - "tuples to scan. Use parallelism 15"){ - INITIALIZER(runLoadTable); - TC_PROPERTY("Parallelism", 15); - TC_PROPERTY("AbortProb", 90); - STEPS(runScanRead, 3); - FINALIZER(runClearTable); -} -TESTCASE("ScanReadAbort240", - "Scan requirement: A scan may be aborted by the application "\ - "at any time. This can be performed even if there are more "\ - "tuples to scan. Use parallelism 240(it will be downgraded to max para for this config)"){ - INITIALIZER(runLoadTable); - TC_PROPERTY("Parallelism", 240); - TC_PROPERTY("AbortProb", 90); - STEPS(runScanRead, 3); - FINALIZER(runClearTable); -} -TESTCASE("ScanUpdateAbort16", - "Scan requirement: A scan may be aborted by the application "\ - "at any time. This can be performed even if there are more "\ - "tuples to scan. Use parallelism 16"){ - INITIALIZER(runLoadTable); - TC_PROPERTY("Parallelism", 16); - TC_PROPERTY("AbortProb", 90); - STEPS(runScanUpdate, 3); - FINALIZER(runClearTable); -} -TESTCASE("ScanUpdateAbort240", - "Scan requirement: A scan may be aborted by the application "\ - "at any time. This can be performed even if there are more "\ - "tuples to scan. Use parallelism 240(it will be downgraded to max para for this config)"){ - INITIALIZER(runLoadTable); - TC_PROPERTY("Parallelism", 240); - TC_PROPERTY("AbortProb", 90); - STEPS(runScanUpdate, 3); - FINALIZER(runClearTable); -} -TESTCASE("CheckGetValue", - "Check that we can call getValue to read attributes"\ - "Especially interesting to see if we can read only the"\ - " first, last or any two attributes from the table"){ - INITIALIZER(runLoadTable); - STEP(runCheckGetValue); - VERIFIER(runScanRead); - FINALIZER(runClearTable); -} -TESTCASE("CloseWithoutStop", - "Check that we can close the scanning transaction without calling "\ - "stopScan"){ - INITIALIZER(runLoadTable); - STEP(runCloseWithoutStop); - VERIFIER(runScanRead); - FINALIZER(runClearTable); -} -TESTCASE("NextScanWhenNoMore", - "Check that we can call nextScanResult when there are no more "\ - "records, and that it returns a valid value"){ - INITIALIZER(runLoadTable); - STEP(runNextScanWhenNoMore); - VERIFIER(runScanRead); - FINALIZER(runClearTable); -} -TESTCASE("EqualAfterOpenScan", - "Check that we can't call equal after openScan"){ - STEP(runEqualAfterOpenScan); -} -TESTCASE("ExecuteScanWithoutOpenScan", - "Check that we can't call executeScan without defining a scan "\ - "with openScan"){ - INITIALIZER(runLoadTable); - STEP(runExecuteScanWithoutOpenScan); - VERIFIER(runScanRead); - FINALIZER(runClearTable); -} -TESTCASE("OnlyOpenScanOnce", - "Check that we may only call openScan once in the same trans"){ - INITIALIZER(runLoadTable); - STEP(runOnlyOpenScanOnce); - VERIFIER(runScanRead); - FINALIZER(runClearTable); -} -TESTCASE("OnlyOneOpInScanTrans", - "Check that we can have only one operation in a scan trans"){ - INITIALIZER(runLoadTable); - STEP(runOnlyOneOpInScanTrans); - VERIFIER(runScanRead); - FINALIZER(runClearTable); -} -TESTCASE("OnlyOneOpBeforeOpenScan", - "Check that we can have only one operation in a trans defined "\ - "when calling openScan "){ - INITIALIZER(runLoadTable); - STEP(runOnlyOneOpBeforeOpenScan); - VERIFIER(runScanRead); - FINALIZER(runClearTable); -} -TESTCASE("OnlyOneScanPerTrans", - "Check that we can have only one scan operation in a trans"){ - INITIALIZER(runLoadTable); - STEP(runOnlyOneScanPerTrans); - VERIFIER(runScanRead); - FINALIZER(runClearTable); -} -TESTCASE("NoCloseTransaction", - "Check behaviour when close transaction is not called "){ - INITIALIZER(runLoadTable); - STEP(runNoCloseTransaction); - VERIFIER(runScanRead); - FINALIZER(runClearTable); -} -TESTCASE("CheckInactivityTimeOut", - "Check behaviour when the api sleeps for a long time before continuing scan "){ - INITIALIZER(runLoadTable); - STEP(runCheckInactivityTimeOut); - VERIFIER(runScanRead); - FINALIZER(runClearTable); -} -TESTCASE("CheckInactivityBeforeClose", - "Check behaviour when the api sleeps for a long time before calling close scan "){ - INITIALIZER(runLoadTable); - STEP(runCheckInactivityBeforeClose); - VERIFIER(runScanRead); - FINALIZER(runClearTable); -} -TESTCASE("ScanReadError5021", - "Scan and insert error 5021, one node is expected to crash"){ - INITIALIZER(runLoadTable); - TC_PROPERTY("ErrorCode", 5021); - STEP(runScanReadErrorOneNode); - FINALIZER(runClearTable); -} -TESTCASE("ScanReadError5022", - "Scan and insert error 5022, one node is expected to crash"){ - INITIALIZER(runLoadTable); - TC_PROPERTY("ErrorCode", 5022); - TC_PROPERTY("NodeNumber", 2); - STEP(runScanReadErrorOneNode); - FINALIZER(runClearTable); -} -TESTCASE("ScanReadError5023", - "Scan and insert error 5023"){ - INITIALIZER(runLoadTable); - TC_PROPERTY("ErrorCode", 5023); - STEP(runScanReadError); - FINALIZER(runClearTable); -} -TESTCASE("ScanReadError5024", - "Scan and insert error 5024"){ - INITIALIZER(runLoadTable); - TC_PROPERTY("ErrorCode", 5024); - STEP(runScanReadError); - FINALIZER(runClearTable); -} -TESTCASE("ScanReadError5025", - "Scan and insert error 5025"){ - INITIALIZER(runLoadTable); - TC_PROPERTY("ErrorCode", 5025); - STEP(runScanReadError); - FINALIZER(runClearTable); -} -TESTCASE("ScanReadError5030", - "Scan and insert error 5030."\ - "Drop all SCAN_NEXTREQ signals in LQH until the node is "\ - "shutdown with SYSTEM_ERROR because of scan fragment timeout"){ - INITIALIZER(runLoadTable); - TC_PROPERTY("ErrorCode", 5030); - STEP(runScanReadErrorOneNode); - FINALIZER(runClearTable); -} -TESTCASE("ScanReadRestart", - "Scan requirement:A scan should be able to start and "\ - "complete during node recovery and when one or more nodes "\ - "in the cluster is down.Use random parallelism "){ - INITIALIZER(runLoadTable); - TC_PROPERTY("Parallelism", RANDOM_PARALLELISM); // Random - STEP(runScanReadUntilStopped); - STEP(runRestarter); - FINALIZER(runClearTable); -} -TESTCASE("ScanUpdateRestart", - "Scan requirement:A scan should be able to start and "\ - "complete during node recovery and when one or more nodes "\ - "in the cluster is down. Use random parallelism"){ - INITIALIZER(runLoadTable); - TC_PROPERTY("Parallelism", RANDOM_PARALLELISM); // Random - STEP(runScanUpdateUntilStopped); - STEP(runRestarter); - FINALIZER(runClearTable); -} -#if 0 -TESTCASE("ScanReadRestart9999", - "Scan requirement:A scan should be able to start and "\ - "complete during node recovery and when one or more nodes "\ - "in the cluster is down. Use parallelism 240."\ - "Restart using error insert 9999"){ - INITIALIZER(runLoadTable); - TC_PROPERTY("Parallelism", 240); - STEP(runScanReadUntilStopped); - STEP(runRestarter9999); - FINALIZER(runClearTable); -} -TESTCASE("ScanUpdateRestart9999", - "Scan requirement:A scan should be able to start and "\ - "complete during node recovery and when one or more nodes "\ - "in the cluster is down. Use parallelism 240."\ - "Restart using error insert 9999"){ - INITIALIZER(runLoadTable); - TC_PROPERTY("Parallelism", 240); - STEP(runScanReadUntilStopped); - STEP(runScanUpdateUntilStopped); - STEP(runRestarter9999); - FINALIZER(runClearTable); -} -#endif -TESTCASE("InsertDelete", - "Load and delete all while scan updating and scan reading\n"\ - "Alexander Lukas special"){ - INITIALIZER(runClearTable); - STEP(runScanReadUntilStoppedNoCount); - STEP(runScanUpdateUntilStopped); - STEP(runInsertDelete); - FINALIZER(runClearTable); -} -TESTCASE("CheckAfterTerror", - "Check that we can still scan read after this terror of NdbApi"){ - INITIALIZER(runLoadTable); - STEPS(runScanRead, 5); - FINALIZER(runClearTable); -} -NDBT_TESTSUITE_END(testScan); - -int main(int argc, const char** argv){ - myRandom48Init(NdbTick_CurrentMillisecond()); - return testScan.execute(argc, argv); -} - diff --git a/ndb/test/ndbapi/testScanInterpreter.cpp b/ndb/test/ndbapi/testScanInterpreter.cpp new file mode 100644 index 00000000000..3b5baf954e0 --- /dev/null +++ b/ndb/test/ndbapi/testScanInterpreter.cpp @@ -0,0 +1,280 @@ +/* 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 */ + +#include "NDBT_Test.hpp" +#include "NDBT_ReturnCodes.h" +#include "HugoTransactions.hpp" +#include "UtilTransactions.hpp" +#include "NdbRestarter.hpp" +#include +#include "ScanFilter.hpp" +#include "ScanInterpretTest.hpp" + +int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ + + int records = ctx->getNumRecords(); + HugoTransactions hugoTrans(*ctx->getTab()); + if (hugoTrans.loadTable(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + + UtilTransactions utilTrans(*ctx->getTab()); + if (utilTrans.clearTable2(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runClearResTable(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + const NdbDictionary::Table* pResTab = + GETNDB(step)->getDictionary()->getTable(ctx->getProperty("ResultTabName", "NULL")); + + UtilTransactions utilTrans(*pResTab); + if (utilTrans.clearTable2(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runScanRead(NDBT_Context* ctx, NDBT_Step* step){ + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + int parallelism = ctx->getProperty("Parallelism", 1); + + int i = 0; + HugoTransactions hugoTrans(*ctx->getTab()); + while (igetNumRecords(); + int parallelism = ctx->getProperty("Parallelism", 1); + const NdbDictionary::Table* pResTab = + NDBT_Table::discoverTableFromDb(GETNDB(step), + ctx->getProperty("ResultTabName", "NULL")); + + HugoTransactions hugoTrans(*pResTab); + if (hugoTrans.scanReadRecords(GETNDB(step), records, 0, parallelism) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runCreateResultTable(NDBT_Context* ctx, NDBT_Step* step){ + + const NdbDictionary::Table* pTab = ctx->getTab(); + char newTabName[256]; + snprintf(newTabName, 256, "%s_RES", pTab->getName()); + ctx->setProperty("ResultTabName", newTabName); + + NdbDictionary::Table resTab(* pTab); + resTab.setName(newTabName); + + if (GETNDB(step)->getDictionary()->createTable(resTab) != 0){ + g_err << newTabName << " creation failed!"<< endl; + return NDBT_FAILED; + }else{ + g_info << newTabName << " created!"<< endl; + return NDBT_OK; + } +} + +int scanWithFilter(NDBT_Context* ctx, NDBT_Step* step, ScanFilter& filt){ + int records = ctx->getNumRecords(); + const char* resTabName = ctx->getProperty("ResultTabName", "NULL"); + if (strcmp(resTabName, "NULL") == 0) + return NDBT_FAILED; + const NdbDictionary::Table* pTab = ctx->getTab(); + const NdbDictionary::Table* pResTab = NDBT_Table::discoverTableFromDb(GETNDB(step), resTabName); + if (pResTab == NULL) + return NDBT_FAILED; + + ScanInterpretTest interpretTest(*pTab, *pResTab); + if (interpretTest.scanRead(GETNDB(step), + records, + 16, + filt) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} +int runScanLessThan(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + LessThanFilter filt(records); + return scanWithFilter(ctx, step, filt); +} +int runScanEqual(NDBT_Context* ctx, NDBT_Step* step){ + EqualFilter filt; + return scanWithFilter(ctx, step, filt); +} + +int scanVerifyWithFilter(NDBT_Context* ctx, NDBT_Step* step, ScanFilter& filt){ + int records = ctx->getNumRecords(); + const char* resTabName = ctx->getProperty("ResultTabName", "NULL"); + if (strcmp(resTabName, "NULL") == 0) + return NDBT_FAILED; + const NdbDictionary::Table* pTab = ctx->getTab(); + const NdbDictionary::Table* pResTab = NDBT_Table::discoverTableFromDb(GETNDB(step), resTabName); + if (pResTab == NULL) + return NDBT_FAILED; + + ScanInterpretTest interpretTest(*pTab, *pResTab); + if (interpretTest.scanReadVerify(GETNDB(step), + records, + 16, + filt) != NDBT_OK){ + return NDBT_FAILED; + } + return NDBT_OK; +} +int runScanLessThanVerify(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + LessThanFilter filt(records); + return scanVerifyWithFilter(ctx, step, filt); +} +int runScanEqualVerify(NDBT_Context* ctx, NDBT_Step* step){ + EqualFilter filt; + return scanVerifyWithFilter(ctx, step, filt); +} + +int runScanEqualLoop(NDBT_Context* ctx, NDBT_Step* step){ + int loops = ctx->getNumLoops(); + int l = 0; + EqualFilter filt; + while(l < loops){ + if (scanWithFilter(ctx, step, filt) != NDBT_OK) + return NDBT_FAILED; + if (runClearResTable(ctx, step) != NDBT_OK) + return NDBT_FAILED; + l++; + } + return NDBT_OK; +} + + +int runScanEqualVerifyLoop(NDBT_Context* ctx, NDBT_Step* step){ + int loops = ctx->getNumLoops(); + int l = 0; + EqualFilter filt; + while(l < loops){ + if (scanWithFilter(ctx, step, filt) != NDBT_OK) + return NDBT_FAILED; + if (scanVerifyWithFilter(ctx, step, filt) != NDBT_OK) + return NDBT_FAILED; + if (runClearResTable(ctx, step) != NDBT_OK) + return NDBT_FAILED; + l++; + } + return NDBT_OK; +} + +int runScanLessThanLoop(NDBT_Context* ctx, NDBT_Step* step){ + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + int l = 0; + LessThanFilter filt(records); + while(l < loops){ + if (scanWithFilter(ctx, step, filt) != NDBT_OK) + return NDBT_FAILED; + if (runClearResTable(ctx, step) != NDBT_OK) + return NDBT_FAILED; + l++; + } + return NDBT_OK; +} + +NDBT_TESTSUITE(testScanInterpreter); +TESTCASE("ScanLessThan", + "Read all records in table TX with attrX less "\ + "than a value and store the resultset in TX_RES."\ + "Then compare records in TX_RES with records in TX."){ + // TABLE("T1"); + // TABLE("T2"); + INITIALIZER(runLoadTable); + INITIALIZER(runCreateResultTable); + STEP(runScanLessThan); + VERIFIER(runScanLessThanVerify); + FINALIZER(runClearTable); + FINALIZER(runClearResTable); +} +TESTCASE("ScanEqual", + "Read all records in table TX with attrX equal "\ + "to a value and store the resultset in TX_RES."\ + "Then compare records in TX_RES with records in TX."){ + // TABLE("T1"); + // TABLE("T2"); + INITIALIZER(runLoadTable); + INITIALIZER(runCreateResultTable); + STEP(runScanEqual); + VERIFIER(runScanEqualVerify); + FINALIZER(runClearTable); + FINALIZER(runClearResTable); +} +TESTCASE("ScanEqualLoop", + "Scan all records in TX equal to a value."\ + "Do this loop number of times"){ + // TABLE("T1"); + // TABLE("T2"); + INITIALIZER(runLoadTable); + INITIALIZER(runCreateResultTable); + STEP(runScanEqualLoop); + FINALIZER(runClearTable); + FINALIZER(runClearResTable); +} +TESTCASE("ScanEqualVerifyLoop", + "Scan all records in TX equal to a value."\ + "Verify record in TX_RES table"\ + "Do this loop number of times"){ + // TABLE("T1"); + // TABLE("T2"); + INITIALIZER(runLoadTable); + INITIALIZER(runCreateResultTable); + STEP(runScanEqualVerifyLoop); + FINALIZER(runClearTable); + FINALIZER(runClearResTable); +} +TESTCASE("ScanLessThanLoop", + "Scan all records in TX less than a value."\ + "Do this loop number of times"){ + // TABLE("T1"); + // TABLE("T2"); + INITIALIZER(runLoadTable); + INITIALIZER(runCreateResultTable); + STEP(runScanLessThanLoop); + FINALIZER(runClearTable); + FINALIZER(runClearResTable); +} +NDBT_TESTSUITE_END(testScanInterpreter); + +int main(int argc, const char** argv){ + return testScanInterpreter.execute(argc, argv); +} + + + diff --git a/ndb/test/ndbapi/testScanInterpreter/Makefile b/ndb/test/ndbapi/testScanInterpreter/Makefile deleted file mode 100644 index c7d96494148..00000000000 --- a/ndb/test/ndbapi/testScanInterpreter/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include .defs.mk - -TYPE = ndbapitest - -BIN_TARGET = testScanInterpreter - -SOURCES = testScanInterpreter.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/testScanInterpreter/ScanFilter.hpp b/ndb/test/ndbapi/testScanInterpreter/ScanFilter.hpp deleted file mode 100644 index 09786756798..00000000000 --- a/ndb/test/ndbapi/testScanInterpreter/ScanFilter.hpp +++ /dev/null @@ -1,131 +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 */ - -#ifndef SCAN_FILTER_HPP -#define SCAN_FILTER_HPP - -class ScanFilter { -public: -#if 0 - /** - * Create a scan filter for table tab - * colNo - column to filter on - * val - val to use when selecting valu to filter on - * - */ - ScanFilter(const NDBT_Table& tab, - int colNo, - int val); -#endif - ScanFilter(int records = 1000){}; - virtual int filterOp(NdbOperation*) = 0; - virtual int verifyRecord(NDBT_ResultRow&) = 0; -private: - - // const NDBT_Table& tab; -}; - -class LessThanFilter : public ScanFilter { -public: - LessThanFilter(int records){ compare_value = records / 100; }; -private: - Uint32 compare_value; - int filterOp(NdbOperation* pOp); - int verifyRecord(NDBT_ResultRow&); -}; - -class EqualFilter : public ScanFilter { - static const Uint32 compare_value = 100; - int filterOp(NdbOperation* pOp); - int verifyRecord(NDBT_ResultRow&); -}; - -class NoFilter : public ScanFilter { - int filterOp(NdbOperation* pOp); - int verifyRecord(NDBT_ResultRow&); -}; - - -int LessThanFilter::filterOp(NdbOperation* pOp){ - - if (pOp->load_const_u32(1, compare_value) != 0) - return NDBT_FAILED; - - if (pOp->read_attr("KOL2", 2) != 0) - return NDBT_FAILED; - - if (pOp->branch_lt(1, 2, 0) != 0) - return NDBT_FAILED; - - if (pOp->interpret_exit_nok() != 0) - return NDBT_FAILED; - - if (pOp->def_label(0) != 0) - return NDBT_FAILED; - - if (pOp->interpret_exit_ok() != 0) - return NDBT_FAILED; - - return NDBT_OK; -} - -int LessThanFilter::verifyRecord(NDBT_ResultRow& row){ - NdbRecAttr* rec = row.attributeStore(1); - if (rec->u_32_value() < compare_value) - return NDBT_OK; - return NDBT_FAILED; -} - -int EqualFilter::filterOp(NdbOperation* pOp){ - - if (pOp->load_const_u32(1, compare_value) != 0) - return NDBT_FAILED; - - if (pOp->read_attr("KOL2", 2) != 0) - return NDBT_FAILED; - - if (pOp->branch_eq(1, 2, 0) != 0) - return NDBT_FAILED; - - if (pOp->interpret_exit_nok() != 0) - return NDBT_FAILED; - - if (pOp->def_label(0) != 0) - return NDBT_FAILED; - - if (pOp->interpret_exit_ok() != 0) - return NDBT_FAILED; - - return NDBT_OK; -} - -int EqualFilter::verifyRecord(NDBT_ResultRow& row){ - NdbRecAttr* rec = row.attributeStore(1); - if (rec->u_32_value() == compare_value) - return NDBT_OK; - return NDBT_FAILED; -} - -int NoFilter::filterOp(NdbOperation* pOp){ - return NDBT_OK; -} - -int NoFilter::verifyRecord(NDBT_ResultRow& row){ - // Check if this record should be in the result set or not - return NDBT_OK; -} - -#endif diff --git a/ndb/test/ndbapi/testScanInterpreter/ScanInterpretTest.hpp b/ndb/test/ndbapi/testScanInterpreter/ScanInterpretTest.hpp deleted file mode 100644 index 3862de34111..00000000000 --- a/ndb/test/ndbapi/testScanInterpreter/ScanInterpretTest.hpp +++ /dev/null @@ -1,528 +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 */ - -#ifndef SCAN_INTERPRET_TEST_HPP -#define SCAN_INTERPRET_TEST_HPP - -#include "ScanFilter.hpp" - -class ScanInterpretTest { -public: - ScanInterpretTest(const NdbDictionary::Table& _tab, - const NdbDictionary::Table& _restab) : - tab(_tab), - restab(_restab), - row(_tab){ - } - - int scanRead(Ndb*, - int records, - int parallelism, - ScanFilter& filter); - int scanReadVerify(Ndb*, - int records, - int parallelism, - ScanFilter& filter); - - int addRowToInsert(Ndb* pNdb, - NdbConnection* pInsTrans); - int addRowToCheckTrans(Ndb* pNdb, - NdbConnection* pCheckTrans); -private: - const NdbDictionary::Table& tab; - const NdbDictionary::Table& restab; - NDBT_ResultRow row; - -}; - - -inline -int -ScanInterpretTest::addRowToInsert(Ndb* pNdb, - NdbConnection* pInsTrans){ - - NdbOperation* pOp = - pInsTrans->getNdbOperation(restab.getName()); - if (pOp == NULL) { - ERR(pInsTrans->getNdbError()); - pNdb->closeTransaction(pInsTrans); - return NDBT_FAILED; - } - - if( pOp->insertTuple() == -1 ) { - ERR(pInsTrans->getNdbError()); - pNdb->closeTransaction(pInsTrans); - return NDBT_FAILED; - } - - // Copy all attribute to the new operation - for (int a = 0; agetType()){ - case NdbDictionary::Column::Char: - case NdbDictionary::Column::Varchar: - case NdbDictionary::Column::Binary: - case NdbDictionary::Column::Varbinary:{ - check = pOp->setValue( attr->getName(), - reca->aRef()); - break; - } - case NdbDictionary::Column::Int:{ - check = pOp->setValue( attr->getName(), - reca->int32_value()); - } - break; - case NdbDictionary::Column::Bigint:{ - check = pOp->setValue( attr->getName(), - reca->int64_value()); - } - break; - case NdbDictionary::Column::Unsigned:{ - check = pOp->setValue( attr->getName(), - reca->u_32_value()); - } - break; - case NdbDictionary::Column::Bigunsigned:{ - check = pOp->setValue( attr->getName(), - reca->u_64_value()); - } - break; - case NdbDictionary::Column::Float: - check = pOp->setValue( attr->getName(), - reca->float_value()); - - break; - default: - check = -1; - break; - } - if(check != 0){ - ERR(pInsTrans->getNdbError()); - pNdb->closeTransaction(pInsTrans); - return NDBT_FAILED; - } - } - - return NDBT_OK; -} - -inline -int -ScanInterpretTest::addRowToCheckTrans(Ndb* pNdb, - NdbConnection* pCheckTrans){ - - NdbOperation* pOp = - pCheckTrans->getNdbOperation(restab.getName()); - if (pOp == NULL) { - ERR(pNdb->getNdbError()); - return NDBT_FAILED; - } - - if(pOp->readTuple() != 0) { - ERR(pNdb->getNdbError()); - return NDBT_FAILED; - } - - // Copy pk attribute's to the new operation - for (int a = 0; agetPrimaryKey() == true){ - NdbRecAttr* reca = row.attributeStore(a); - int check = -1; - switch (attr->getType()){ - case NdbDictionary::Column::Char: - case NdbDictionary::Column::Varchar: - case NdbDictionary::Column::Binary: - case NdbDictionary::Column::Varbinary:{ - check = pOp->equal( attr->getName(), - reca->aRef()); - break; - } - case NdbDictionary::Column::Int:{ - check = pOp->equal( attr->getName(), - reca->int32_value()); - } - break; - case NdbDictionary::Column::Bigint:{ - check = pOp->equal( attr->getName(), - reca->int64_value()); - } - break; - case NdbDictionary::Column::Unsigned:{ - check = pOp->equal( attr->getName(), - reca->u_32_value()); - } - break; - case NdbDictionary::Column::Bigunsigned:{ - check = pOp->equal( attr->getName(), - reca->u_64_value()); - } - break; - default: - check = -1; - break; - } - if(check != 0){ - ERR(pNdb->getNdbError()); - return NDBT_FAILED; - } - } - } - - return NDBT_OK; -} - -inline -int -ScanInterpretTest::scanRead(Ndb* pNdb, - int records, - int parallelism, - ScanFilter& filter){ - int retryAttempt = 0; - int retryMax = 100; - int check; - NdbConnection *pTrans; - NdbOperation *pOp; - - while (true){ - - if (retryAttempt >= retryMax){ - ndbout << "ERROR: has retried this operation " << retryAttempt - << " times, failing!" << endl; - return NDBT_FAILED; - } - - pTrans = pNdb->startTransaction(); - if (pTrans == NULL) { - const NdbError err = pNdb->getNdbError(); - if (err.status == NdbError::TemporaryError){ - ERR(err); - NdbSleep_MilliSleep(50); - retryAttempt++; - continue; - } - ERR(err); - return NDBT_FAILED; - } - - pOp = pTrans->getNdbOperation(tab.getName()); - if (pOp == NULL) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp->openScanRead(parallelism); - //check = pOp->openScanExclusive(parallelism); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - - if (filter.filterOp(pOp) != 0){ - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - - // Read all attributes - for(int a = 0; agetValue(tab.getColumn(a)->getName())) == 0) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - } - check = pTrans->executeScan(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - - int eof; - int rows = 0; - NdbConnection* pInsTrans; - - while((eof = pTrans->nextScanResult(true)) == 0){ - pInsTrans = pNdb->startTransaction(); - if (pInsTrans == NULL) { - const NdbError err = pNdb->getNdbError(); - ERR(err); - return NDBT_FAILED; - } - do { - rows++; - if (addRowToInsert(pNdb, pInsTrans) != 0){ - pNdb->closeTransaction(pTrans); - pNdb->closeTransaction(pInsTrans); - return NDBT_FAILED; - } - } while((eof = pTrans->nextScanResult(false)) == 0); - - check = pInsTrans->execute(Commit); - if( check == -1 ) { - const NdbError err = pInsTrans->getNdbError(); - ERR(err); - pNdb->closeTransaction(pInsTrans); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - pNdb->closeTransaction(pInsTrans); - - } - if (eof == -1) { - const NdbError err = pTrans->getNdbError(); - - if (err.status == NdbError::TemporaryError){ - ERR(err); - pNdb->closeTransaction(pTrans); - NdbSleep_MilliSleep(50); - retryAttempt++; - continue; - } - ERR(err); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - - pNdb->closeTransaction(pTrans); - - g_info << rows << " rows have been scanned" << endl; - - return NDBT_OK; - } - return NDBT_FAILED; -} - -inline -int -ScanInterpretTest::scanReadVerify(Ndb* pNdb, - int records, - int parallelism, - ScanFilter& filter){ - int retryAttempt = 0; - const int retryMax = 100; - int check; - NdbConnection *pTrans; - NdbOperation *pOp; - - while (true){ - - if (retryAttempt >= retryMax){ - ndbout << "ERROR: has retried this operation " << retryAttempt - << " times, failing!" << endl; - return NDBT_FAILED; - } - - pTrans = pNdb->startTransaction(); - if (pTrans == NULL) { - const NdbError err = pNdb->getNdbError(); - if (err.status == NdbError::TemporaryError){ - ERR(err); - NdbSleep_MilliSleep(50); - retryAttempt++; - continue; - } - ERR(err); - return NDBT_FAILED; - } - - - pOp = pTrans->getNdbOperation(tab.getName()); - if (pOp == NULL) { if (pOp->getValue("KOL2") == 0){ - ERR(pNdb->getNdbError()); - return NDBT_FAILED; - } - - - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp->openScanRead(parallelism); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - - check = pOp->interpret_exit_ok(); - if (check == -1) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - - - // Read all attributes - for(int a = 0; agetValue(tab.getColumn(a)->getName())) == 0) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - } - check = pTrans->executeScan(); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - - int eof; - int rows = 0; - int rowsNoExist = 0; - int rowsExist = 0; - int existingRecordsNotFound = 0; - int nonExistingRecordsFound = 0; - - - NdbConnection* pExistTrans; - NdbConnection* pNoExistTrans; - - while((eof = pTrans->nextScanResult(true)) == 0){ - pExistTrans = pNdb->startTransaction(); - if (pExistTrans == NULL) { - const NdbError err = pNdb->getNdbError(); - ERR(err); - return NDBT_FAILED; - } - pNoExistTrans = pNdb->startTransaction(); - if (pNoExistTrans == NULL) { - const NdbError err = pNdb->getNdbError(); - ERR(err); - return NDBT_FAILED; - } - do { - rows++; - if (filter.verifyRecord(row) == NDBT_OK){ - rowsExist++; - if (addRowToCheckTrans(pNdb, pExistTrans) != 0){ - pNdb->closeTransaction(pTrans); - pNdb->closeTransaction(pExistTrans); - pNdb->closeTransaction(pNoExistTrans); - return NDBT_FAILED; - } - }else{ - rowsNoExist++; - if (addRowToCheckTrans(pNdb, pNoExistTrans) != 0){ - pNdb->closeTransaction(pTrans); - pNdb->closeTransaction(pExistTrans); - pNdb->closeTransaction(pNoExistTrans); - return NDBT_FAILED; - } - } - } while((eof = pTrans->nextScanResult(false)) == 0); - - - // Execute the transaction containing reads of - // all the records that should be in the result table - check = pExistTrans->execute(Commit); - if( check == -1 ) { - const NdbError err = pExistTrans->getNdbError(); - ERR(err); - if (err.code != 626){ - pNdb->closeTransaction(pExistTrans); - pNdb->closeTransaction(pNoExistTrans); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - }else{ - // Some of the records expected to be found wasn't - // there - existingRecordsNotFound = 1; - } - } - pNdb->closeTransaction(pExistTrans); - - // Execute the transaction containing reads of - // all the records that should NOT be in the result table - check = pNoExistTrans->execute(Commit, CommitAsMuchAsPossible); - if( check == -1 ) { - const NdbError err = pNoExistTrans->getNdbError(); - // The transactions error code should be zero - if (err.code != 626){ - ERR(err); - pNdb->closeTransaction(pNoExistTrans); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - // Loop through the no existing transaction and check that no - // operations where successful - const NdbOperation* pOp2 = NULL; - while ((pOp2 = pNoExistTrans->getNextCompletedOperation(pOp2)) != NULL){ - const NdbError err = pOp2->getNdbError(); - if (err.code != 626){ - ndbout << "err.code = " << err.code<< endl; - nonExistingRecordsFound = 1; - } - } - } - - pNdb->closeTransaction(pNoExistTrans); - - - } - if (eof == -1) { - const NdbError err = pTrans->getNdbError(); - - if (err.status == NdbError::TemporaryError){ - ERR(err); - pNdb->closeTransaction(pTrans); - NdbSleep_MilliSleep(50); - retryAttempt++; - continue; - } - ERR(err); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - - int testResult = NDBT_OK; - int rowsResult = 0; - UtilTransactions utilTrans(restab); - if (utilTrans.selectCount(pNdb, - 240, - &rowsResult) != 0){ - return NDBT_FAILED; - } - if (existingRecordsNotFound == 1){ - ndbout << "!!! Expected records not found" << endl; - testResult = NDBT_FAILED; - } - if (nonExistingRecordsFound == 1){ - ndbout << "!!! Unxpected records found" << endl; - testResult = NDBT_FAILED; - } - ndbout << rows << " rows scanned(" - << rowsExist << " found, " << rowsResult<<" expected)" << endl; - if (rowsResult != rowsExist){ - ndbout << "!!! Number of rows in result table different from expected" << endl; - testResult = NDBT_FAILED; - } - - return testResult; - } - return NDBT_FAILED; -} - -#endif diff --git a/ndb/test/ndbapi/testScanInterpreter/testScanInterpreter.cpp b/ndb/test/ndbapi/testScanInterpreter/testScanInterpreter.cpp deleted file mode 100644 index 3b5baf954e0..00000000000 --- a/ndb/test/ndbapi/testScanInterpreter/testScanInterpreter.cpp +++ /dev/null @@ -1,280 +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 */ - -#include "NDBT_Test.hpp" -#include "NDBT_ReturnCodes.h" -#include "HugoTransactions.hpp" -#include "UtilTransactions.hpp" -#include "NdbRestarter.hpp" -#include -#include "ScanFilter.hpp" -#include "ScanInterpretTest.hpp" - -int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ - - int records = ctx->getNumRecords(); - HugoTransactions hugoTrans(*ctx->getTab()); - if (hugoTrans.loadTable(GETNDB(step), records) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - - UtilTransactions utilTrans(*ctx->getTab()); - if (utilTrans.clearTable2(GETNDB(step), records) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runClearResTable(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - const NdbDictionary::Table* pResTab = - GETNDB(step)->getDictionary()->getTable(ctx->getProperty("ResultTabName", "NULL")); - - UtilTransactions utilTrans(*pResTab); - if (utilTrans.clearTable2(GETNDB(step), records) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runScanRead(NDBT_Context* ctx, NDBT_Step* step){ - int loops = ctx->getNumLoops(); - int records = ctx->getNumRecords(); - int parallelism = ctx->getProperty("Parallelism", 1); - - int i = 0; - HugoTransactions hugoTrans(*ctx->getTab()); - while (igetNumRecords(); - int parallelism = ctx->getProperty("Parallelism", 1); - const NdbDictionary::Table* pResTab = - NDBT_Table::discoverTableFromDb(GETNDB(step), - ctx->getProperty("ResultTabName", "NULL")); - - HugoTransactions hugoTrans(*pResTab); - if (hugoTrans.scanReadRecords(GETNDB(step), records, 0, parallelism) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runCreateResultTable(NDBT_Context* ctx, NDBT_Step* step){ - - const NdbDictionary::Table* pTab = ctx->getTab(); - char newTabName[256]; - snprintf(newTabName, 256, "%s_RES", pTab->getName()); - ctx->setProperty("ResultTabName", newTabName); - - NdbDictionary::Table resTab(* pTab); - resTab.setName(newTabName); - - if (GETNDB(step)->getDictionary()->createTable(resTab) != 0){ - g_err << newTabName << " creation failed!"<< endl; - return NDBT_FAILED; - }else{ - g_info << newTabName << " created!"<< endl; - return NDBT_OK; - } -} - -int scanWithFilter(NDBT_Context* ctx, NDBT_Step* step, ScanFilter& filt){ - int records = ctx->getNumRecords(); - const char* resTabName = ctx->getProperty("ResultTabName", "NULL"); - if (strcmp(resTabName, "NULL") == 0) - return NDBT_FAILED; - const NdbDictionary::Table* pTab = ctx->getTab(); - const NdbDictionary::Table* pResTab = NDBT_Table::discoverTableFromDb(GETNDB(step), resTabName); - if (pResTab == NULL) - return NDBT_FAILED; - - ScanInterpretTest interpretTest(*pTab, *pResTab); - if (interpretTest.scanRead(GETNDB(step), - records, - 16, - filt) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} -int runScanLessThan(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - LessThanFilter filt(records); - return scanWithFilter(ctx, step, filt); -} -int runScanEqual(NDBT_Context* ctx, NDBT_Step* step){ - EqualFilter filt; - return scanWithFilter(ctx, step, filt); -} - -int scanVerifyWithFilter(NDBT_Context* ctx, NDBT_Step* step, ScanFilter& filt){ - int records = ctx->getNumRecords(); - const char* resTabName = ctx->getProperty("ResultTabName", "NULL"); - if (strcmp(resTabName, "NULL") == 0) - return NDBT_FAILED; - const NdbDictionary::Table* pTab = ctx->getTab(); - const NdbDictionary::Table* pResTab = NDBT_Table::discoverTableFromDb(GETNDB(step), resTabName); - if (pResTab == NULL) - return NDBT_FAILED; - - ScanInterpretTest interpretTest(*pTab, *pResTab); - if (interpretTest.scanReadVerify(GETNDB(step), - records, - 16, - filt) != NDBT_OK){ - return NDBT_FAILED; - } - return NDBT_OK; -} -int runScanLessThanVerify(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - LessThanFilter filt(records); - return scanVerifyWithFilter(ctx, step, filt); -} -int runScanEqualVerify(NDBT_Context* ctx, NDBT_Step* step){ - EqualFilter filt; - return scanVerifyWithFilter(ctx, step, filt); -} - -int runScanEqualLoop(NDBT_Context* ctx, NDBT_Step* step){ - int loops = ctx->getNumLoops(); - int l = 0; - EqualFilter filt; - while(l < loops){ - if (scanWithFilter(ctx, step, filt) != NDBT_OK) - return NDBT_FAILED; - if (runClearResTable(ctx, step) != NDBT_OK) - return NDBT_FAILED; - l++; - } - return NDBT_OK; -} - - -int runScanEqualVerifyLoop(NDBT_Context* ctx, NDBT_Step* step){ - int loops = ctx->getNumLoops(); - int l = 0; - EqualFilter filt; - while(l < loops){ - if (scanWithFilter(ctx, step, filt) != NDBT_OK) - return NDBT_FAILED; - if (scanVerifyWithFilter(ctx, step, filt) != NDBT_OK) - return NDBT_FAILED; - if (runClearResTable(ctx, step) != NDBT_OK) - return NDBT_FAILED; - l++; - } - return NDBT_OK; -} - -int runScanLessThanLoop(NDBT_Context* ctx, NDBT_Step* step){ - int loops = ctx->getNumLoops(); - int records = ctx->getNumRecords(); - int l = 0; - LessThanFilter filt(records); - while(l < loops){ - if (scanWithFilter(ctx, step, filt) != NDBT_OK) - return NDBT_FAILED; - if (runClearResTable(ctx, step) != NDBT_OK) - return NDBT_FAILED; - l++; - } - return NDBT_OK; -} - -NDBT_TESTSUITE(testScanInterpreter); -TESTCASE("ScanLessThan", - "Read all records in table TX with attrX less "\ - "than a value and store the resultset in TX_RES."\ - "Then compare records in TX_RES with records in TX."){ - // TABLE("T1"); - // TABLE("T2"); - INITIALIZER(runLoadTable); - INITIALIZER(runCreateResultTable); - STEP(runScanLessThan); - VERIFIER(runScanLessThanVerify); - FINALIZER(runClearTable); - FINALIZER(runClearResTable); -} -TESTCASE("ScanEqual", - "Read all records in table TX with attrX equal "\ - "to a value and store the resultset in TX_RES."\ - "Then compare records in TX_RES with records in TX."){ - // TABLE("T1"); - // TABLE("T2"); - INITIALIZER(runLoadTable); - INITIALIZER(runCreateResultTable); - STEP(runScanEqual); - VERIFIER(runScanEqualVerify); - FINALIZER(runClearTable); - FINALIZER(runClearResTable); -} -TESTCASE("ScanEqualLoop", - "Scan all records in TX equal to a value."\ - "Do this loop number of times"){ - // TABLE("T1"); - // TABLE("T2"); - INITIALIZER(runLoadTable); - INITIALIZER(runCreateResultTable); - STEP(runScanEqualLoop); - FINALIZER(runClearTable); - FINALIZER(runClearResTable); -} -TESTCASE("ScanEqualVerifyLoop", - "Scan all records in TX equal to a value."\ - "Verify record in TX_RES table"\ - "Do this loop number of times"){ - // TABLE("T1"); - // TABLE("T2"); - INITIALIZER(runLoadTable); - INITIALIZER(runCreateResultTable); - STEP(runScanEqualVerifyLoop); - FINALIZER(runClearTable); - FINALIZER(runClearResTable); -} -TESTCASE("ScanLessThanLoop", - "Scan all records in TX less than a value."\ - "Do this loop number of times"){ - // TABLE("T1"); - // TABLE("T2"); - INITIALIZER(runLoadTable); - INITIALIZER(runCreateResultTable); - STEP(runScanLessThanLoop); - FINALIZER(runClearTable); - FINALIZER(runClearResTable); -} -NDBT_TESTSUITE_END(testScanInterpreter); - -int main(int argc, const char** argv){ - return testScanInterpreter.execute(argc, argv); -} - - - diff --git a/ndb/test/ndbapi/testSystemRestart.cpp b/ndb/test/ndbapi/testSystemRestart.cpp new file mode 100644 index 00000000000..1b8a35487cb --- /dev/null +++ b/ndb/test/ndbapi/testSystemRestart.cpp @@ -0,0 +1,942 @@ +/* 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 */ + +#include +#include +#include +#include +#include +#include +#include + +int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ + + int records = ctx->getNumRecords(); + HugoTransactions hugoTrans(*ctx->getTab()); + if (hugoTrans.loadTable(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +#define CHECK(b) if (!(b)) { \ + g_err << "ERR: "<< step->getName() \ + << " failed on line " << __LINE__ << endl; \ + result = NDBT_FAILED; \ + continue; } + +int runSystemRestart1(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; + int timeout = 300; + Uint32 loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + int count; + NdbRestarter restarter; + Uint32 i = 1; + + UtilTransactions utilTrans(*ctx->getTab()); + HugoTransactions hugoTrans(*ctx->getTab()); + while(i<=loops && result != NDBT_FAILED){ + + ndbout << "Loop " << i << "/"<< loops <<" started" << endl; + /* + 1. Load data + 2. Restart cluster and verify records + 3. Update records + 4. Restart cluster and verify records + 5. Delete half of the records + 6. Restart cluster and verify records + 7. Delete all records + 8. Restart cluster and verify records + 9. Insert, update, delete records + 10. Restart cluster and verify records + 11. Insert, update, delete records + 12. Restart cluster with error insert 5020 and verify records + */ + ndbout << "Loading records..." << endl; + CHECK(hugoTrans.loadTable(pNdb, records) == 0); + + ndbout << "Restarting cluster" << endl; + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(pNdb->waitUntilReady(timeout) == 0); + + ndbout << "Verifying records..." << endl; + CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == records); + + ndbout << "Updating records..." << endl; + CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); + + ndbout << "Restarting cluster..." << endl; + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(pNdb->waitUntilReady(timeout) == 0); + + ndbout << "Verifying records..." << endl; + CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == records); + + ndbout << "Deleting 50% of records..." << endl; + CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); + + ndbout << "Restarting cluster..." << endl; + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(pNdb->waitUntilReady(timeout) == 0); + + ndbout << "Verifying records..." << endl; + CHECK(hugoTrans.scanReadRecords(pNdb, records/2, 0, 64) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == (records/2)); + + ndbout << "Deleting all records..." << endl; + CHECK(utilTrans.clearTable(pNdb, records/2) == 0); + + ndbout << "Restarting cluster..." << endl; + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(pNdb->waitUntilReady(timeout) == 0); + + ndbout << "Verifying records..." << endl; + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == 0); + + ndbout << "Doing it all..." << endl; + CHECK(hugoTrans.loadTable(pNdb, records) == 0); + CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); + CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); + CHECK(hugoTrans.scanUpdateRecords(pNdb, records) == 0); + CHECK(utilTrans.clearTable(pNdb, records) == 0); + CHECK(hugoTrans.loadTable(pNdb, records) == 0); + CHECK(utilTrans.clearTable(pNdb, records) == 0); + CHECK(hugoTrans.loadTable(pNdb, records) == 0); + CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); + CHECK(utilTrans.clearTable(pNdb, records) == 0); + + ndbout << "Restarting cluster..." << endl; + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(pNdb->waitUntilReady(timeout) == 0); + + ndbout << "Verifying records..." << endl; + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == 0); + + ndbout << "Doing it all..." << endl; + CHECK(hugoTrans.loadTable(pNdb, records) == 0); + CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); + CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); + CHECK(hugoTrans.scanUpdateRecords(pNdb, records) == 0); + CHECK(utilTrans.clearTable(pNdb, records) == 0); + CHECK(hugoTrans.loadTable(pNdb, records) == 0); + CHECK(utilTrans.clearTable(pNdb, records) == 0); + + ndbout << "Restarting cluster with error insert 5020..." << endl; + CHECK(restarter.restartAll(false, true) == 0); + CHECK(restarter.waitClusterNoStart(timeout) == 0); + CHECK(restarter.insertErrorInAllNodes(5020) == 0); + CHECK(restarter.startAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(pNdb->waitUntilReady(timeout) == 0); + + i++; + } + + ndbout << "runSystemRestart1 finished" << endl; + + return result; +} + +int runSystemRestart2(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; +/// int timeout = 300; + int timeout = 120; + Uint32 loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + int count; + NdbRestarter restarter; + Uint32 i = 1; + + UtilTransactions utilTrans(*ctx->getTab()); + HugoTransactions hugoTrans(*ctx->getTab()); + while(i<=loops && result != NDBT_FAILED && !ctx->isTestStopped()){ + + ndbout << "Loop " << i << "/"<< loops <<" started" << endl; + /* Use error 7070 to set time between LCP to it's min value + 1. Load data + 2. Restart cluster and verify records + 3. Update records + 4. Restart cluster and verify records + 5. Delete half of the records + 6. Restart cluster and verify records + 7. Delete all records + 8. Restart cluster and verify records + 9. Insert, update, delete records + 10. Restart cluster and verify records + */ + int val = DumpStateOrd::DihMinTimeBetweenLCP; + CHECK(restarter.dumpStateAllNodes(&val, 1) == 0); + + ndbout << "Loading records..." << endl; + CHECK(hugoTrans.loadTable(pNdb, records) == 0); + + ndbout << "Restarting cluster" << endl; + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + { + int val = DumpStateOrd::DihMinTimeBetweenLCP; + CHECK(restarter.dumpStateAllNodes(&val, 1) == 0); + } + CHECK(pNdb->waitUntilReady(timeout) == 0); + + ndbout << "Verifying records..." << endl; + CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == records); + + ndbout << "Updating records..." << endl; + CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); + + ndbout << "Restarting cluster..." << endl; + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + { + int val = DumpStateOrd::DihMinTimeBetweenLCP; + CHECK(restarter.dumpStateAllNodes(&val, 1) == 0); + } + CHECK(pNdb->waitUntilReady(timeout) == 0); + + ndbout << "Verifying records..." << endl; + CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == records); + + ndbout << "Deleting 50% of records..." << endl; + CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); + + ndbout << "Restarting cluster..." << endl; + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + { + int val = DumpStateOrd::DihMinTimeBetweenLCP; + CHECK(restarter.dumpStateAllNodes(&val, 1) == 0); + } + CHECK(pNdb->waitUntilReady(timeout) == 0); + + ndbout << "Verifying records..." << endl; + CHECK(hugoTrans.scanReadRecords(pNdb, records/2, 0, 64) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == (records/2)); + + ndbout << "Deleting all records..." << endl; + CHECK(utilTrans.clearTable(pNdb, records/2) == 0); + + ndbout << "Restarting cluster..." << endl; + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + { + int val = DumpStateOrd::DihMinTimeBetweenLCP; + CHECK(restarter.dumpStateAllNodes(&val, 1) == 0); + } + CHECK(pNdb->waitUntilReady(timeout) == 0); + + ndbout << "Verifying records..." << endl; + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == 0); + + ndbout << "Doing it all..." << endl; + CHECK(hugoTrans.loadTable(pNdb, records) == 0); + CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); + CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); + CHECK(hugoTrans.scanUpdateRecords(pNdb, records) == 0); + CHECK(utilTrans.clearTable(pNdb, records) == 0); + CHECK(hugoTrans.loadTable(pNdb, records) == 0); + CHECK(utilTrans.clearTable(pNdb, records) == 0); + CHECK(hugoTrans.loadTable(pNdb, records) == 0); + CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); + CHECK(utilTrans.clearTable(pNdb, records) == 0); + + ndbout << "Restarting cluster..." << endl; + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + { + int val = DumpStateOrd::DihMinTimeBetweenLCP; + CHECK(restarter.dumpStateAllNodes(&val, 1) == 0); + } + CHECK(pNdb->waitUntilReady(timeout) == 0); + + ndbout << "Verifying records..." << endl; + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == 0); + + i++; + } + + ndbout << "runSystemRestart2 finished" << endl; + + return result; +} + +int runSystemRestartTestUndoLog(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; + int timeout = 300; + Uint32 loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + int count; + NdbRestarter restarter; + Uint32 i = 1; + + int dump7080[2]; + dump7080[0] = 7080; + dump7080[1] = ctx->getTab()->getTableId(); + + UtilTransactions utilTrans(*ctx->getTab()); + HugoTransactions hugoTrans(*ctx->getTab()); + while(i<=loops && result != NDBT_FAILED){ + + ndbout << "Loop " << i << "/"<< loops <<" started" << endl; + /* + 1. Start LCP, turn on undologging but delay write of datapages. + 2. Insert, update, delete records + 3. Complete writing of data pages and finish LCP. + 4. Restart cluster and verify records + */ + // Use dump state 7080 to delay writing of datapages + // for the current table + ndbout << "Dump state: "<waitUntilReady(timeout) == 0); + + ndbout << "Verifying records..." << endl; + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == 0); + + // Use dump state 7080 to delay writing of datapages + // for the current table + ndbout << "Dump state: "<waitUntilReady(timeout) == 0); + + ndbout << "Verifying records..." << endl; + CHECK(hugoTrans.scanReadRecords(pNdb, records/2, 0, 64) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == (records/2)); + CHECK(utilTrans.clearTable(pNdb, records) == 0); + + i++; + } + + ndbout << "runSystemRestartTestUndoLog finished" << endl; + + return result; +} + +int runSystemRestartTestFullDb(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; + int timeout = 300; + Uint32 loops = ctx->getNumLoops(); + int count1, count2; + NdbRestarter restarter; + Uint32 i = 1; + + UtilTransactions utilTrans(*ctx->getTab()); + HugoTransactions hugoTrans(*ctx->getTab()); + while(i<=loops && result != NDBT_FAILED){ + + ndbout << "Loop " << i << "/"<< loops <<" started" << endl; + /* + 1. Load data until db reports it's full + 2. Restart cluster and verify records + */ + ndbout << "Filling up table..." << endl; + CHECK(hugoTrans.fillTable(pNdb) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count1) == 0); + ndbout << "Db is full. Table has "<waitUntilReady(timeout) == 0); + + ndbout << "Verifying records..." << endl; + CHECK(hugoTrans.scanReadRecords(pNdb, count1) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count2) == 0); + CHECK(count1 == count2); + + ndbout << "Deleting all records..." << endl; + CHECK(utilTrans.clearTable2(pNdb, count1) == 0); + + ndbout << "Restarting cluster..." << endl; + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(pNdb->waitUntilReady(timeout) == 0); + + ndbout << "Verifying records..." << endl; + CHECK(utilTrans.selectCount(pNdb, 64, &count1) == 0); + CHECK(count1 == 0); + + i++; + } + + ndbout << "runSystemRestartTestFullDb finished" << endl; + + return result; +} + +int runSystemRestart3(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; + int timeout = 300; + Uint32 loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + int count; + NdbRestarter restarter; + Uint32 i = 1; + + const Uint32 nodeCount = restarter.getNumDbNodes(); + if(nodeCount < 2){ + g_info << "SR3 - Needs atleast 2 nodes to test" << endl; + return NDBT_OK; + } + + Vector nodeIds; + for(Uint32 i = 0; igetTab()); + HugoTransactions hugoTrans(*ctx->getTab()); + + while(i<=loops && result != NDBT_FAILED){ + + g_info << "Loop " << i << "/"<< loops <<" started" << endl; + /** + * 1. Load data + * 2. Restart 1 node -nostart + * 3. Update records + * 4. Restart cluster and verify records + * 5. Restart 1 node -nostart + * 6. Delete half of the records + * 7. Restart cluster and verify records + * 8. Restart 1 node -nostart + * 9. Delete all records + * 10. Restart cluster and verify records + */ + g_info << "Loading records..." << endl; + CHECK(hugoTrans.loadTable(pNdb, records) == 0); + + /*** 1 ***/ + g_info << "1 - Stopping one node" << endl; + CHECK(restarter.restartOneDbNode(nodeIds[currentRestartNodeIndex], + false, + true, + false) == 0); + currentRestartNodeIndex = (currentRestartNodeIndex + 1 ) % nodeCount; + + g_info << "Updating records..." << endl; + CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); + + g_info << "Restarting cluster..." << endl; + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(pNdb->waitUntilReady(timeout) == 0); + + g_info << "Verifying records..." << endl; + CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == records); + + g_info << "2 - Stopping one node" << endl; + CHECK(restarter.restartOneDbNode(nodeIds[currentRestartNodeIndex], + false, + true, + false) == 0); + currentRestartNodeIndex = (currentRestartNodeIndex + 1 ) % nodeCount; + + g_info << "Deleting 50% of records..." << endl; + CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); + + g_info << "Restarting cluster..." << endl; + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(pNdb->waitUntilReady(timeout) == 0); + + g_info << "Verifying records..." << endl; + CHECK(hugoTrans.scanReadRecords(pNdb, records/2, 0, 64) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == (records/2)); + + g_info << "3 - Stopping one node" << endl; + CHECK(restarter.restartOneDbNode(nodeIds[currentRestartNodeIndex], + false, + true, + false) == 0); + currentRestartNodeIndex = (currentRestartNodeIndex + 1 ) % nodeCount; + g_info << "Deleting all records..." << endl; + CHECK(utilTrans.clearTable(pNdb, records/2) == 0); + + g_info << "Restarting cluster..." << endl; + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(pNdb->waitUntilReady(timeout) == 0); + + ndbout << "Verifying records..." << endl; + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == 0); + + i++; + } + + g_info << "runSystemRestart3 finished" << endl; + + return result; +} + +int runSystemRestart4(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; + int timeout = 300; + Uint32 loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + int count; + NdbRestarter restarter; + Uint32 i = 1; + + const Uint32 nodeCount = restarter.getNumDbNodes(); + if(nodeCount < 2){ + g_info << "SR4 - Needs atleast 2 nodes to test" << endl; + return NDBT_OK; + } + + Vector nodeIds; + for(Uint32 i = 0; igetTab()); + HugoTransactions hugoTrans(*ctx->getTab()); + + { + int val = DumpStateOrd::DihMinTimeBetweenLCP; + if(restarter.dumpStateAllNodes(&val, 1) != 0){ + g_err << "ERR: "<< step->getName() + << " failed on line " << __LINE__ << endl; + return NDBT_FAILED; + } + } + + while(i<=loops && result != NDBT_FAILED){ + + g_info << "Loop " << i << "/"<< loops <<" started" << endl; + /** + * 1. Load data + * 2. Restart 1 node -nostart + * 3. Update records + * 4. Restart cluster and verify records + * 5. Restart 1 node -nostart + * 6. Delete half of the records + * 7. Restart cluster and verify records + * 8. Restart 1 node -nostart + * 9. Delete all records + * 10. Restart cluster and verify records + */ + g_info << "Loading records..." << endl; + CHECK(hugoTrans.loadTable(pNdb, records) == 0); + + /*** 1 ***/ + g_info << "1 - Stopping one node" << endl; + CHECK(restarter.restartOneDbNode(nodeIds[currentRestartNodeIndex], + false, + true, + false) == 0); + currentRestartNodeIndex = (currentRestartNodeIndex + 1 ) % nodeCount; + + g_info << "Updating records..." << endl; + CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); + + g_info << "Restarting cluster..." << endl; + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + { + int val = DumpStateOrd::DihMinTimeBetweenLCP; + CHECK(restarter.dumpStateAllNodes(&val, 1) == 0); + } + CHECK(pNdb->waitUntilReady(timeout) == 0); + + g_info << "Verifying records..." << endl; + CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == records); + + g_info << "2 - Stopping one node" << endl; + CHECK(restarter.restartOneDbNode(nodeIds[currentRestartNodeIndex], + false, + true, + false) == 0); + currentRestartNodeIndex = (currentRestartNodeIndex + 1 ) % nodeCount; + + g_info << "Deleting 50% of records..." << endl; + CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); + + g_info << "Restarting cluster..." << endl; + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + { + int val = DumpStateOrd::DihMinTimeBetweenLCP; + CHECK(restarter.dumpStateAllNodes(&val, 1) == 0); + } + CHECK(pNdb->waitUntilReady(timeout) == 0); + + g_info << "Verifying records..." << endl; + CHECK(hugoTrans.scanReadRecords(pNdb, records/2, 0, 64) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == (records/2)); + + g_info << "3 - Stopping one node" << endl; + CHECK(restarter.restartOneDbNode(nodeIds[currentRestartNodeIndex], + false, + true, + false) == 0); + currentRestartNodeIndex = (currentRestartNodeIndex + 1 ) % nodeCount; + g_info << "Deleting all records..." << endl; + CHECK(utilTrans.clearTable(pNdb, records/2) == 0); + + g_info << "Restarting cluster..." << endl; + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + { + int val = DumpStateOrd::DihMinTimeBetweenLCP; + CHECK(restarter.dumpStateAllNodes(&val, 1) == 0); + } + CHECK(pNdb->waitUntilReady(timeout) == 0); + + ndbout << "Verifying records..." << endl; + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == 0); + + i++; + } + + g_info << "runSystemRestart4 finished" << endl; + + return result; +} + +int runSystemRestart5(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; + int timeout = 300; + Uint32 loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + int count; + NdbRestarter restarter; + Uint32 i = 1; + + const Uint32 nodeCount = restarter.getNumDbNodes(); + if(nodeCount < 2){ + g_info << "SR5 - Needs atleast 2 nodes to test" << endl; + return NDBT_OK; + } + + Vector nodeIds; + for(Uint32 i = 0; igetTab()); + HugoTransactions hugoTrans(*ctx->getTab()); + + { + int val = DumpStateOrd::DihMinTimeBetweenLCP; + if(restarter.dumpStateAllNodes(&val, 1) != 0){ + g_err << "ERR: "<< step->getName() + << " failed on line " << __LINE__ << endl; + return NDBT_FAILED; + } + } + + while(i<=loops && result != NDBT_FAILED){ + + g_info << "Loop " << i << "/"<< loops <<" started" << endl; + /** + * 1. Load data + * 2. Restart 1 node -nostart + * 3. Update records + * 4. Restart cluster and verify records + * 5. Restart 1 node -nostart + * 6. Delete half of the records + * 7. Restart cluster and verify records + * 8. Restart 1 node -nostart + * 9. Delete all records + * 10. Restart cluster and verify records + */ + g_info << "Loading records..." << endl; + hugoTrans.loadTable(pNdb, records); + + /*** 1 ***/ + g_info << "1 - Stopping one node" << endl; + CHECK(restarter.restartOneDbNode(nodeIds[currentRestartNodeIndex], + false, + true, + false) == 0); + currentRestartNodeIndex = (currentRestartNodeIndex + 1 ) % nodeCount; + + g_info << "Updating records..." << endl; + hugoTrans.pkUpdateRecords(pNdb, records); + + g_info << "Restarting cluster..." << endl; + CHECK(restarter.restartAll(false, false, true) == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + { + int val = DumpStateOrd::DihMinTimeBetweenLCP; + CHECK(restarter.dumpStateAllNodes(&val, 1) == 0); + } + CHECK(pNdb->waitUntilReady(timeout) == 0); + + g_info << "Verifying records..." << endl; + hugoTrans.pkReadRecords(pNdb, records); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + //CHECK(count == records); + + g_info << "2 - Stopping one node" << endl; + CHECK(restarter.restartOneDbNode(nodeIds[currentRestartNodeIndex], + false, + true, + false) == 0); + currentRestartNodeIndex = (currentRestartNodeIndex + 1 ) % nodeCount; + + g_info << "Deleting 50% of records..." << endl; + hugoTrans.pkDelRecords(pNdb, records/2); + + g_info << "Restarting cluster..." << endl; + CHECK(restarter.restartAll(false, false, true) == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + { + int val = DumpStateOrd::DihMinTimeBetweenLCP; + CHECK(restarter.dumpStateAllNodes(&val, 1) == 0); + } + CHECK(pNdb->waitUntilReady(timeout) == 0); + + g_info << "Verifying records..." << endl; + hugoTrans.scanReadRecords(pNdb, records/2, 0, 64); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + //CHECK(count == (records/2)); + + g_info << "3 - Stopping one node" << endl; + CHECK(restarter.restartOneDbNode(nodeIds[currentRestartNodeIndex], + false, + true, + false) == 0); + currentRestartNodeIndex = (currentRestartNodeIndex + 1 ) % nodeCount; + g_info << "Deleting all records..." << endl; + utilTrans.clearTable(pNdb, records/2); + + g_info << "Restarting cluster..." << endl; + CHECK(restarter.restartAll(false, false, true) == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + { + int val = DumpStateOrd::DihMinTimeBetweenLCP; + CHECK(restarter.dumpStateAllNodes(&val, 1) == 0); + } + CHECK(pNdb->waitUntilReady(timeout) == 0); + + ndbout << "Verifying records..." << endl; + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + //CHECK(count == 0); + + CHECK(utilTrans.clearTable(pNdb) == 0); + i++; + } + + g_info << "runSystemRestart5 finished" << endl; + + return result; +} + +int runWaitStarted(NDBT_Context* ctx, NDBT_Step* step){ + + NdbRestarter restarter; + restarter.waitClusterStarted(300); + + NdbSleep_SecSleep(3); + return NDBT_OK; +} + +int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + + UtilTransactions utilTrans(*ctx->getTab()); + if (utilTrans.clearTable2(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + + +NDBT_TESTSUITE(testSystemRestart); +TESTCASE("SR1", + "Basic system restart test. Focus on testing restart from REDO log.\n" + "NOTE! Time between lcp's and gcp's should be left at default, \n" + "so that Ndb uses the Redo log when restarting\n" + "1. Load records\n" + "2. Restart cluster and verify records \n" + "3. Update records\n" + "4. Restart cluster and verify records \n" + "5. Delete half of the records \n" + "6. Restart cluster and verify records \n" + "7. Delete all records \n" + "8. Restart cluster and verify records \n" + "9. Insert, update, delete records \n" + "10. Restart cluster and verify records\n" + "11. Insert, update, delete records \n" + "12. Restart cluster with error insert 5020 and verify records\n"){ + INITIALIZER(runWaitStarted); + STEP(runSystemRestart1); + FINALIZER(runClearTable); +} +TESTCASE("SR2", + "Basic system restart test. Focus on testing restart from LCP\n" + "NOTE! Time between lcp's is automatically set to it's min value\n" + "so that Ndb uses LCP's when restarting.\n" + "1. Load records\n" + "2. Restart cluster and verify records \n" + "3. Update records\n" + "4. Restart cluster and verify records \n" + "5. Delete half of the records \n" + "6. Restart cluster and verify records \n" + "7. Delete all records \n" + "8. Restart cluster and verify records \n" + "9. Insert, update, delete records \n" + "10. Restart cluster and verify records\n"){ + INITIALIZER(runWaitStarted); + STEP(runSystemRestart2); + FINALIZER(runClearTable); +} +TESTCASE("SR_UNDO", + "System restart test. Focus on testing of undologging\n" + "in DBACC and DBTUP.\n" + "This is done by starting a LCP, turn on undologging \n" + "but don't start writing the datapages. This will force all\n" + "operations to be written into the undolog.\n" + "Then write datapages and complete LCP.\n" + "Restart the system\n"){ + INITIALIZER(runWaitStarted); + STEP(runSystemRestartTestUndoLog); + FINALIZER(runClearTable); +} +TESTCASE("SR_FULLDB", + "System restart test. Test to restart when DB is full.\n"){ + INITIALIZER(runWaitStarted); + STEP(runSystemRestartTestFullDb); + FINALIZER(runClearTable); +} +TESTCASE("SR3", + "System restart test. Focus on testing restart from with\n" + "not all nodes alive when system went down\n" + "* 1. Load data\n" + "* 2. Restart 1 node -nostart\n" + "* 3. Update records\n" + "* 4. Restart cluster and verify records\n" + "* 5. Restart 1 node -nostart\n" + "* 6. Delete half of the records\n" + "* 7. Restart cluster and verify records\n" + "* 8. Restart 1 node -nostart\n" + "* 9. Delete all records\n" + "* 10. Restart cluster and verify records\n"){ + INITIALIZER(runWaitStarted); + STEP(runSystemRestart3); + FINALIZER(runClearTable); +} +TESTCASE("SR4", + "System restart test. Focus on testing restart from with\n" + "not all nodes alive when system went down but running LCP at\n" + "high speed so that sometimes a TO is required to start cluster\n" + "* 1. Load data\n" + "* 2. Restart 1 node -nostart\n" + "* 3. Update records\n" + "* 4. Restart cluster and verify records\n" + "* 5. Restart 1 node -nostart\n" + "* 6. Delete half of the records\n" + "* 7. Restart cluster and verify records\n" + "* 8. Restart 1 node -nostart\n" + "* 9. Delete all records\n" + "* 10. Restart cluster and verify records\n"){ + INITIALIZER(runWaitStarted); + STEP(runSystemRestart4); + FINALIZER(runClearTable); +} +TESTCASE("SR5", + "As SR4 but making restart aborts\n" + "* 1. Load data\n" + "* 2. Restart 1 node -nostart\n" + "* 3. Update records\n" + "* 4. Restart cluster and verify records\n" + "* 5. Restart 1 node -nostart\n" + "* 6. Delete half of the records\n" + "* 7. Restart cluster and verify records\n" + "* 8. Restart 1 node -nostart\n" + "* 9. Delete all records\n" + "* 10. Restart cluster and verify records\n"){ + INITIALIZER(runWaitStarted); + STEP(runSystemRestart5); + FINALIZER(runClearTable); +} +NDBT_TESTSUITE_END(testSystemRestart); + +int main(int argc, const char** argv){ + return testSystemRestart.execute(argc, argv); +} + + diff --git a/ndb/test/ndbapi/testSystemRestart/Makefile b/ndb/test/ndbapi/testSystemRestart/Makefile deleted file mode 100644 index 7a306eb313d..00000000000 --- a/ndb/test/ndbapi/testSystemRestart/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -include .defs.mk - -TYPE = ndbapitest - -BIN_TARGET = testSystemRestart - -SOURCES = testSystemRestart.cpp - -CFLAGS_testSystemRestart.cpp := -I$(call fixpath,$(NDB_TOP)/include/kernel) - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/testSystemRestart/testSystemRestart.cpp b/ndb/test/ndbapi/testSystemRestart/testSystemRestart.cpp deleted file mode 100644 index 1b8a35487cb..00000000000 --- a/ndb/test/ndbapi/testSystemRestart/testSystemRestart.cpp +++ /dev/null @@ -1,942 +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 */ - -#include -#include -#include -#include -#include -#include -#include - -int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ - - int records = ctx->getNumRecords(); - HugoTransactions hugoTrans(*ctx->getTab()); - if (hugoTrans.loadTable(GETNDB(step), records) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -#define CHECK(b) if (!(b)) { \ - g_err << "ERR: "<< step->getName() \ - << " failed on line " << __LINE__ << endl; \ - result = NDBT_FAILED; \ - continue; } - -int runSystemRestart1(NDBT_Context* ctx, NDBT_Step* step){ - Ndb* pNdb = GETNDB(step); - int result = NDBT_OK; - int timeout = 300; - Uint32 loops = ctx->getNumLoops(); - int records = ctx->getNumRecords(); - int count; - NdbRestarter restarter; - Uint32 i = 1; - - UtilTransactions utilTrans(*ctx->getTab()); - HugoTransactions hugoTrans(*ctx->getTab()); - while(i<=loops && result != NDBT_FAILED){ - - ndbout << "Loop " << i << "/"<< loops <<" started" << endl; - /* - 1. Load data - 2. Restart cluster and verify records - 3. Update records - 4. Restart cluster and verify records - 5. Delete half of the records - 6. Restart cluster and verify records - 7. Delete all records - 8. Restart cluster and verify records - 9. Insert, update, delete records - 10. Restart cluster and verify records - 11. Insert, update, delete records - 12. Restart cluster with error insert 5020 and verify records - */ - ndbout << "Loading records..." << endl; - CHECK(hugoTrans.loadTable(pNdb, records) == 0); - - ndbout << "Restarting cluster" << endl; - CHECK(restarter.restartAll() == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - CHECK(pNdb->waitUntilReady(timeout) == 0); - - ndbout << "Verifying records..." << endl; - CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0); - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == records); - - ndbout << "Updating records..." << endl; - CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); - - ndbout << "Restarting cluster..." << endl; - CHECK(restarter.restartAll() == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - CHECK(pNdb->waitUntilReady(timeout) == 0); - - ndbout << "Verifying records..." << endl; - CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0); - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == records); - - ndbout << "Deleting 50% of records..." << endl; - CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); - - ndbout << "Restarting cluster..." << endl; - CHECK(restarter.restartAll() == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - CHECK(pNdb->waitUntilReady(timeout) == 0); - - ndbout << "Verifying records..." << endl; - CHECK(hugoTrans.scanReadRecords(pNdb, records/2, 0, 64) == 0); - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == (records/2)); - - ndbout << "Deleting all records..." << endl; - CHECK(utilTrans.clearTable(pNdb, records/2) == 0); - - ndbout << "Restarting cluster..." << endl; - CHECK(restarter.restartAll() == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - CHECK(pNdb->waitUntilReady(timeout) == 0); - - ndbout << "Verifying records..." << endl; - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == 0); - - ndbout << "Doing it all..." << endl; - CHECK(hugoTrans.loadTable(pNdb, records) == 0); - CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); - CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); - CHECK(hugoTrans.scanUpdateRecords(pNdb, records) == 0); - CHECK(utilTrans.clearTable(pNdb, records) == 0); - CHECK(hugoTrans.loadTable(pNdb, records) == 0); - CHECK(utilTrans.clearTable(pNdb, records) == 0); - CHECK(hugoTrans.loadTable(pNdb, records) == 0); - CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); - CHECK(utilTrans.clearTable(pNdb, records) == 0); - - ndbout << "Restarting cluster..." << endl; - CHECK(restarter.restartAll() == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - CHECK(pNdb->waitUntilReady(timeout) == 0); - - ndbout << "Verifying records..." << endl; - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == 0); - - ndbout << "Doing it all..." << endl; - CHECK(hugoTrans.loadTable(pNdb, records) == 0); - CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); - CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); - CHECK(hugoTrans.scanUpdateRecords(pNdb, records) == 0); - CHECK(utilTrans.clearTable(pNdb, records) == 0); - CHECK(hugoTrans.loadTable(pNdb, records) == 0); - CHECK(utilTrans.clearTable(pNdb, records) == 0); - - ndbout << "Restarting cluster with error insert 5020..." << endl; - CHECK(restarter.restartAll(false, true) == 0); - CHECK(restarter.waitClusterNoStart(timeout) == 0); - CHECK(restarter.insertErrorInAllNodes(5020) == 0); - CHECK(restarter.startAll() == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - CHECK(pNdb->waitUntilReady(timeout) == 0); - - i++; - } - - ndbout << "runSystemRestart1 finished" << endl; - - return result; -} - -int runSystemRestart2(NDBT_Context* ctx, NDBT_Step* step){ - Ndb* pNdb = GETNDB(step); - int result = NDBT_OK; -/// int timeout = 300; - int timeout = 120; - Uint32 loops = ctx->getNumLoops(); - int records = ctx->getNumRecords(); - int count; - NdbRestarter restarter; - Uint32 i = 1; - - UtilTransactions utilTrans(*ctx->getTab()); - HugoTransactions hugoTrans(*ctx->getTab()); - while(i<=loops && result != NDBT_FAILED && !ctx->isTestStopped()){ - - ndbout << "Loop " << i << "/"<< loops <<" started" << endl; - /* Use error 7070 to set time between LCP to it's min value - 1. Load data - 2. Restart cluster and verify records - 3. Update records - 4. Restart cluster and verify records - 5. Delete half of the records - 6. Restart cluster and verify records - 7. Delete all records - 8. Restart cluster and verify records - 9. Insert, update, delete records - 10. Restart cluster and verify records - */ - int val = DumpStateOrd::DihMinTimeBetweenLCP; - CHECK(restarter.dumpStateAllNodes(&val, 1) == 0); - - ndbout << "Loading records..." << endl; - CHECK(hugoTrans.loadTable(pNdb, records) == 0); - - ndbout << "Restarting cluster" << endl; - CHECK(restarter.restartAll() == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - { - int val = DumpStateOrd::DihMinTimeBetweenLCP; - CHECK(restarter.dumpStateAllNodes(&val, 1) == 0); - } - CHECK(pNdb->waitUntilReady(timeout) == 0); - - ndbout << "Verifying records..." << endl; - CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0); - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == records); - - ndbout << "Updating records..." << endl; - CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); - - ndbout << "Restarting cluster..." << endl; - CHECK(restarter.restartAll() == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - { - int val = DumpStateOrd::DihMinTimeBetweenLCP; - CHECK(restarter.dumpStateAllNodes(&val, 1) == 0); - } - CHECK(pNdb->waitUntilReady(timeout) == 0); - - ndbout << "Verifying records..." << endl; - CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0); - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == records); - - ndbout << "Deleting 50% of records..." << endl; - CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); - - ndbout << "Restarting cluster..." << endl; - CHECK(restarter.restartAll() == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - { - int val = DumpStateOrd::DihMinTimeBetweenLCP; - CHECK(restarter.dumpStateAllNodes(&val, 1) == 0); - } - CHECK(pNdb->waitUntilReady(timeout) == 0); - - ndbout << "Verifying records..." << endl; - CHECK(hugoTrans.scanReadRecords(pNdb, records/2, 0, 64) == 0); - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == (records/2)); - - ndbout << "Deleting all records..." << endl; - CHECK(utilTrans.clearTable(pNdb, records/2) == 0); - - ndbout << "Restarting cluster..." << endl; - CHECK(restarter.restartAll() == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - { - int val = DumpStateOrd::DihMinTimeBetweenLCP; - CHECK(restarter.dumpStateAllNodes(&val, 1) == 0); - } - CHECK(pNdb->waitUntilReady(timeout) == 0); - - ndbout << "Verifying records..." << endl; - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == 0); - - ndbout << "Doing it all..." << endl; - CHECK(hugoTrans.loadTable(pNdb, records) == 0); - CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); - CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); - CHECK(hugoTrans.scanUpdateRecords(pNdb, records) == 0); - CHECK(utilTrans.clearTable(pNdb, records) == 0); - CHECK(hugoTrans.loadTable(pNdb, records) == 0); - CHECK(utilTrans.clearTable(pNdb, records) == 0); - CHECK(hugoTrans.loadTable(pNdb, records) == 0); - CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); - CHECK(utilTrans.clearTable(pNdb, records) == 0); - - ndbout << "Restarting cluster..." << endl; - CHECK(restarter.restartAll() == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - { - int val = DumpStateOrd::DihMinTimeBetweenLCP; - CHECK(restarter.dumpStateAllNodes(&val, 1) == 0); - } - CHECK(pNdb->waitUntilReady(timeout) == 0); - - ndbout << "Verifying records..." << endl; - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == 0); - - i++; - } - - ndbout << "runSystemRestart2 finished" << endl; - - return result; -} - -int runSystemRestartTestUndoLog(NDBT_Context* ctx, NDBT_Step* step){ - Ndb* pNdb = GETNDB(step); - int result = NDBT_OK; - int timeout = 300; - Uint32 loops = ctx->getNumLoops(); - int records = ctx->getNumRecords(); - int count; - NdbRestarter restarter; - Uint32 i = 1; - - int dump7080[2]; - dump7080[0] = 7080; - dump7080[1] = ctx->getTab()->getTableId(); - - UtilTransactions utilTrans(*ctx->getTab()); - HugoTransactions hugoTrans(*ctx->getTab()); - while(i<=loops && result != NDBT_FAILED){ - - ndbout << "Loop " << i << "/"<< loops <<" started" << endl; - /* - 1. Start LCP, turn on undologging but delay write of datapages. - 2. Insert, update, delete records - 3. Complete writing of data pages and finish LCP. - 4. Restart cluster and verify records - */ - // Use dump state 7080 to delay writing of datapages - // for the current table - ndbout << "Dump state: "<waitUntilReady(timeout) == 0); - - ndbout << "Verifying records..." << endl; - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == 0); - - // Use dump state 7080 to delay writing of datapages - // for the current table - ndbout << "Dump state: "<waitUntilReady(timeout) == 0); - - ndbout << "Verifying records..." << endl; - CHECK(hugoTrans.scanReadRecords(pNdb, records/2, 0, 64) == 0); - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == (records/2)); - CHECK(utilTrans.clearTable(pNdb, records) == 0); - - i++; - } - - ndbout << "runSystemRestartTestUndoLog finished" << endl; - - return result; -} - -int runSystemRestartTestFullDb(NDBT_Context* ctx, NDBT_Step* step){ - Ndb* pNdb = GETNDB(step); - int result = NDBT_OK; - int timeout = 300; - Uint32 loops = ctx->getNumLoops(); - int count1, count2; - NdbRestarter restarter; - Uint32 i = 1; - - UtilTransactions utilTrans(*ctx->getTab()); - HugoTransactions hugoTrans(*ctx->getTab()); - while(i<=loops && result != NDBT_FAILED){ - - ndbout << "Loop " << i << "/"<< loops <<" started" << endl; - /* - 1. Load data until db reports it's full - 2. Restart cluster and verify records - */ - ndbout << "Filling up table..." << endl; - CHECK(hugoTrans.fillTable(pNdb) == 0); - CHECK(utilTrans.selectCount(pNdb, 64, &count1) == 0); - ndbout << "Db is full. Table has "<waitUntilReady(timeout) == 0); - - ndbout << "Verifying records..." << endl; - CHECK(hugoTrans.scanReadRecords(pNdb, count1) == 0); - CHECK(utilTrans.selectCount(pNdb, 64, &count2) == 0); - CHECK(count1 == count2); - - ndbout << "Deleting all records..." << endl; - CHECK(utilTrans.clearTable2(pNdb, count1) == 0); - - ndbout << "Restarting cluster..." << endl; - CHECK(restarter.restartAll() == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - CHECK(pNdb->waitUntilReady(timeout) == 0); - - ndbout << "Verifying records..." << endl; - CHECK(utilTrans.selectCount(pNdb, 64, &count1) == 0); - CHECK(count1 == 0); - - i++; - } - - ndbout << "runSystemRestartTestFullDb finished" << endl; - - return result; -} - -int runSystemRestart3(NDBT_Context* ctx, NDBT_Step* step){ - Ndb* pNdb = GETNDB(step); - int result = NDBT_OK; - int timeout = 300; - Uint32 loops = ctx->getNumLoops(); - int records = ctx->getNumRecords(); - int count; - NdbRestarter restarter; - Uint32 i = 1; - - const Uint32 nodeCount = restarter.getNumDbNodes(); - if(nodeCount < 2){ - g_info << "SR3 - Needs atleast 2 nodes to test" << endl; - return NDBT_OK; - } - - Vector nodeIds; - for(Uint32 i = 0; igetTab()); - HugoTransactions hugoTrans(*ctx->getTab()); - - while(i<=loops && result != NDBT_FAILED){ - - g_info << "Loop " << i << "/"<< loops <<" started" << endl; - /** - * 1. Load data - * 2. Restart 1 node -nostart - * 3. Update records - * 4. Restart cluster and verify records - * 5. Restart 1 node -nostart - * 6. Delete half of the records - * 7. Restart cluster and verify records - * 8. Restart 1 node -nostart - * 9. Delete all records - * 10. Restart cluster and verify records - */ - g_info << "Loading records..." << endl; - CHECK(hugoTrans.loadTable(pNdb, records) == 0); - - /*** 1 ***/ - g_info << "1 - Stopping one node" << endl; - CHECK(restarter.restartOneDbNode(nodeIds[currentRestartNodeIndex], - false, - true, - false) == 0); - currentRestartNodeIndex = (currentRestartNodeIndex + 1 ) % nodeCount; - - g_info << "Updating records..." << endl; - CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); - - g_info << "Restarting cluster..." << endl; - CHECK(restarter.restartAll() == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - CHECK(pNdb->waitUntilReady(timeout) == 0); - - g_info << "Verifying records..." << endl; - CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0); - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == records); - - g_info << "2 - Stopping one node" << endl; - CHECK(restarter.restartOneDbNode(nodeIds[currentRestartNodeIndex], - false, - true, - false) == 0); - currentRestartNodeIndex = (currentRestartNodeIndex + 1 ) % nodeCount; - - g_info << "Deleting 50% of records..." << endl; - CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); - - g_info << "Restarting cluster..." << endl; - CHECK(restarter.restartAll() == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - CHECK(pNdb->waitUntilReady(timeout) == 0); - - g_info << "Verifying records..." << endl; - CHECK(hugoTrans.scanReadRecords(pNdb, records/2, 0, 64) == 0); - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == (records/2)); - - g_info << "3 - Stopping one node" << endl; - CHECK(restarter.restartOneDbNode(nodeIds[currentRestartNodeIndex], - false, - true, - false) == 0); - currentRestartNodeIndex = (currentRestartNodeIndex + 1 ) % nodeCount; - g_info << "Deleting all records..." << endl; - CHECK(utilTrans.clearTable(pNdb, records/2) == 0); - - g_info << "Restarting cluster..." << endl; - CHECK(restarter.restartAll() == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - CHECK(pNdb->waitUntilReady(timeout) == 0); - - ndbout << "Verifying records..." << endl; - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == 0); - - i++; - } - - g_info << "runSystemRestart3 finished" << endl; - - return result; -} - -int runSystemRestart4(NDBT_Context* ctx, NDBT_Step* step){ - Ndb* pNdb = GETNDB(step); - int result = NDBT_OK; - int timeout = 300; - Uint32 loops = ctx->getNumLoops(); - int records = ctx->getNumRecords(); - int count; - NdbRestarter restarter; - Uint32 i = 1; - - const Uint32 nodeCount = restarter.getNumDbNodes(); - if(nodeCount < 2){ - g_info << "SR4 - Needs atleast 2 nodes to test" << endl; - return NDBT_OK; - } - - Vector nodeIds; - for(Uint32 i = 0; igetTab()); - HugoTransactions hugoTrans(*ctx->getTab()); - - { - int val = DumpStateOrd::DihMinTimeBetweenLCP; - if(restarter.dumpStateAllNodes(&val, 1) != 0){ - g_err << "ERR: "<< step->getName() - << " failed on line " << __LINE__ << endl; - return NDBT_FAILED; - } - } - - while(i<=loops && result != NDBT_FAILED){ - - g_info << "Loop " << i << "/"<< loops <<" started" << endl; - /** - * 1. Load data - * 2. Restart 1 node -nostart - * 3. Update records - * 4. Restart cluster and verify records - * 5. Restart 1 node -nostart - * 6. Delete half of the records - * 7. Restart cluster and verify records - * 8. Restart 1 node -nostart - * 9. Delete all records - * 10. Restart cluster and verify records - */ - g_info << "Loading records..." << endl; - CHECK(hugoTrans.loadTable(pNdb, records) == 0); - - /*** 1 ***/ - g_info << "1 - Stopping one node" << endl; - CHECK(restarter.restartOneDbNode(nodeIds[currentRestartNodeIndex], - false, - true, - false) == 0); - currentRestartNodeIndex = (currentRestartNodeIndex + 1 ) % nodeCount; - - g_info << "Updating records..." << endl; - CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); - - g_info << "Restarting cluster..." << endl; - CHECK(restarter.restartAll() == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - { - int val = DumpStateOrd::DihMinTimeBetweenLCP; - CHECK(restarter.dumpStateAllNodes(&val, 1) == 0); - } - CHECK(pNdb->waitUntilReady(timeout) == 0); - - g_info << "Verifying records..." << endl; - CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0); - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == records); - - g_info << "2 - Stopping one node" << endl; - CHECK(restarter.restartOneDbNode(nodeIds[currentRestartNodeIndex], - false, - true, - false) == 0); - currentRestartNodeIndex = (currentRestartNodeIndex + 1 ) % nodeCount; - - g_info << "Deleting 50% of records..." << endl; - CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); - - g_info << "Restarting cluster..." << endl; - CHECK(restarter.restartAll() == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - { - int val = DumpStateOrd::DihMinTimeBetweenLCP; - CHECK(restarter.dumpStateAllNodes(&val, 1) == 0); - } - CHECK(pNdb->waitUntilReady(timeout) == 0); - - g_info << "Verifying records..." << endl; - CHECK(hugoTrans.scanReadRecords(pNdb, records/2, 0, 64) == 0); - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == (records/2)); - - g_info << "3 - Stopping one node" << endl; - CHECK(restarter.restartOneDbNode(nodeIds[currentRestartNodeIndex], - false, - true, - false) == 0); - currentRestartNodeIndex = (currentRestartNodeIndex + 1 ) % nodeCount; - g_info << "Deleting all records..." << endl; - CHECK(utilTrans.clearTable(pNdb, records/2) == 0); - - g_info << "Restarting cluster..." << endl; - CHECK(restarter.restartAll() == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - { - int val = DumpStateOrd::DihMinTimeBetweenLCP; - CHECK(restarter.dumpStateAllNodes(&val, 1) == 0); - } - CHECK(pNdb->waitUntilReady(timeout) == 0); - - ndbout << "Verifying records..." << endl; - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - CHECK(count == 0); - - i++; - } - - g_info << "runSystemRestart4 finished" << endl; - - return result; -} - -int runSystemRestart5(NDBT_Context* ctx, NDBT_Step* step){ - Ndb* pNdb = GETNDB(step); - int result = NDBT_OK; - int timeout = 300; - Uint32 loops = ctx->getNumLoops(); - int records = ctx->getNumRecords(); - int count; - NdbRestarter restarter; - Uint32 i = 1; - - const Uint32 nodeCount = restarter.getNumDbNodes(); - if(nodeCount < 2){ - g_info << "SR5 - Needs atleast 2 nodes to test" << endl; - return NDBT_OK; - } - - Vector nodeIds; - for(Uint32 i = 0; igetTab()); - HugoTransactions hugoTrans(*ctx->getTab()); - - { - int val = DumpStateOrd::DihMinTimeBetweenLCP; - if(restarter.dumpStateAllNodes(&val, 1) != 0){ - g_err << "ERR: "<< step->getName() - << " failed on line " << __LINE__ << endl; - return NDBT_FAILED; - } - } - - while(i<=loops && result != NDBT_FAILED){ - - g_info << "Loop " << i << "/"<< loops <<" started" << endl; - /** - * 1. Load data - * 2. Restart 1 node -nostart - * 3. Update records - * 4. Restart cluster and verify records - * 5. Restart 1 node -nostart - * 6. Delete half of the records - * 7. Restart cluster and verify records - * 8. Restart 1 node -nostart - * 9. Delete all records - * 10. Restart cluster and verify records - */ - g_info << "Loading records..." << endl; - hugoTrans.loadTable(pNdb, records); - - /*** 1 ***/ - g_info << "1 - Stopping one node" << endl; - CHECK(restarter.restartOneDbNode(nodeIds[currentRestartNodeIndex], - false, - true, - false) == 0); - currentRestartNodeIndex = (currentRestartNodeIndex + 1 ) % nodeCount; - - g_info << "Updating records..." << endl; - hugoTrans.pkUpdateRecords(pNdb, records); - - g_info << "Restarting cluster..." << endl; - CHECK(restarter.restartAll(false, false, true) == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - { - int val = DumpStateOrd::DihMinTimeBetweenLCP; - CHECK(restarter.dumpStateAllNodes(&val, 1) == 0); - } - CHECK(pNdb->waitUntilReady(timeout) == 0); - - g_info << "Verifying records..." << endl; - hugoTrans.pkReadRecords(pNdb, records); - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - //CHECK(count == records); - - g_info << "2 - Stopping one node" << endl; - CHECK(restarter.restartOneDbNode(nodeIds[currentRestartNodeIndex], - false, - true, - false) == 0); - currentRestartNodeIndex = (currentRestartNodeIndex + 1 ) % nodeCount; - - g_info << "Deleting 50% of records..." << endl; - hugoTrans.pkDelRecords(pNdb, records/2); - - g_info << "Restarting cluster..." << endl; - CHECK(restarter.restartAll(false, false, true) == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - { - int val = DumpStateOrd::DihMinTimeBetweenLCP; - CHECK(restarter.dumpStateAllNodes(&val, 1) == 0); - } - CHECK(pNdb->waitUntilReady(timeout) == 0); - - g_info << "Verifying records..." << endl; - hugoTrans.scanReadRecords(pNdb, records/2, 0, 64); - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - //CHECK(count == (records/2)); - - g_info << "3 - Stopping one node" << endl; - CHECK(restarter.restartOneDbNode(nodeIds[currentRestartNodeIndex], - false, - true, - false) == 0); - currentRestartNodeIndex = (currentRestartNodeIndex + 1 ) % nodeCount; - g_info << "Deleting all records..." << endl; - utilTrans.clearTable(pNdb, records/2); - - g_info << "Restarting cluster..." << endl; - CHECK(restarter.restartAll(false, false, true) == 0); - CHECK(restarter.waitClusterStarted(timeout) == 0); - { - int val = DumpStateOrd::DihMinTimeBetweenLCP; - CHECK(restarter.dumpStateAllNodes(&val, 1) == 0); - } - CHECK(pNdb->waitUntilReady(timeout) == 0); - - ndbout << "Verifying records..." << endl; - CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); - //CHECK(count == 0); - - CHECK(utilTrans.clearTable(pNdb) == 0); - i++; - } - - g_info << "runSystemRestart5 finished" << endl; - - return result; -} - -int runWaitStarted(NDBT_Context* ctx, NDBT_Step* step){ - - NdbRestarter restarter; - restarter.waitClusterStarted(300); - - NdbSleep_SecSleep(3); - return NDBT_OK; -} - -int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - - UtilTransactions utilTrans(*ctx->getTab()); - if (utilTrans.clearTable2(GETNDB(step), records) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - - -NDBT_TESTSUITE(testSystemRestart); -TESTCASE("SR1", - "Basic system restart test. Focus on testing restart from REDO log.\n" - "NOTE! Time between lcp's and gcp's should be left at default, \n" - "so that Ndb uses the Redo log when restarting\n" - "1. Load records\n" - "2. Restart cluster and verify records \n" - "3. Update records\n" - "4. Restart cluster and verify records \n" - "5. Delete half of the records \n" - "6. Restart cluster and verify records \n" - "7. Delete all records \n" - "8. Restart cluster and verify records \n" - "9. Insert, update, delete records \n" - "10. Restart cluster and verify records\n" - "11. Insert, update, delete records \n" - "12. Restart cluster with error insert 5020 and verify records\n"){ - INITIALIZER(runWaitStarted); - STEP(runSystemRestart1); - FINALIZER(runClearTable); -} -TESTCASE("SR2", - "Basic system restart test. Focus on testing restart from LCP\n" - "NOTE! Time between lcp's is automatically set to it's min value\n" - "so that Ndb uses LCP's when restarting.\n" - "1. Load records\n" - "2. Restart cluster and verify records \n" - "3. Update records\n" - "4. Restart cluster and verify records \n" - "5. Delete half of the records \n" - "6. Restart cluster and verify records \n" - "7. Delete all records \n" - "8. Restart cluster and verify records \n" - "9. Insert, update, delete records \n" - "10. Restart cluster and verify records\n"){ - INITIALIZER(runWaitStarted); - STEP(runSystemRestart2); - FINALIZER(runClearTable); -} -TESTCASE("SR_UNDO", - "System restart test. Focus on testing of undologging\n" - "in DBACC and DBTUP.\n" - "This is done by starting a LCP, turn on undologging \n" - "but don't start writing the datapages. This will force all\n" - "operations to be written into the undolog.\n" - "Then write datapages and complete LCP.\n" - "Restart the system\n"){ - INITIALIZER(runWaitStarted); - STEP(runSystemRestartTestUndoLog); - FINALIZER(runClearTable); -} -TESTCASE("SR_FULLDB", - "System restart test. Test to restart when DB is full.\n"){ - INITIALIZER(runWaitStarted); - STEP(runSystemRestartTestFullDb); - FINALIZER(runClearTable); -} -TESTCASE("SR3", - "System restart test. Focus on testing restart from with\n" - "not all nodes alive when system went down\n" - "* 1. Load data\n" - "* 2. Restart 1 node -nostart\n" - "* 3. Update records\n" - "* 4. Restart cluster and verify records\n" - "* 5. Restart 1 node -nostart\n" - "* 6. Delete half of the records\n" - "* 7. Restart cluster and verify records\n" - "* 8. Restart 1 node -nostart\n" - "* 9. Delete all records\n" - "* 10. Restart cluster and verify records\n"){ - INITIALIZER(runWaitStarted); - STEP(runSystemRestart3); - FINALIZER(runClearTable); -} -TESTCASE("SR4", - "System restart test. Focus on testing restart from with\n" - "not all nodes alive when system went down but running LCP at\n" - "high speed so that sometimes a TO is required to start cluster\n" - "* 1. Load data\n" - "* 2. Restart 1 node -nostart\n" - "* 3. Update records\n" - "* 4. Restart cluster and verify records\n" - "* 5. Restart 1 node -nostart\n" - "* 6. Delete half of the records\n" - "* 7. Restart cluster and verify records\n" - "* 8. Restart 1 node -nostart\n" - "* 9. Delete all records\n" - "* 10. Restart cluster and verify records\n"){ - INITIALIZER(runWaitStarted); - STEP(runSystemRestart4); - FINALIZER(runClearTable); -} -TESTCASE("SR5", - "As SR4 but making restart aborts\n" - "* 1. Load data\n" - "* 2. Restart 1 node -nostart\n" - "* 3. Update records\n" - "* 4. Restart cluster and verify records\n" - "* 5. Restart 1 node -nostart\n" - "* 6. Delete half of the records\n" - "* 7. Restart cluster and verify records\n" - "* 8. Restart 1 node -nostart\n" - "* 9. Delete all records\n" - "* 10. Restart cluster and verify records\n"){ - INITIALIZER(runWaitStarted); - STEP(runSystemRestart5); - FINALIZER(runClearTable); -} -NDBT_TESTSUITE_END(testSystemRestart); - -int main(int argc, const char** argv){ - return testSystemRestart.execute(argc, argv); -} - - diff --git a/ndb/test/ndbapi/testTimeout.cpp b/ndb/test/ndbapi/testTimeout.cpp new file mode 100644 index 00000000000..de1d2cfc40b --- /dev/null +++ b/ndb/test/ndbapi/testTimeout.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; 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 */ + +#include +#include +#include +#include +#include +#include + + +int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ + + int records = ctx->getNumRecords(); + HugoTransactions hugoTrans(*ctx->getTab()); + if (hugoTrans.loadTable(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + + UtilTransactions utilTrans(*ctx->getTab()); + if (utilTrans.clearTable2(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + + +#define CHECK(b) if (!(b)) { \ + ndbout << "ERR: "<< step->getName() \ + << " failed on line " << __LINE__ << endl; \ + result = NDBT_FAILED; \ + break; } + +int runTimeoutTrans(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int loops = ctx->getNumLoops(); + NdbConfig conf(GETNDB(step)->getNodeId()+1); + unsigned int nodeId = conf.getMasterNodeId(); + int stepNo = step->getStepNo(); + Uint32 timeoutVal; + if (!conf.getProperty(nodeId, + "DB", + "TransactionInactiveTimeout", + &timeoutVal)){ + return NDBT_FAILED; + } + int minSleep = (int)(timeoutVal * 1.5); + int maxSleep = timeoutVal * 2; + ndbout << "TransactionInactiveTimeout="<getNumLoops(); + NdbConfig conf(GETNDB(step)->getNodeId()+1); + unsigned int nodeId = conf.getMasterNodeId(); + int stepNo = step->getStepNo(); + Uint32 timeoutVal; + if (!conf.getProperty(nodeId, + "DB", + "TransactionInactiveTimeout", + &timeoutVal)){ + return NDBT_FAILED; + } + int maxSleep = (int)(timeoutVal * 0.5); + ndbout << "TransactionInactiveTimeout="<getNumLoops(); + int records = ctx->getNumRecords(); + NdbConfig conf(GETNDB(step)->getNodeId()+1); + unsigned int nodeId = conf.getMasterNodeId(); + int stepNo = step->getStepNo(); + Uint32 timeoutVal; + if (!conf.getProperty(nodeId, + "DB", + "TransactionInactiveTimeout", + &timeoutVal)){ + return NDBT_FAILED; + } + int maxSleep = (int)(timeoutVal * 0.3); + ndbout << "TransactionInactiveTimeout="< -#include -#include -#include -#include -#include - - -int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ - - int records = ctx->getNumRecords(); - HugoTransactions hugoTrans(*ctx->getTab()); - if (hugoTrans.loadTable(GETNDB(step), records) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - - UtilTransactions utilTrans(*ctx->getTab()); - if (utilTrans.clearTable2(GETNDB(step), records) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - - -#define CHECK(b) if (!(b)) { \ - ndbout << "ERR: "<< step->getName() \ - << " failed on line " << __LINE__ << endl; \ - result = NDBT_FAILED; \ - break; } - -int runTimeoutTrans(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - int loops = ctx->getNumLoops(); - NdbConfig conf(GETNDB(step)->getNodeId()+1); - unsigned int nodeId = conf.getMasterNodeId(); - int stepNo = step->getStepNo(); - Uint32 timeoutVal; - if (!conf.getProperty(nodeId, - "DB", - "TransactionInactiveTimeout", - &timeoutVal)){ - return NDBT_FAILED; - } - int minSleep = (int)(timeoutVal * 1.5); - int maxSleep = timeoutVal * 2; - ndbout << "TransactionInactiveTimeout="<getNumLoops(); - NdbConfig conf(GETNDB(step)->getNodeId()+1); - unsigned int nodeId = conf.getMasterNodeId(); - int stepNo = step->getStepNo(); - Uint32 timeoutVal; - if (!conf.getProperty(nodeId, - "DB", - "TransactionInactiveTimeout", - &timeoutVal)){ - return NDBT_FAILED; - } - int maxSleep = (int)(timeoutVal * 0.5); - ndbout << "TransactionInactiveTimeout="<getNumLoops(); - int records = ctx->getNumRecords(); - NdbConfig conf(GETNDB(step)->getNodeId()+1); - unsigned int nodeId = conf.getMasterNodeId(); - int stepNo = step->getStepNo(); - Uint32 timeoutVal; - if (!conf.getProperty(nodeId, - "DB", - "TransactionInactiveTimeout", - &timeoutVal)){ - return NDBT_FAILED; - } - int maxSleep = (int)(timeoutVal * 0.3); - ndbout << "TransactionInactiveTimeout="< +#include +#include +#include +#include +#include + +struct OperationTestCase { + const char * name; + bool preCond; // start transaction | insert | commit + + // start transaction 1 + const char * op1; + const int val1; + + // no commit + + // start transaction 2 + const char * op2; + const int res2; + const int val2; + // no commit + + // commit transaction 1 + // commit transaction 2 + + // start transaction + // op3 = READ + const int res3; + const int val3; + // commit transaction +}; + +#define X -1 + +OperationTestCase matrix[] = { + { "ReadRead", true, "READ", 1, "READ", 0, 1, 0, 1 }, + { "ReadReadEx", true, "READ", 1, "READ-EX", 266, X, 0, 1 }, + { "ReadSimpleRead", true, "READ", 1, "S-READ", 0, 1, 0, 1 }, + { "ReadDirtyRead", true, "READ", 1, "D-READ", 0, 1, 0, 1 }, + { "ReadInsert", true, "READ", 1, "INSERT", 266, X, 0, 1 }, + { "ReadUpdate", true, "READ", 1, "UPDATE", 266, X, 0, 1 }, + { "ReadDelete", true, "READ", 1, "DELETE", 266, X, 0, 1 }, + { "ReadScan", true, "READ", 1, "SCAN", 0, 1, 0, 1 }, + { "ReadScanHl", true, "READ", 1, "SCAN-HL", 0, 1, 0, 1 }, + { "ReadScanEx", true, "READ", 1, "SCAN-EX", 274, X, 0, 1 }, +#if 0 + { "ReadScanUp", true, "READ", 1, "SCAN-UP", 266, X, 0, 1 }, + { "ReadScanDe", true, "READ", 1, "SCAN-DE", 266, X, 0, 1 }, +#endif + + { "ScanRead", true, "SCAN", 1, "READ", 0, 1, 0, 1 }, + { "ScanReadEx", true, "SCAN", 1, "READ-EX", 0, 1, 0, 1 }, + { "ScanSimpleRead", true, "SCAN", 1, "S-READ", 0, 1, 0, 1 }, + { "ScanDirtyRead", true, "SCAN", 1, "D-READ", 0, 1, 0, 1 }, + { "ScanInsert", true, "SCAN", 1, "INSERT", 630, X, 0, 1 }, + { "ScanUpdate", true, "SCAN", 1, "UPDATE", 0, 2, 0, 2 }, + { "ScanDelete", true, "SCAN", 1, "DELETE", 0, X, 626, X }, + { "ScanScan", true, "SCAN", 1, "SCAN", 0, 1, 0, 1 }, + { "ScanScanHl", true, "SCAN", 1, "SCAN-HL", 0, 1, 0, 1 }, + { "ScanScanEx", true, "SCAN", 1, "SCAN-EX", 0, 1, 0, 1 }, +#if 0 + { "ScanScanUp", true, "SCAN", 1, "SCAN-UP", 266, X, 0, 1 }, + { "ScanScanDe", true, "SCAN", 1, "SCAN-DE", 266, X, 0, 1 }, +#endif + + { "ScanHlRead", true, "SCAN-HL",1, "READ", 0, 1, 0, 1 }, + { "ScanHlReadEx", true, "SCAN-HL",1, "READ-EX", 266, 1, 0, 1 }, + { "ScanHlSimpleRead", true, "SCAN-HL",1, "S-READ", 0, 1, 0, 1 }, + { "ScanHlDirtyRead", true, "SCAN-HL",1, "D-READ", 0, 1, 0, 1 }, + { "ScanHlInsert", true, "SCAN-HL",1, "INSERT", 266, X, 0, 1 }, + { "ScanHlUpdate", true, "SCAN-HL",1, "UPDATE", 266, 2, 0, 1 }, + { "ScanHlDelete", true, "SCAN-HL",1, "DELETE", 266, X, 0, 1 }, + { "ScanHlScan", true, "SCAN-HL",1, "SCAN", 0, 1, 0, 1 }, + { "ScanHlScanHl", true, "SCAN-HL",1, "SCAN-HL", 0, 1, 0, 1 }, + { "ScanHlScanEx", true, "SCAN-HL",1, "SCAN-EX", 274, X, 0, 1 }, +#if 0 + { "ScanHlScanUp", true, "SCAN-HL",1, "SCAN-UP", 266, X, 0, 1 }, + { "ScanHlScanDe", true, "SCAN-HL",1, "SCAN-DE", 266, X, 0, 1 }, +#endif + + { "ScanExRead", true, "SCAN-EX",1, "READ", 266, 1, 0, 1 }, + { "ScanExReadEx", true, "SCAN-EX",1, "READ-EX", 266, 1, 0, 1 }, + { "ScanExSimpleRead", true, "SCAN-EX",1, "S-READ", 266, 1, 0, 1 }, + { "ScanExDirtyRead", true, "SCAN-EX",1, "D-READ", 0, 1, 0, 1 }, + { "ScanExInsert", true, "SCAN-EX",1, "INSERT", 266, X, 0, 1 }, + { "ScanExUpdate", true, "SCAN-EX",1, "UPDATE", 266, 2, 0, 1 }, + { "ScanExDelete", true, "SCAN-EX",1, "DELETE", 266, X, 0, 1 }, + { "ScanExScan", true, "SCAN-EX",1, "SCAN", 274, X, 0, 1 }, + { "ScanExScanHl", true, "SCAN-EX",1, "SCAN-HL", 274, X, 0, 1 }, + { "ScanExScanEx", true, "SCAN-EX",1, "SCAN-EX", 274, X, 0, 1 }, +#if 0 + { "ScanExScanUp", true, "SCAN-EX",1, "SCAN-UP", 266, X, 0, 1 }, + { "ScanExScanDe", true, "SCAN-EX",1, "SCAN-DE", 266, X, 0, 1 }, +#endif + + { "ReadExRead", true, "READ-EX",1, "READ", 266, X, 0, 1 }, + { "ReadExReadEx", true, "READ-EX",1, "READ-EX", 266, X, 0, 1 }, + { "ReadExSimpleRead", true, "READ-EX",1, "S-READ", 266, X, 0, 1 }, + { "ReadExDirtyRead", true, "READ-EX",1, "D-READ", 0, 1, 0, 1 }, + { "ReadExInsert", true, "READ-EX",1, "INSERT", 266, X, 0, 1 }, + { "ReadExUpdate", true, "READ-EX",1, "UPDATE", 266, X, 0, 1 }, + { "ReadExDelete", true, "READ-EX",1, "DELETE", 266, X, 0, 1 }, + { "ReadExScan", true, "READ-EX",1, "SCAN", 274, 1, 0, 1 }, + { "ReadExScanHl", true, "READ-EX",1, "SCAN-HL", 274, 1, 0, 1 }, + { "ReadExScanEx", true, "READ-EX",1, "SCAN-EX", 274, X, 0, 1 }, +#if 0 + { "ReadExScanUp", true, "READ-EX",1, "SCAN-UP", 266, X, 0, 1 }, + { "ReadExScanDe", true, "READ-EX",1, "SCAN-DE", 266, X, 0, 1 }, +#endif + + { "InsertRead", false, "INSERT", 1, "READ", 266, X, 0, 1 }, + { "InsertReadEx", false, "INSERT", 1, "READ-EX", 266, X, 0, 1 }, + { "InsertSimpleRead",false, "INSERT", 1, "S-READ", 266, X, 0, 1 }, + { "InsertDirtyRead", false, "INSERT", 1, "D-READ", 626, X, 0, 1 }, + { "InsertInsert", false, "INSERT", 1, "INSERT", 266, X, 0, 1 }, + { "InsertUpdate", false, "INSERT", 1, "UPDATE", 266, X, 0, 1 }, + { "InsertDelete", false, "INSERT", 1, "DELETE", 266, X, 0, 1 }, + { "InsertScan", false, "INSERT", 1, "SCAN", 274, X, 0, 1 }, + { "InsertScanHl", false, "INSERT", 1, "SCAN-HL", 274, X, 0, 1 }, + { "InsertScanEx", false, "INSERT", 1, "SCAN-EX", 274, X, 0, 1 }, +#if 0 + { "InsertScanUp", false, "INSERT", 1, "SCAN-UP", 266, X, 0, 1 }, + { "InsertScanDe", false, "INSERT", 1, "SCAN-DE", 266, X, 0, 1 }, +#endif + + { "UpdateRead", true, "UPDATE", 2, "READ", 266, X, 0, 2 }, + { "UpdateReadEx", true, "UPDATE", 2, "READ-EX", 266, X, 0, 2 }, + { "UpdateSimpleRead", true, "UPDATE", 2, "S-READ", 266, X, 0, 2 }, + { "UpdateDirtyRead", true, "UPDATE", 2, "D-READ", 0, 1, 0, 2 }, + { "UpdateInsert", true, "UPDATE", 2, "INSERT", 266, X, 0, 2 }, + { "UpdateUpdate", true, "UPDATE", 2, "UPDATE", 266, X, 0, 2 }, + { "UpdateDelete", true, "UPDATE", 2, "DELETE", 266, X, 0, 2 }, + { "UpdateScan", true, "UPDATE", 2, "SCAN", 274, X, 0, 2 }, + { "UpdateScanHl", true, "UPDATE", 2, "SCAN-HL", 274, X, 0, 2 }, + { "UpdateScanEx", true, "UPDATE", 2, "SCAN-EX", 274, X, 0, 2 }, +#if 0 + { "UpdateScanUp", true, "UPDATE", 2, "SCAN-UP", 266, X, 0, 2 }, + { "UpdateScanDe", true, "UPDATE", 2, "SCAN-DE", 266, X, 0, 2 }, +#endif + + { "DeleteRead", true, "DELETE", X, "READ", 266, X, 626, X }, + { "DeleteReadEx", true, "DELETE", X, "READ-EX", 266, X, 626, X }, + { "DeleteSimpleRead", true, "DELETE", X, "S-READ", 266, X, 626, X }, + { "DeleteDirtyRead", true, "DELETE", X, "D-READ", 0, 1, 626, X }, + { "DeleteInsert", true, "DELETE", X, "INSERT", 266, X, 626, X }, + { "DeleteUpdate", true, "DELETE", X, "UPDATE", 266, X, 626, X }, + { "DeleteDelete", true, "DELETE", X, "DELETE", 266, X, 626, X }, + { "DeleteScan", true, "DELETE", X, "SCAN", 274, X, 626, X }, + { "DeleteScanHl", true, "DELETE", X, "SCAN-HL", 274, X, 626, X }, + { "DeleteScanEx", true, "DELETE", X, "SCAN-EX", 274, X, 626, X }, +#if 0 + { "DeleteScanUp", true, "DELETE", X, "SCAN-UP", 266, X, 626, X }, + { "DeleteScanDe", true, "DELETE", X, "SCAN-DE", 266, X, 626, X } +#endif + +}; + +#define CHECK(a, b) { int x = a; int y = b; if (x != y) { \ + g_err << "ERR: "<< step->getName() \ + << " failed on line " << __LINE__ << endl << " " \ + << x << " != " << y << endl;\ + result = NDBT_FAILED; \ + break; } } + +int +runOp(HugoOperations & hugoOps, + Ndb * pNdb, + const char * op, + int value){ + +#define C2(x) if(!(x)) {\ + g_err << "ERR: failed on line " << __LINE__ << endl; \ + return NDBT_FAILED; } + + if(strcmp(op, "READ") == 0){ + C2(hugoOps.pkReadRecord(pNdb, 1, false, 1) == 0); + } else if(strcmp(op, "READ-EX") == 0){ + C2(hugoOps.pkReadRecord(pNdb, 1, true, 1) == 0); + } else if(strcmp(op, "S-READ") == 0){ + C2(hugoOps.pkSimpleReadRecord(pNdb, 1, 1) == 0); + } else if(strcmp(op, "D-READ") == 0){ + C2(hugoOps.pkDirtyReadRecord(pNdb, 1, 1) == 0); + } else if(strcmp(op, "INSERT") == 0){ + C2(hugoOps.pkInsertRecord(pNdb, 1, 1, value) == 0); + } else if(strcmp(op, "UPDATE") == 0){ + C2(hugoOps.pkUpdateRecord(pNdb, 1, 1, value) == 0); + } else if(strcmp(op, "DELETE") == 0){ + C2(hugoOps.pkDeleteRecord(pNdb, 1, 1) == 0); + } else if(strcmp(op, "SCAN") == 0){ + C2(hugoOps.scanReadRecords(pNdb) == 0); + } else if(strcmp(op, "SCAN-HL") == 0){ + C2(hugoOps.scanReadRecords(pNdb, 240, HugoOperations::SL_ReadHold) == 0); + } else if(strcmp(op, "SCAN-EX") == 0){ + C2(hugoOps.scanReadRecords(pNdb, 240, HugoOperations::SL_Exclusive) == 0); + } else { + g_err << __FILE__ << " - " << __LINE__ + << ": Unknown operation" << op << endl; + return NDBT_FAILED; + } + + return NDBT_OK; +} + +int +checkVal(HugoOperations & hugoOps, + const char * op, + int value, + int result){ + + if(result != 0) + return NDBT_OK; + + if(strcmp(op, "READ") == 0){ + } else if(strcmp(op, "READ-EX") == 0){ + } else if(strcmp(op, "S-READ") == 0){ + } else if(strcmp(op, "D-READ") == 0){ + } else if(strcmp(op, "SCAN") == 0){ + } else if(strcmp(op, "SCAN-HL") == 0){ + } else if(strcmp(op, "SCAN-EX") == 0){ + } else { + return NDBT_OK; + } + + return hugoOps.verifyUpdatesValue(value); +} + +#define TIMEOUT 100 + +int +setTransactionTimeout(NDBT_Context* ctx, NDBT_Step* step){ + NdbRestarter restarter; + + int val[] = + { DumpStateOrd::TcSetTransactionTimeout, TIMEOUT }; + if(restarter.dumpStateAllNodes(val, 2) != 0){ + return NDBT_FAILED; + } + + return NDBT_OK; +} + +int +runTwoTrans1(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + HugoOperations T1(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + + const char * op1 = ctx->getProperty("op1", "NONE"); + int val1 = ctx->getProperty("val1", ~0); + + do { + // Insert, read + CHECK(T1.startTransaction(pNdb), 0); + CHECK(runOp(T1, pNdb, op1, val1), 0); + CHECK(T1.execute_NoCommit(pNdb), 0); + CHECK(checkVal(T1, op1, val1, 0), 0); + + ctx->setProperty("T1-1-Complete", 1); + while(ctx->getProperty("T2-Complete", (Uint32)0) == 0){ + T1.refresh(); + NdbSleep_MilliSleep(10); + } + + CHECK(T1.execute_Commit(pNdb), 0); + + } while(false); + T1.closeTransaction(pNdb); + + if(result != NDBT_OK) + return result; + + const int res3 = ctx->getProperty("res3", ~0); + const int val3 = ctx->getProperty("val3", ~0); + + do { + CHECK(T1.startTransaction(pNdb), 0); + CHECK(runOp(T1, pNdb, "READ", 0), 0); + CHECK(T1.execute_Commit(pNdb), res3); + CHECK(checkVal(T1, "READ", val3, res3), 0); + } while(false); + T1.closeTransaction(pNdb); + + return result; +} + +int +runTwoTrans2(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + HugoOperations T2(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + + const char * op2 = ctx->getProperty("op2", "NONE"); + const int res2 = ctx->getProperty("res2", ~0); + const int val2 = ctx->getProperty("val2", ~0); + + while(ctx->getProperty("T1-1-Complete", (Uint32)0) == 0 && + !ctx->isTestStopped()){ + NdbSleep_MilliSleep(100); + } + + if(!ctx->isTestStopped()){ + do { + CHECK(T2.startTransaction(pNdb), 0); + CHECK(runOp(T2, pNdb, op2, val2), 0); + CHECK(T2.execute_NoCommit(pNdb), res2); + CHECK(checkVal(T2, op2, val2, res2), 0); + if(res2 == 0){ + CHECK(T2.execute_Commit(pNdb), res2); + } + } while(false); + T2.closeTransaction(pNdb); + } + + ctx->setProperty("T2-Complete", 1); + + return result; +} + +int +runInsertRecord(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + + do{ + // Insert, insert + CHECK(hugoOps.startTransaction(pNdb), 0); + CHECK(hugoOps.pkInsertRecord(pNdb, 1, 1, 1), 0); + CHECK(hugoOps.execute_Commit(pNdb), 0); + } while(false); + + hugoOps.closeTransaction(pNdb); + + return result; +} + +int +runClearTable(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + + UtilTransactions utilTrans(*ctx->getTab()); + if (utilTrans.clearTable2(GETNDB(step), records, 240) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int +main(int argc, const char** argv){ + + NDBT_TestSuite ts("testOperations"); + for(Uint32 i = 0; iaddInitializer(new NDBT_Initializer(pt, + "runClearTable", + runClearTable)); + + if(matrix[i].preCond){ + pt->addInitializer(new NDBT_Initializer(pt, + "runInsertRecord", + runInsertRecord)); + } + + pt->addInitializer(new NDBT_Initializer(pt, + "setTransactionTimeout", + setTransactionTimeout)); + + pt->setProperty("op1", matrix[i].op1); + pt->setProperty("val1", matrix[i].val1); + + pt->setProperty("op2", matrix[i].op2); + pt->setProperty("res2", matrix[i].res2); + pt->setProperty("val2", matrix[i].val2); + + pt->setProperty("res3", matrix[i].res3); + pt->setProperty("val3", matrix[i].val3); + + pt->addStep(new NDBT_ParallelStep(pt, + matrix[i].name, + runTwoTrans1)); + pt->addStep(new NDBT_ParallelStep(pt, + matrix[i].name, + runTwoTrans2)); + pt->addFinalizer(new NDBT_Finalizer(pt, + "runClearTable", + runClearTable)); + + ts.addTest(pt); + } + + return ts.execute(argc, argv); +} + diff --git a/ndb/test/ndbapi/testTransactions/Makefile b/ndb/test/ndbapi/testTransactions/Makefile deleted file mode 100644 index 0279a526923..00000000000 --- a/ndb/test/ndbapi/testTransactions/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := testTransactions - -SOURCES := testTransactions.cpp -CFLAGS_testTransactions.cpp := -I$(call fixpath,$(NDB_TOP)/include/kernel) - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/testTransactions/testTransactions.cpp b/ndb/test/ndbapi/testTransactions/testTransactions.cpp deleted file mode 100644 index 9ce928f8736..00000000000 --- a/ndb/test/ndbapi/testTransactions/testTransactions.cpp +++ /dev/null @@ -1,411 +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 */ - -#include -#include -#include -#include -#include -#include - -struct OperationTestCase { - const char * name; - bool preCond; // start transaction | insert | commit - - // start transaction 1 - const char * op1; - const int val1; - - // no commit - - // start transaction 2 - const char * op2; - const int res2; - const int val2; - // no commit - - // commit transaction 1 - // commit transaction 2 - - // start transaction - // op3 = READ - const int res3; - const int val3; - // commit transaction -}; - -#define X -1 - -OperationTestCase matrix[] = { - { "ReadRead", true, "READ", 1, "READ", 0, 1, 0, 1 }, - { "ReadReadEx", true, "READ", 1, "READ-EX", 266, X, 0, 1 }, - { "ReadSimpleRead", true, "READ", 1, "S-READ", 0, 1, 0, 1 }, - { "ReadDirtyRead", true, "READ", 1, "D-READ", 0, 1, 0, 1 }, - { "ReadInsert", true, "READ", 1, "INSERT", 266, X, 0, 1 }, - { "ReadUpdate", true, "READ", 1, "UPDATE", 266, X, 0, 1 }, - { "ReadDelete", true, "READ", 1, "DELETE", 266, X, 0, 1 }, - { "ReadScan", true, "READ", 1, "SCAN", 0, 1, 0, 1 }, - { "ReadScanHl", true, "READ", 1, "SCAN-HL", 0, 1, 0, 1 }, - { "ReadScanEx", true, "READ", 1, "SCAN-EX", 274, X, 0, 1 }, -#if 0 - { "ReadScanUp", true, "READ", 1, "SCAN-UP", 266, X, 0, 1 }, - { "ReadScanDe", true, "READ", 1, "SCAN-DE", 266, X, 0, 1 }, -#endif - - { "ScanRead", true, "SCAN", 1, "READ", 0, 1, 0, 1 }, - { "ScanReadEx", true, "SCAN", 1, "READ-EX", 0, 1, 0, 1 }, - { "ScanSimpleRead", true, "SCAN", 1, "S-READ", 0, 1, 0, 1 }, - { "ScanDirtyRead", true, "SCAN", 1, "D-READ", 0, 1, 0, 1 }, - { "ScanInsert", true, "SCAN", 1, "INSERT", 630, X, 0, 1 }, - { "ScanUpdate", true, "SCAN", 1, "UPDATE", 0, 2, 0, 2 }, - { "ScanDelete", true, "SCAN", 1, "DELETE", 0, X, 626, X }, - { "ScanScan", true, "SCAN", 1, "SCAN", 0, 1, 0, 1 }, - { "ScanScanHl", true, "SCAN", 1, "SCAN-HL", 0, 1, 0, 1 }, - { "ScanScanEx", true, "SCAN", 1, "SCAN-EX", 0, 1, 0, 1 }, -#if 0 - { "ScanScanUp", true, "SCAN", 1, "SCAN-UP", 266, X, 0, 1 }, - { "ScanScanDe", true, "SCAN", 1, "SCAN-DE", 266, X, 0, 1 }, -#endif - - { "ScanHlRead", true, "SCAN-HL",1, "READ", 0, 1, 0, 1 }, - { "ScanHlReadEx", true, "SCAN-HL",1, "READ-EX", 266, 1, 0, 1 }, - { "ScanHlSimpleRead", true, "SCAN-HL",1, "S-READ", 0, 1, 0, 1 }, - { "ScanHlDirtyRead", true, "SCAN-HL",1, "D-READ", 0, 1, 0, 1 }, - { "ScanHlInsert", true, "SCAN-HL",1, "INSERT", 266, X, 0, 1 }, - { "ScanHlUpdate", true, "SCAN-HL",1, "UPDATE", 266, 2, 0, 1 }, - { "ScanHlDelete", true, "SCAN-HL",1, "DELETE", 266, X, 0, 1 }, - { "ScanHlScan", true, "SCAN-HL",1, "SCAN", 0, 1, 0, 1 }, - { "ScanHlScanHl", true, "SCAN-HL",1, "SCAN-HL", 0, 1, 0, 1 }, - { "ScanHlScanEx", true, "SCAN-HL",1, "SCAN-EX", 274, X, 0, 1 }, -#if 0 - { "ScanHlScanUp", true, "SCAN-HL",1, "SCAN-UP", 266, X, 0, 1 }, - { "ScanHlScanDe", true, "SCAN-HL",1, "SCAN-DE", 266, X, 0, 1 }, -#endif - - { "ScanExRead", true, "SCAN-EX",1, "READ", 266, 1, 0, 1 }, - { "ScanExReadEx", true, "SCAN-EX",1, "READ-EX", 266, 1, 0, 1 }, - { "ScanExSimpleRead", true, "SCAN-EX",1, "S-READ", 266, 1, 0, 1 }, - { "ScanExDirtyRead", true, "SCAN-EX",1, "D-READ", 0, 1, 0, 1 }, - { "ScanExInsert", true, "SCAN-EX",1, "INSERT", 266, X, 0, 1 }, - { "ScanExUpdate", true, "SCAN-EX",1, "UPDATE", 266, 2, 0, 1 }, - { "ScanExDelete", true, "SCAN-EX",1, "DELETE", 266, X, 0, 1 }, - { "ScanExScan", true, "SCAN-EX",1, "SCAN", 274, X, 0, 1 }, - { "ScanExScanHl", true, "SCAN-EX",1, "SCAN-HL", 274, X, 0, 1 }, - { "ScanExScanEx", true, "SCAN-EX",1, "SCAN-EX", 274, X, 0, 1 }, -#if 0 - { "ScanExScanUp", true, "SCAN-EX",1, "SCAN-UP", 266, X, 0, 1 }, - { "ScanExScanDe", true, "SCAN-EX",1, "SCAN-DE", 266, X, 0, 1 }, -#endif - - { "ReadExRead", true, "READ-EX",1, "READ", 266, X, 0, 1 }, - { "ReadExReadEx", true, "READ-EX",1, "READ-EX", 266, X, 0, 1 }, - { "ReadExSimpleRead", true, "READ-EX",1, "S-READ", 266, X, 0, 1 }, - { "ReadExDirtyRead", true, "READ-EX",1, "D-READ", 0, 1, 0, 1 }, - { "ReadExInsert", true, "READ-EX",1, "INSERT", 266, X, 0, 1 }, - { "ReadExUpdate", true, "READ-EX",1, "UPDATE", 266, X, 0, 1 }, - { "ReadExDelete", true, "READ-EX",1, "DELETE", 266, X, 0, 1 }, - { "ReadExScan", true, "READ-EX",1, "SCAN", 274, 1, 0, 1 }, - { "ReadExScanHl", true, "READ-EX",1, "SCAN-HL", 274, 1, 0, 1 }, - { "ReadExScanEx", true, "READ-EX",1, "SCAN-EX", 274, X, 0, 1 }, -#if 0 - { "ReadExScanUp", true, "READ-EX",1, "SCAN-UP", 266, X, 0, 1 }, - { "ReadExScanDe", true, "READ-EX",1, "SCAN-DE", 266, X, 0, 1 }, -#endif - - { "InsertRead", false, "INSERT", 1, "READ", 266, X, 0, 1 }, - { "InsertReadEx", false, "INSERT", 1, "READ-EX", 266, X, 0, 1 }, - { "InsertSimpleRead",false, "INSERT", 1, "S-READ", 266, X, 0, 1 }, - { "InsertDirtyRead", false, "INSERT", 1, "D-READ", 626, X, 0, 1 }, - { "InsertInsert", false, "INSERT", 1, "INSERT", 266, X, 0, 1 }, - { "InsertUpdate", false, "INSERT", 1, "UPDATE", 266, X, 0, 1 }, - { "InsertDelete", false, "INSERT", 1, "DELETE", 266, X, 0, 1 }, - { "InsertScan", false, "INSERT", 1, "SCAN", 274, X, 0, 1 }, - { "InsertScanHl", false, "INSERT", 1, "SCAN-HL", 274, X, 0, 1 }, - { "InsertScanEx", false, "INSERT", 1, "SCAN-EX", 274, X, 0, 1 }, -#if 0 - { "InsertScanUp", false, "INSERT", 1, "SCAN-UP", 266, X, 0, 1 }, - { "InsertScanDe", false, "INSERT", 1, "SCAN-DE", 266, X, 0, 1 }, -#endif - - { "UpdateRead", true, "UPDATE", 2, "READ", 266, X, 0, 2 }, - { "UpdateReadEx", true, "UPDATE", 2, "READ-EX", 266, X, 0, 2 }, - { "UpdateSimpleRead", true, "UPDATE", 2, "S-READ", 266, X, 0, 2 }, - { "UpdateDirtyRead", true, "UPDATE", 2, "D-READ", 0, 1, 0, 2 }, - { "UpdateInsert", true, "UPDATE", 2, "INSERT", 266, X, 0, 2 }, - { "UpdateUpdate", true, "UPDATE", 2, "UPDATE", 266, X, 0, 2 }, - { "UpdateDelete", true, "UPDATE", 2, "DELETE", 266, X, 0, 2 }, - { "UpdateScan", true, "UPDATE", 2, "SCAN", 274, X, 0, 2 }, - { "UpdateScanHl", true, "UPDATE", 2, "SCAN-HL", 274, X, 0, 2 }, - { "UpdateScanEx", true, "UPDATE", 2, "SCAN-EX", 274, X, 0, 2 }, -#if 0 - { "UpdateScanUp", true, "UPDATE", 2, "SCAN-UP", 266, X, 0, 2 }, - { "UpdateScanDe", true, "UPDATE", 2, "SCAN-DE", 266, X, 0, 2 }, -#endif - - { "DeleteRead", true, "DELETE", X, "READ", 266, X, 626, X }, - { "DeleteReadEx", true, "DELETE", X, "READ-EX", 266, X, 626, X }, - { "DeleteSimpleRead", true, "DELETE", X, "S-READ", 266, X, 626, X }, - { "DeleteDirtyRead", true, "DELETE", X, "D-READ", 0, 1, 626, X }, - { "DeleteInsert", true, "DELETE", X, "INSERT", 266, X, 626, X }, - { "DeleteUpdate", true, "DELETE", X, "UPDATE", 266, X, 626, X }, - { "DeleteDelete", true, "DELETE", X, "DELETE", 266, X, 626, X }, - { "DeleteScan", true, "DELETE", X, "SCAN", 274, X, 626, X }, - { "DeleteScanHl", true, "DELETE", X, "SCAN-HL", 274, X, 626, X }, - { "DeleteScanEx", true, "DELETE", X, "SCAN-EX", 274, X, 626, X }, -#if 0 - { "DeleteScanUp", true, "DELETE", X, "SCAN-UP", 266, X, 626, X }, - { "DeleteScanDe", true, "DELETE", X, "SCAN-DE", 266, X, 626, X } -#endif - -}; - -#define CHECK(a, b) { int x = a; int y = b; if (x != y) { \ - g_err << "ERR: "<< step->getName() \ - << " failed on line " << __LINE__ << endl << " " \ - << x << " != " << y << endl;\ - result = NDBT_FAILED; \ - break; } } - -int -runOp(HugoOperations & hugoOps, - Ndb * pNdb, - const char * op, - int value){ - -#define C2(x) if(!(x)) {\ - g_err << "ERR: failed on line " << __LINE__ << endl; \ - return NDBT_FAILED; } - - if(strcmp(op, "READ") == 0){ - C2(hugoOps.pkReadRecord(pNdb, 1, false, 1) == 0); - } else if(strcmp(op, "READ-EX") == 0){ - C2(hugoOps.pkReadRecord(pNdb, 1, true, 1) == 0); - } else if(strcmp(op, "S-READ") == 0){ - C2(hugoOps.pkSimpleReadRecord(pNdb, 1, 1) == 0); - } else if(strcmp(op, "D-READ") == 0){ - C2(hugoOps.pkDirtyReadRecord(pNdb, 1, 1) == 0); - } else if(strcmp(op, "INSERT") == 0){ - C2(hugoOps.pkInsertRecord(pNdb, 1, 1, value) == 0); - } else if(strcmp(op, "UPDATE") == 0){ - C2(hugoOps.pkUpdateRecord(pNdb, 1, 1, value) == 0); - } else if(strcmp(op, "DELETE") == 0){ - C2(hugoOps.pkDeleteRecord(pNdb, 1, 1) == 0); - } else if(strcmp(op, "SCAN") == 0){ - C2(hugoOps.scanReadRecords(pNdb) == 0); - } else if(strcmp(op, "SCAN-HL") == 0){ - C2(hugoOps.scanReadRecords(pNdb, 240, HugoOperations::SL_ReadHold) == 0); - } else if(strcmp(op, "SCAN-EX") == 0){ - C2(hugoOps.scanReadRecords(pNdb, 240, HugoOperations::SL_Exclusive) == 0); - } else { - g_err << __FILE__ << " - " << __LINE__ - << ": Unknown operation" << op << endl; - return NDBT_FAILED; - } - - return NDBT_OK; -} - -int -checkVal(HugoOperations & hugoOps, - const char * op, - int value, - int result){ - - if(result != 0) - return NDBT_OK; - - if(strcmp(op, "READ") == 0){ - } else if(strcmp(op, "READ-EX") == 0){ - } else if(strcmp(op, "S-READ") == 0){ - } else if(strcmp(op, "D-READ") == 0){ - } else if(strcmp(op, "SCAN") == 0){ - } else if(strcmp(op, "SCAN-HL") == 0){ - } else if(strcmp(op, "SCAN-EX") == 0){ - } else { - return NDBT_OK; - } - - return hugoOps.verifyUpdatesValue(value); -} - -#define TIMEOUT 100 - -int -setTransactionTimeout(NDBT_Context* ctx, NDBT_Step* step){ - NdbRestarter restarter; - - int val[] = - { DumpStateOrd::TcSetTransactionTimeout, TIMEOUT }; - if(restarter.dumpStateAllNodes(val, 2) != 0){ - return NDBT_FAILED; - } - - return NDBT_OK; -} - -int -runTwoTrans1(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - HugoOperations T1(*ctx->getTab()); - Ndb* pNdb = GETNDB(step); - - const char * op1 = ctx->getProperty("op1", "NONE"); - int val1 = ctx->getProperty("val1", ~0); - - do { - // Insert, read - CHECK(T1.startTransaction(pNdb), 0); - CHECK(runOp(T1, pNdb, op1, val1), 0); - CHECK(T1.execute_NoCommit(pNdb), 0); - CHECK(checkVal(T1, op1, val1, 0), 0); - - ctx->setProperty("T1-1-Complete", 1); - while(ctx->getProperty("T2-Complete", (Uint32)0) == 0){ - T1.refresh(); - NdbSleep_MilliSleep(10); - } - - CHECK(T1.execute_Commit(pNdb), 0); - - } while(false); - T1.closeTransaction(pNdb); - - if(result != NDBT_OK) - return result; - - const int res3 = ctx->getProperty("res3", ~0); - const int val3 = ctx->getProperty("val3", ~0); - - do { - CHECK(T1.startTransaction(pNdb), 0); - CHECK(runOp(T1, pNdb, "READ", 0), 0); - CHECK(T1.execute_Commit(pNdb), res3); - CHECK(checkVal(T1, "READ", val3, res3), 0); - } while(false); - T1.closeTransaction(pNdb); - - return result; -} - -int -runTwoTrans2(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - HugoOperations T2(*ctx->getTab()); - Ndb* pNdb = GETNDB(step); - - const char * op2 = ctx->getProperty("op2", "NONE"); - const int res2 = ctx->getProperty("res2", ~0); - const int val2 = ctx->getProperty("val2", ~0); - - while(ctx->getProperty("T1-1-Complete", (Uint32)0) == 0 && - !ctx->isTestStopped()){ - NdbSleep_MilliSleep(100); - } - - if(!ctx->isTestStopped()){ - do { - CHECK(T2.startTransaction(pNdb), 0); - CHECK(runOp(T2, pNdb, op2, val2), 0); - CHECK(T2.execute_NoCommit(pNdb), res2); - CHECK(checkVal(T2, op2, val2, res2), 0); - if(res2 == 0){ - CHECK(T2.execute_Commit(pNdb), res2); - } - } while(false); - T2.closeTransaction(pNdb); - } - - ctx->setProperty("T2-Complete", 1); - - return result; -} - -int -runInsertRecord(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; - HugoOperations hugoOps(*ctx->getTab()); - Ndb* pNdb = GETNDB(step); - - do{ - // Insert, insert - CHECK(hugoOps.startTransaction(pNdb), 0); - CHECK(hugoOps.pkInsertRecord(pNdb, 1, 1, 1), 0); - CHECK(hugoOps.execute_Commit(pNdb), 0); - } while(false); - - hugoOps.closeTransaction(pNdb); - - return result; -} - -int -runClearTable(NDBT_Context* ctx, NDBT_Step* step){ - int records = ctx->getNumRecords(); - - UtilTransactions utilTrans(*ctx->getTab()); - if (utilTrans.clearTable2(GETNDB(step), records, 240) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int -main(int argc, const char** argv){ - - NDBT_TestSuite ts("testOperations"); - for(Uint32 i = 0; iaddInitializer(new NDBT_Initializer(pt, - "runClearTable", - runClearTable)); - - if(matrix[i].preCond){ - pt->addInitializer(new NDBT_Initializer(pt, - "runInsertRecord", - runInsertRecord)); - } - - pt->addInitializer(new NDBT_Initializer(pt, - "setTransactionTimeout", - setTransactionTimeout)); - - pt->setProperty("op1", matrix[i].op1); - pt->setProperty("val1", matrix[i].val1); - - pt->setProperty("op2", matrix[i].op2); - pt->setProperty("res2", matrix[i].res2); - pt->setProperty("val2", matrix[i].val2); - - pt->setProperty("res3", matrix[i].res3); - pt->setProperty("val3", matrix[i].val3); - - pt->addStep(new NDBT_ParallelStep(pt, - matrix[i].name, - runTwoTrans1)); - pt->addStep(new NDBT_ParallelStep(pt, - matrix[i].name, - runTwoTrans2)); - pt->addFinalizer(new NDBT_Finalizer(pt, - "runClearTable", - runClearTable)); - - ts.addTest(pt); - } - - return ts.execute(argc, argv); -} - diff --git a/ndb/test/ndbapi/test_event.cpp b/ndb/test/ndbapi/test_event.cpp new file mode 100644 index 00000000000..40fc1c6defa --- /dev/null +++ b/ndb/test/ndbapi/test_event.cpp @@ -0,0 +1,142 @@ +/* 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 */ + +#include "NDBT_Test.hpp" +#include "NDBT_ReturnCodes.h" +#include "HugoTransactions.hpp" +#include "UtilTransactions.hpp" +#include "TestNdbEventOperation.hpp" + +#define GETNDB(ps) ((NDBT_NdbApiStep*)ps)->getNdb() + +int runCreateEvent(NDBT_Context* ctx, NDBT_Step* step) +{ + HugoTransactions hugoTrans(*ctx->getTab()); + + if (hugoTrans.createEvent(GETNDB(step)) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int theThreadIdCounter = 0; + +int runEventOperation(NDBT_Context* ctx, NDBT_Step* step) +{ + int tId = theThreadIdCounter++; + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + HugoTransactions hugoTrans(*ctx->getTab()); + + EventOperationStats stats; + + g_info << "***** Id " << tId << endl; + + // sleep(tId); + + if (hugoTrans.eventOperation(GETNDB(step), (void*)&stats, 3*records) != 0){ + return NDBT_FAILED; + } + + int ret; + if (stats.n_inserts == records && + stats.n_deletes == records && + stats.n_updates == records && + stats.n_consecutive == 3 && + stats.n_duplicates == 0) + ret = NDBT_OK; + else + ret = NDBT_FAILED; + + if (ret == NDBT_FAILED) { + ndbout << "n_inserts = " << stats.n_inserts << endl; + ndbout << "n_deletes = " << stats.n_deletes << endl; + ndbout << "n_updates = " << stats.n_updates << endl; + ndbout << "n_consecutive = " << stats.n_consecutive << endl; + ndbout << "n_duplicates = " << stats.n_duplicates << endl; + ndbout << "n_inconsistent_gcis = " << stats.n_inconsistent_gcis << endl; + } + + return ret; +} + +int runEventLoad(NDBT_Context* ctx, NDBT_Step* step) +{ + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + HugoTransactions hugoTrans(*ctx->getTab()); + + sleep(5); + sleep(theThreadIdCounter); + + if (hugoTrans.loadTable(GETNDB(step), records, 1, true, loops) != 0){ + return NDBT_FAILED; + } + if (hugoTrans.pkUpdateRecords(GETNDB(step), records, 1, loops) != 0){ + return NDBT_FAILED; + } + if (hugoTrans.pkDelRecords(GETNDB(step), records, 1, true, loops) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runDropEvent(NDBT_Context* ctx, NDBT_Step* step) +{ + HugoTransactions hugoTrans(*ctx->getTab()); + + theThreadIdCounter = 0; + // if (hugoTrans.createEvent(GETNDB(step)) != 0){ + // return NDBT_FAILED; + // } + return NDBT_OK; +} + +// INITIALIZER(runInsert); +// STEP(runPkRead); +// VERIFIER(runVerifyInsert); +// FINALIZER(runClearTable); + +NDBT_TESTSUITE(test_event); +TESTCASE("BasicEventOperation", + "Verify that we can listen to Events" + "NOTE! No errors are allowed!" ){ + INITIALIZER(runCreateEvent); + STEP(runEventOperation); + STEP(runEventOperation); + STEP(runEventOperation); + STEP(runEventOperation); + STEP(runEventLoad); + FINALIZER(runDropEvent); +} +NDBT_TESTSUITE_END(test_event); + +#if 0 +NDBT_TESTSUITE(test_event); +TESTCASE("ParallellEventOperation", + "Verify that we can listen to Events in Parallell" + "NOTE! No errors are allowed!" ){ + INITIALIZER(runCreateAllEvent); + STEP(runEventOperation); + FINALIZER(runDropEvent); +} +NDBT_TESTSUITE_END(test_event); +#endif + +int main(int argc, const char** argv){ + return test_event.execute(argc, argv); +} + diff --git a/ndb/test/ndbapi/test_event/Makefile b/ndb/test/ndbapi/test_event/Makefile deleted file mode 100644 index 6299fa47845..00000000000 --- a/ndb/test/ndbapi/test_event/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := test_event - -SOURCES := test_event.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/test_event/test_event.cpp b/ndb/test/ndbapi/test_event/test_event.cpp deleted file mode 100644 index 40fc1c6defa..00000000000 --- a/ndb/test/ndbapi/test_event/test_event.cpp +++ /dev/null @@ -1,142 +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 */ - -#include "NDBT_Test.hpp" -#include "NDBT_ReturnCodes.h" -#include "HugoTransactions.hpp" -#include "UtilTransactions.hpp" -#include "TestNdbEventOperation.hpp" - -#define GETNDB(ps) ((NDBT_NdbApiStep*)ps)->getNdb() - -int runCreateEvent(NDBT_Context* ctx, NDBT_Step* step) -{ - HugoTransactions hugoTrans(*ctx->getTab()); - - if (hugoTrans.createEvent(GETNDB(step)) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int theThreadIdCounter = 0; - -int runEventOperation(NDBT_Context* ctx, NDBT_Step* step) -{ - int tId = theThreadIdCounter++; - int loops = ctx->getNumLoops(); - int records = ctx->getNumRecords(); - HugoTransactions hugoTrans(*ctx->getTab()); - - EventOperationStats stats; - - g_info << "***** Id " << tId << endl; - - // sleep(tId); - - if (hugoTrans.eventOperation(GETNDB(step), (void*)&stats, 3*records) != 0){ - return NDBT_FAILED; - } - - int ret; - if (stats.n_inserts == records && - stats.n_deletes == records && - stats.n_updates == records && - stats.n_consecutive == 3 && - stats.n_duplicates == 0) - ret = NDBT_OK; - else - ret = NDBT_FAILED; - - if (ret == NDBT_FAILED) { - ndbout << "n_inserts = " << stats.n_inserts << endl; - ndbout << "n_deletes = " << stats.n_deletes << endl; - ndbout << "n_updates = " << stats.n_updates << endl; - ndbout << "n_consecutive = " << stats.n_consecutive << endl; - ndbout << "n_duplicates = " << stats.n_duplicates << endl; - ndbout << "n_inconsistent_gcis = " << stats.n_inconsistent_gcis << endl; - } - - return ret; -} - -int runEventLoad(NDBT_Context* ctx, NDBT_Step* step) -{ - int loops = ctx->getNumLoops(); - int records = ctx->getNumRecords(); - HugoTransactions hugoTrans(*ctx->getTab()); - - sleep(5); - sleep(theThreadIdCounter); - - if (hugoTrans.loadTable(GETNDB(step), records, 1, true, loops) != 0){ - return NDBT_FAILED; - } - if (hugoTrans.pkUpdateRecords(GETNDB(step), records, 1, loops) != 0){ - return NDBT_FAILED; - } - if (hugoTrans.pkDelRecords(GETNDB(step), records, 1, true, loops) != 0){ - return NDBT_FAILED; - } - return NDBT_OK; -} - -int runDropEvent(NDBT_Context* ctx, NDBT_Step* step) -{ - HugoTransactions hugoTrans(*ctx->getTab()); - - theThreadIdCounter = 0; - // if (hugoTrans.createEvent(GETNDB(step)) != 0){ - // return NDBT_FAILED; - // } - return NDBT_OK; -} - -// INITIALIZER(runInsert); -// STEP(runPkRead); -// VERIFIER(runVerifyInsert); -// FINALIZER(runClearTable); - -NDBT_TESTSUITE(test_event); -TESTCASE("BasicEventOperation", - "Verify that we can listen to Events" - "NOTE! No errors are allowed!" ){ - INITIALIZER(runCreateEvent); - STEP(runEventOperation); - STEP(runEventOperation); - STEP(runEventOperation); - STEP(runEventOperation); - STEP(runEventLoad); - FINALIZER(runDropEvent); -} -NDBT_TESTSUITE_END(test_event); - -#if 0 -NDBT_TESTSUITE(test_event); -TESTCASE("ParallellEventOperation", - "Verify that we can listen to Events in Parallell" - "NOTE! No errors are allowed!" ){ - INITIALIZER(runCreateAllEvent); - STEP(runEventOperation); - FINALIZER(runDropEvent); -} -NDBT_TESTSUITE_END(test_event); -#endif - -int main(int argc, const char** argv){ - return test_event.execute(argc, argv); -} - diff --git a/ndb/test/ndbapi/userInterface.cpp b/ndb/test/ndbapi/userInterface.cpp new file mode 100644 index 00000000000..fdbc229cc98 --- /dev/null +++ b/ndb/test/ndbapi/userInterface.cpp @@ -0,0 +1,117 @@ +/* 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 */ + +/*************************************************************** +* I N C L U D E D F I L E S * +***************************************************************/ + +#include +#include + +#include "ndb_schema.hpp" +#include "ndb_error.hpp" +#include "userInterface.h" +#include +#include +#include +#include +#include + +/*************************************************************** +* L O C A L C O N S T A N T S * +***************************************************************/ + +/*************************************************************** +* L O C A L D A T A S T R U C T U R E S * +***************************************************************/ + +/*************************************************************** +* L O C A L F U N C T I O N S * +***************************************************************/ + +#ifndef NDB_WIN32 +#include +#endif + + +static NdbMutex* startupMutex = NdbMutex_Create(); + +Ndb* +asyncDbConnect(int parallellism){ + NdbMutex_Lock(startupMutex); + Ndb * pNDB = new Ndb(""); + + pNDB->init(parallellism + 1); + + while(pNDB->waitUntilReady() != 0){ + } + + NdbMutex_Unlock(startupMutex); + + return pNDB; +} + +void +asyncDbDisconnect(Ndb* pNDB) +{ + delete pNDB; +} + +double +userGetTime(void) +{ + static bool initialized = false; + static NDB_TICKS initSecs = 0; + static Uint32 initMicros = 0; + double timeValue = 0; + + if ( !initialized ) { + initialized = true; + NdbTick_CurrentMicrosecond(&initSecs, &initMicros); + timeValue = 0.0; + } else { + NDB_TICKS secs = 0; + Uint32 micros = 0; + + NdbTick_CurrentMicrosecond(&secs, µs); + double s = (double)secs - (double)initSecs; + double us = (double)micros - (double)initMicros; + + timeValue = s + (us / 1000000.0); + } + return timeValue; +} + +void showTime() +{ + char buf[128]; + struct tm* tm_now; + time_t now; + now = ::time((time_t*)NULL); + tm_now = ::gmtime(&now); + + ::snprintf(buf, 128, + "%d-%.2d-%.2d %.2d:%.2d:%.2d", + tm_now->tm_year + 1900, + tm_now->tm_mon, + tm_now->tm_mday, + tm_now->tm_hour, + tm_now->tm_min, + tm_now->tm_sec); + + ndbout_c("Time: %s", buf); +} + diff --git a/ndb/test/ndbapi/vw_test/Makefile b/ndb/test/ndbapi/vw_test/Makefile deleted file mode 100644 index 144873dcc69..00000000000 --- a/ndb/test/ndbapi/vw_test/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := vw_test -BIN_TARGET_LIBS := orafunctr decode cirk inifunc -BIN_TARGET_LIBS_DIRS := /home/ndb/junk/vw/ndb/lib - -SOURCES := cdrserver.C - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/vw_test/bcd.h b/ndb/test/ndbapi/vw_test/bcd.h deleted file mode 100644 index d0aaffbd8b7..00000000000 --- a/ndb/test/ndbapi/vw_test/bcd.h +++ /dev/null @@ -1,26 +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 */ - -#include - -struct bcdtab { - char tab[3]; -}; - -int dec2hex(int dec,int last); -int bcd_code (char *bcd_in,char *bcd_out); -int bcd_decode (int bcd_len,char *bcd_in,char *bcd_out); -int bcd_decode2 (int bcd_len,char *bcd_in,char *bcd_out); diff --git a/ndb/test/ndbapi/vw_test/cdrserver.cpp b/ndb/test/ndbapi/vw_test/cdrserver.cpp deleted file mode 100644 index 8354d28f53f..00000000000 --- a/ndb/test/ndbapi/vw_test/cdrserver.cpp +++ /dev/null @@ -1,1627 +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 */ - -/* **************************************************************** */ -/* */ -/* S E R V . T C P */ -/* * This is an example program that demonstrates the use of */ -/* stream sockets as an IPC mechanism. This contains the server, */ -/* and is intended to operate in conjunction with the client */ -/* program found in client.tcp. Together, these two programs */ -/* demonstrate many of the features of sockets, as well as good */ -/* conventions for using these features. */ -/* * This program provides a service called "example". In order for*/ -/* it to function, an entry for it needs to exist in the */ -/* ./etc/services file. The port address for this service can be */ -/* any port number that is likely to be unused, such as 22375, */ -/* for example. The host on which the client will be running */ -/* must also have the same entry (same port number) in its */ -/* ./etc/services file. */ -/* **************************************************************** */ - -#include - -/******** NDB INCLUDE ******/ -#include -/***************************/ -/*#include */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern "C" { -#include "utv.h" -#include "vcdrfunc.h" -#include "bcd.h" -} - -#ifndef TESTLEV -#define TESTLEV -#endif -//#define DEBUG -//#define MYDEBUG -//#define SETDBG - -//#define ops_before_exe 64 -#define MAXOPSEXEC 1024 - -/* Used in nanosleep */ -/**** NDB ********/ -static int bTestPassed; -void create_table(Ndb* pMyNdb); -void error_handler(const char* errorText); -/*****************/ -static struct timespec tmspec1; -static int server(long int); - -/* Function for initiating the cdr-area and make it clean for ongoing calls */ - -static int s; /* connected socket descriptor */ -static int ls; /* listen socket descriptor */ - -static struct hostent *hp; /* pointer to host info for remote host */ -static struct servent *sp; /* pointer to service information */ - -struct linger linger; /* allow a lingering, graceful close; */ - /* used when setting SO_LINGER */ - -static struct sockaddr_in myaddr_in; /* for local socket address */ -static struct sockaddr_in peeraddr_in; /* for peer socket address */ - -static FILE *fi; /* Log output */ -static char temp[600]=""; - -static int ops_before_exe = 1; /* Number of operations per execute, default is 1, - but it can be changed with the -o parameter. */ - -/*---------------------------------------------------------------------- - - M A I N - * This routine starts the server. It forks, leaving the child - to do all the work, so it does not have to be run in the - background. It sets up the listen socket, and for each incoming - connection, it forks a child process to process the data. It - will loop forever, until killed by a signal. - - ----------------------------------------------------------------------*/ - -/****** NDB *******/ -static char *tableName = "VWTABLE"; -/******************/ - -#include -using namespace std; - -int main(int argc, const char** argv) -{ - /******** NDB ***********/ - /* - Ndb MyNdb( "TEST_DB" ); - int tTableId; - */ - /************************/ - char tmpbuf[400]; - /* Loop and status variables */ - int i,j,found; - - /* Used by the server */ - int addrlen; - - /* return code used with functions */ - int rc; - - i = 1; - while (argc > 1) - { - if (strcmp(argv[i], "-o") == 0) - { - ops_before_exe = atoi(argv[i+1]); - if ((ops_before_exe < 1) || (ops_before_exe > MAXOPSEXEC)) - { - cout << "Number of operations per execute must be at least 1, and at most " << MAXOPSEXEC << endl; - exit(1); - } - - } - else - { - cout << "Invalid parameter!" << endl << "Look in cdrserver.C for more info." << endl; - exit(1); - } - - argc -= 2; - i = i + 2; - } - - - /* Setup log handling */ - logname(temp,"Cdrserver","Mother",""); - puts(temp); - fi=fopen(temp,"w"); - if (fi == NULL) - { - perror(argv[0]); - exit(EXIT_FAILURE); - } - m2log(fi,"Initiation of program"); - - /***** NDB ******/ - /* - MyNdb.init(); - if (MyNdb.waitUntilReady(30) != 0) - { - puts("Not ready"); - exit(-1); - } - tTableId = MyNdb.getTable()->openTable(tableName); - if (tTableId == -1) - { - printf("%d: Creating table",getpid()); - create_table(&MyNdb); - } - else printf("%d: Table already create",getpid()); - */ - - /****************/ - - /* clear out address structures */ - memset ((char *)&myaddr_in, 0, sizeof(struct sockaddr_in)); - memset ((char *)&peeraddr_in, 0, sizeof(struct sockaddr_in)); - - m2log(fi,"Socket setup starting"); - - /* Set up address structure for the listen socket. */ - myaddr_in.sin_family = AF_INET; - - /* The server should listen on the wildcard address, */ - /* rather than its own internet address. This is */ - /* generally good practice for servers, because on */ - /* systems which are connected to more than one */ - /* network at once will be able to have one server */ - /* listening on all networks at once. Even when the */ - /* host is connected to only one network, this is good */ - /* practice, because it makes the server program more */ - /* portable. */ - - myaddr_in.sin_addr.s_addr = INADDR_ANY; - /* Find the information for the "cdrserver" server */ - /* in order to get the needed port number. */ - - sp = getservbyname ("cdrserver", "tcp"); - if (sp == NULL) { - m2log(fi,"Service cdrserver not found in /etc/services"); - m2log(fi,"Terminating."); - exit(EXIT_FAILURE); - } - - myaddr_in.sin_port = sp->s_port; - - /* Create the listen socket.i */ - - ls = socket (AF_INET, SOCK_STREAM, 0); - if (ls == -1) { - m2log(fi,"Unable to create socket"); - m2log(fi,"Terminating."); - exit(EXIT_FAILURE); - } - printf("Socket created\n"); - printf("Wait..........\n"); - /* Bind the listen address to the socket. */ - if (bind(ls,(struct sockaddr*)&myaddr_in, sizeof(struct sockaddr_in)) == -1) { - m2log(fi,"Unable to bind address"); - m2log(fi,"Terminating."); - exit(EXIT_FAILURE); - } - - /* Initiate the listen on the socket so remote users */ - /* can connect. The listen backlog is set to 5, which */ - /* is the largest currently supported. */ - - if (listen(ls, 5) == -1) { - m2log(fi,"Unable to listen on socket"); - m2log(fi,"Terminating."); - exit(EXIT_FAILURE); - } - - /* Now, all the initialization of the server is */ - /* complete, and any user errors will have already */ - /* been detected. Now we can fork the daemon and */ - /* return to the user. We need to do a setpgrp */ - /* so that the daemon will no longer be associated */ - /* with the user's control terminal. This is done */ - /* before the fork, so that the child will not be */ - /* a process group leader. Otherwise, if the child */ - /* were to open a terminal, it would become associated */ - /* with that terminal as its control terminal. It is */ - /* always best for the parent to do the setpgrp. */ - - m2log(fi,"Socket setup completed"); - m2log(fi,"Start server"); - - setpgrp(); - - /* Initiate the tmspec struct for use with nanosleep() */ - tmspec1.tv_sec = 0; - tmspec1.tv_nsec = 1; - - printf("Waiting for client to connect.........\n"); - printf("Done\n"); - switch (fork()) { - case -1: /* Unable to fork, for some reason. */ - m2log(fi,"Failed to start server"); - m2log(fi,"Terminating."); - fclose(fi); - perror(argv[0]); - fprintf(stderr, "%s: unable to fork daemon\n", argv[0]); - exit(EXIT_FAILURE); - - break; - case 0: /* The child process (daemon) comes here. */ - m2log(fi,"Server started"); - - /* Close stdin and stderr so that they will not */ - /* be kept open. Stdout is assumed to have been */ - /* redirected to some logging file, or /dev/null. */ - /* From now on, the daemon will not report any */ - /* error messages. This daemon will loop forever, */ - /* waiting for connections and forking a child */ - /* server to handle each one. */ - - close((int)stdin); - close((int)stderr); - /* Set SIGCLD to SIG_IGN, in order to prevent */ - /* the accumulation of zombies as each child */ - /* terminates. This means the daemon does not */ - /* have to make wait calls to clean them up. */ - - signal(SIGCLD, SIG_IGN); - for(EVER) { - if ((checkchangelog(fi,temp))==0) - m2log(fi,"Waiting for connection"); - /* Note that addrlen is passed as a pointer */ - /* so that the accept call can return the */ - /* size of the returned address. */ - - addrlen = sizeof(struct sockaddr_in); - - /* This call will block until a new */ - /* connection arrives. Then, it will */ - /* return the address of the connecting */ - /* peer, and a new socket descriptor, s, */ - /* for that connection. */ - - s = accept(ls,(struct sockaddr*) &peeraddr_in, &addrlen); - #ifdef MYDEBUG - puts("accepted"); - #endif - if ((checkchangelog(fi,temp))==0) - m2log(fi,"Connection attempt from a client"); - if ((checkchangelog(fi,temp))==0) - m2log(fi,"Start communication server"); - - if ( s == -1) exit(EXIT_FAILURE); - switch (fork()) { - case -1: /* Can't fork, just exit. */ - if ((checkchangelog(fi,temp))==0) - m2log(fi,"Start communication server failed."); - exit(EXIT_FAILURE); - break; - case 0: /* Child process comes here. */ - - /* Get clients adress and save it in the info area */ - /* Keep track of how many times the client connects to the server */ - printf("Connect attempt from client %u\n",peeraddr_in.sin_addr.s_addr); - server(peeraddr_in.sin_addr.s_addr); - exit(EXIT_FAILURE); - break; - default: /* Daemon process comes here. */ - /* The daemon needs to remember */ - /* to close the new accept socket */ - /* after forking the child. This */ - /* prevents the daemon from running */ - /* out of file descriptor space. It */ - /* also means that when the server */ - /* closes the socket, that it will */ - /* allow the socket to be destroyed */ - /* since it will be the last close. */ - close(s); - break; - } - } - default: /* Parent process comes here. */ - exit(EXIT_FAILURE); - } - return EXIT_SUCCESS; -} - -/*---------------------------------------------------------------------- - - S E R V E R - * This is the actual server routine that the daemon forks to - handle each individual connection. Its purpose is to receive - the request packets from the remote client, process them, - and return the results to the client. It will also write some - logging information to stdout. - - ----------------------------------------------------------------------*/ - -server(long int servernum) -{ - /******** NDB ***********/ - Ndb MyNdb( "TEST_DB" ); - int tTableId; - NdbConnection *MyTransaction; - NdbOperation *MyOperation; - int check; - int c1 = 0; - int c2 = 0; - int c3 = 0; - int c4 = 0; - int act_index = 0; - /************************/ - register unsigned int reqcnt; /* keeps count of number of requests */ - register unsigned int i; /* Loop counters */ - register int x; - register short done; /* Loop variable */ - short int found; - - /* The server index number */ - int thisServer; - - /* Variables used to keep track of some statistics */ - time_t ourtime; - time_t tmptime; - int tmpvalue; - long int tmptransfer; - long int transfer; - int ops = 0; - - /* Variables used by the server */ - char buf[400]; /* This example uses 10 byte messages. */ - char *inet_ntoa(); - char *hostname; /* points to the remote host's name string */ - int len; - int rcvbuf_size; - - long ctid; - - unsigned char uc; - - /* Variables used by the logging facilitiy */ - char msg[600]; - char crap[600]; - char lognamn[600]; - - FILE *log; - - /* scheduling parameter for pthread */ - struct sched_param param1,param2,param3; - - /* Header information */ - /* cdrtype not used */ - /*short cdrtype; */ /* 1 CDR Typ */ - short cdrlen; /* 2 CDR recored length in bytes excluding CDR type */ - short cdrsubtype; /* 1 CDR subtype */ - unsigned int cdrid; /* 8 CDR unique number of each call */ - unsigned int cdrtime; /* 4 CDR Time in seconds */ - short cdrmillisec; /* 2 CDR Milliseconds */ - short cdrstatus; /* 1 CDR For future use */ - short cdrequipeid; /* 1 CDR Equipment id */ - int cdrreserved1; /* 4 CDR For future use */ - - /* Defined or calculated for each record */ - int cdrrestlen; /* Unprocessed data left in record in bytes */ - - /* Gemensamma datatyper */ - unsigned short parmtype_prev; /* 1 Parameter type */ - unsigned short parmtype; /* 1 Parameter type */ - unsigned short parmlen; /* 1 Parameter type */ - - int rc; /* return code for functions */ - - /* Attribute object used with threads */ - pthread_attr_t attr1; - pthread_attr_t attr2; - pthread_attr_t attr3; - struct cdr_record *tmpcdrptr,*ftest; - void *dat; - - int error_from_client = 0; - - /* Konstanter */ - const int headerlen = 24; /* Length of header record */ - - parmtype_prev = 99; - reqcnt = 0; - - /* Close the listen socket inherited from the daemon. */ - close(ls); - - printf("Use the readinfo program to get information about server status\n\n"); - - if((checkchangelog(fi,temp))==0) - c2log(fi,"Communication server started"); - - /* Look up the host information for the remote host */ - /* that we have connected with. Its internet address */ - /* was returned by the accept call, in the main */ - /* daemon loop above. */ - - hp=gethostbyaddr((char *) &peeraddr_in.sin_addr,sizeof(struct in_addr),peeraddr_in.sin_family); - - if (hp == NULL) { - /* The information is unavailable for the remote */ - /* host. Just format its internet address to be */ - /* printed out in the logging information. The */ - /* address will be shown in "internet dot format". */ - - /* - hostname = inet_ntoa(peeraddr_in.sin_addr); - */ - sprintf(hostname,"Test"); - logname(lognamn,"Cdrserver","Child",hostname); - } - else { - hostname = hp->h_name; /* point to host's name */ - logname(lognamn,"Cdrserver","Child",hostname); - } - - log=fopen(lognamn,"w"); - if (log == NULL) - { - perror(hostname); - exit(EXIT_FAILURE); - } - n2log(log,"Setup in progress"); - /* Log a startup message. */ - - /* The port number must be converted first to host byte */ - /* order before printing. On most hosts, this is not */ - /* necessary, but the ntohs() call is included here so */ - /* that this program could easily be ported to a host */ - /* that does require it. */ - - snprintf(msg,sizeof(msg),"Startup from %s port %u",hostname,ntohs(peeraddr_in.sin_port)); - if ((checkchangelog(fi,temp))==0) - c2log(fi,msg); - n2log(log,msg); - snprintf(msg,sizeof(msg),"For further information, see log(%s)",lognamn); - if ((checkchangelog(fi,temp))==0) - c2log(fi,msg); - - /* Set the socket for a lingering, graceful close. */ - /* This will cause a final close of this socket to wait until */ - /* all * data sent on it has been received by the remote host. */ - - linger.l_onoff =1; - linger.l_linger =0; - if (setsockopt(s, SOL_SOCKET, SO_LINGER,(const char*)&linger,sizeof(linger)) == -1) { - snprintf(msg,sizeof(msg),"Setting SO_LINGER, l_onoff=%d, l_linger=%d",linger.l_onoff,linger.l_linger); - if ((checkchangelog(log,lognamn))==0) - n2log(log,msg); - goto errout; - } - - /* Set the socket for a lingering, graceful close. */ - /* This will cause a final close of this socket to wait until all * data sent */ - /* on it has been received by the remote host. */ - - rcvbuf_size=64*1024; - - if (setsockopt(s, SOL_SOCKET, SO_RCVBUF,(const char*) &rcvbuf_size,sizeof(rcvbuf_size)) == -1) { - snprintf(msg,sizeof(msg),"Setting SO_RCVBUF = %d",rcvbuf_size); - if ((checkchangelog(log,lognamn))==0) - n2log(log,msg); - goto errout; - } - - /* Set nodelay on socket */ - n2log(log,"Port setup complete"); - - /* Go into a loop, receiving requests from the remote */ - /* client. After the client has sent the last request, */ - /* it will do a shutdown for sending, which will cause */ - /* an end-of-file condition to appear on this end of the */ - /* connection. After all of the client's requests have */ - /* been received, the next recv call will return zero */ - /* bytes, signalling an end-of-file condition. This is */ - /* how the server will know that no more requests will */ - /* follow, and the loop will be exited. */ - - n2log(log,"Setup completed"); - - /* Fetch the process id for the server */ - - /* Inititate the variables used for counting transfer rates and rec/sec */ - tmpvalue = 0; - tmptime = 0; - tmptransfer = 0; - transfer = 0; - - printf("Client %s connected\nStarting to process the data\n\n",hostname); - - tmpcdrptr = (struct cdr_record*)malloc(sizeof(struct cdr_record)); - - /***** NDB ******/ - MyNdb.init(); - if (MyNdb.waitUntilReady(30) != 0) - { - puts("Not ready"); - exit(-1); - } - tTableId = MyNdb.getTable()->openTable(tableName); - if (tTableId == -1) - { - printf("%d: Creating table",getpid()); - create_table(&MyNdb); - } - else printf("%d: Table already created",getpid()); - - /****************/ - - while (len = recv(s,buf,headerlen,MSG_WAITALL)) { - if (len == -1) { - snprintf(msg,sizeof(msg),"Error from recv"); - if ((checkchangelog(log,lognamn))==0) - n2log(log,msg); - goto errout; /* error from recv */ - } - - /* The reason this while loop exists is that there */ - /* is a remote possibility of the above recv returning */ - /* less than 10 bytes. This is because a recv returns */ - /* as soon as there is some data, and will not wait for */ - /* all of the requested data to arrive. Since 10 bytes */ - /* is relatively small compared to the allowed TCP */ - /* packet sizes, a partial receive is unlikely. If */ - /* this example had used 2048 bytes requests instead, */ - /* a partial receive would be far more likely. */ - /* This loop will keep receiving until all 10 bytes */ - /* have been received, thus guaranteeing that the */ - /* next recv at the top of the loop will start at */ - /* the begining of the next request. */ - - for (;len < headerlen;) { - x = recv(s,buf,(headerlen-len),0); - if (x == -1) { - snprintf(msg,sizeof(msg),"Error from recv"); - if ((checkchangelog(log,lognamn))==0) - n2log(log,msg); - goto errout; /* error from recv */ - } - len=len+x; - } - - if (ops == 0) { - MyTransaction = MyNdb.startTransaction(); - if (MyTransaction == NULL) - error_handler(MyNdb.getNdbErrorString()); - }//if - - MyOperation = MyTransaction->getNdbOperation(tableName); - if (MyOperation == NULL) - error_handler(MyTransaction->getNdbErrorString()); - /*------------------------------------------------------*/ - /* Parse header of CDR records */ - /*------------------------------------------------------*/ - - /*------------------------------------------------------*/ - /* 1. Type of cdr */ - /*------------------------------------------------------*/ - /* Not used for the moment - cdrtype=(char)buf[0]; - */ - /*------------------------------------------------------*/ - /* 2. Total length of CDR */ - /*------------------------------------------------------*/ - swab(buf+1,buf+1,2); - memcpy(&cdrlen,buf+1,2); - /*------------------------------------------------------*/ - /* 3. Partial type of CDR */ - /*------------------------------------------------------*/ - cdrsubtype=(char)buf[3]; - switch (cdrsubtype) - { - case 0: - c1++; - tmpcdrptr->CallAttemptState = 1; - check = MyOperation->insertTuple(); - break; - case 1: - c2++; - tmpcdrptr->CallAttemptState = 2; - check = MyOperation->updateTuple(); - break; - case 2: - c3++; - tmpcdrptr->CallAttemptState = 3; - check = MyOperation->deleteTuple(); - break; - case 3: - c4++; - tmpcdrptr->CallAttemptState = 4; - check = MyOperation->deleteTuple(); - break; - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - } - /*cdrsubtype=(cdrsubtype << 24) >> 24;*/ - /*------------------------------------------------------*/ - /* 4. ID number */ - /*------------------------------------------------------*/ - /*swab(buf+4,buf+4,4);*/ /* ABCD -> BADC */ - /* - swab(buf+4,buf+4,4); - swab(buf+5,buf+5,2); - swab(buf+6,buf+6,2); - swab(buf+4,buf+4,2); - swab(buf+5,buf+5,2); - */ - memcpy(&cdrid,buf+4,4); - tmpcdrptr->CallIdentificationNumber = cdrid; - #ifdef SETDBG - puts("CIN"); - #endif - check = MyOperation->equal("CIN",(char*)&cdrid); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - #ifdef SETDBG - puts("CAS"); - #endif - - if (cdrsubtype < 2) - { - check = MyOperation->setValue("CAS",(char*)&cdrsubtype); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - } - /*------------------------------------------------------*/ - /* 5. Time stamp */ - /*------------------------------------------------------*/ - swab(buf+12,buf+12,4); - swab(buf+13,buf+13,2); - swab(buf+14,buf+14,2); - swab(buf+12,buf+12,2); - swab(buf+13,buf+13,2); - memcpy(&cdrtime,buf+12,4); - switch (cdrsubtype) - { - case 0: - #ifdef SETDBG - puts("START_TIME"); - #endif - check = MyOperation->setValue("START_TIME",(char*)&cdrtime); - break; - case 1: - #ifdef SETDBG - puts("Start1"); - #endif - check = MyOperation->setValue("StartOfCharge",(char*)&cdrtime); - break; - case 2: - #ifdef SETDBG - puts("Start2"); - #endif - /* - check = MyOperation->setValue("StopOfCharge",(char*)&cdrtime); - */ - check = 0; - break; - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - } - /*------------------------------------------------------*/ - /* 6. Milliseconds */ - /*------------------------------------------------------*/ - /* Not used by application - swab(buf+16,buf+16,2); - memcpy(&cdrmillisec,buf+16,2); - */ - /*------------------------------------------------------*/ - /* 7. CDR status reserverd for future use */ - /*------------------------------------------------------*/ - /* Not used by application - memcpy(&cdrstatus,buf+18,1); - */ - /*------------------------------------------------------*/ - /* 8. CDR equipe id, number of sending equipement */ - /*------------------------------------------------------*/ - /* Not used by application - memcpy(&cdrequipeid,buf+19,1); - */ - /*cdrequipeid=(cdrequipeid << 24) >> 24;*/ - /*------------------------------------------------------*/ - /* 9. CDR reserverd for furter use */ - /*------------------------------------------------------*/ - /* Not used by applikation - swab(buf+20,buf+20,4); - swab(buf+21,buf+21,2); - swab(buf+22,buf+22,2); - swab(buf+20,buf+20,2); - swab(buf+21,buf+21,2); - memcpy(&cdrreserved1,buf+20,4); - */ - /*------------------------------------------------------*/ - /* calculate length of datapart in record */ - /* Formula recordlength-headerlen-1 */ - /*------------------------------------------------------*/ - cdrrestlen=cdrlen-(headerlen-1); - /*------------------------------------------------------*/ - /* Finished with header */ - /*------------------------------------------------------*/ - /* Read remaining cdr data into buffer for furter */ - /* handling. */ - /*------------------------------------------------------*/ - len = recv(s,buf,cdrrestlen,MSG_WAITALL); - if (len == -1) { - snprintf(msg,sizeof(msg),"Error from recv"); - if ((checkchangelog(log,lognamn))==0) - n2log(log,msg); - goto errout; /* error from recv */ - } - for (;len 1) - { - #ifdef SETDBG - puts("Going to execute"); - #endif - ops++; - if (ops == ops_before_exe) { - ops = 0; - check = MyTransaction->execute(Commit, CommitAsMuchAsPossible); - if ((check == -1) && (MyTransaction->getNdbError() != 0)) - error_handler(MyTransaction->getNdbErrorString()); - MyNdb.closeTransaction(MyTransaction); - #ifdef SETDBG - puts("Transaction closed"); - #endif - }//if - reqcnt++; - continue; - } - for (x=0;x<=cdrrestlen && !done && cdrrestlen > 1;) { - uc=buf[x]; - parmtype=uc; - /*parmtype=(parmtype << 24) >> 24;*/ /* Modified in sun worked in hp */ - - parmlen = buf[x+1]; - /*parmlen =(parmlen << 24) >> 24;*/ - x+=2; - - switch (parmtype) { - case 4: /* Called party number */ - bcd_decode2(parmlen,&buf[x],crap); - tmpcdrptr->BSubscriberNumberLength = (char)parmlen; - strcpy(tmpcdrptr->BSubscriberNumber,crap); - tmpcdrptr->BSubscriberNumber[parmlen] = '\0'; - x=x+(parmlen/2); - if (parmlen % 2) x++; - tmpcdrptr->USED_FIELDS |= B_BSubscriberNumber; - #ifdef SETDBG - puts("BNumber"); - #endif - check = MyOperation->setValue("BNumber",(char*)&tmpcdrptr->BSubscriberNumber); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - break; - case 9: /* Calling Partys cataegory */ - if (parmlen != 1) printf("ERROR: Calling partys category has wrong length %d\n",parmlen); - else tmpcdrptr->ACategory=(char)buf[x]; - x+=parmlen; - tmpcdrptr->USED_FIELDS |= B_ACategory; - #ifdef SETDBG - puts("ACategory"); - #endif - check = MyOperation->setValue("ACategory",(char*)&tmpcdrptr->ACategory); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - break; - case 10: /* Calling Party Number */ - bcd_decode2(parmlen,&buf[x],crap); - tmpcdrptr->ASubscriberNumberLength = (char)parmlen; - strcpy(tmpcdrptr->ASubscriberNumber,crap); - tmpcdrptr->ASubscriberNumber[parmlen] = '\0'; - x=x+(parmlen/2); - if (parmlen % 2) x++; - tmpcdrptr->USED_FIELDS |= B_ASubscriberNumber; - #ifdef SETDBG - puts("ANumber"); - #endif - check = MyOperation->setValue("ANumber",(char*)&tmpcdrptr->ASubscriberNumber); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - break; - case 11: /* Redirecting number */ - bcd_decode2(parmlen,&buf[x],crap); - strcpy(tmpcdrptr->RedirectingNumber,crap); - x=x+(parmlen/2); - if (parmlen % 2) x++; - tmpcdrptr->USED_FIELDS |= B_RedirectingNumber; - #ifdef SETDBG - puts("RNumber"); - #endif - check = MyOperation->setValue("RNumber",(char*)&tmpcdrptr->RedirectingNumber); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - break; - case 17: /* Called partys category */ - if (parmlen != 1) printf("ERROR: Called partys category has wrong length %d\n",parmlen); - else tmpcdrptr->EndOfSelectionInformation=(char)buf[x]; - x+=parmlen; - tmpcdrptr->USED_FIELDS |= B_EndOfSelectionInformation; - #ifdef SETDBG - puts("EndOfSelInf"); - #endif - check = MyOperation->setValue("EndOfSelInf",(char*)&tmpcdrptr->EndOfSelectionInformation); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - break; - case 18: /* Release reason */ - if (parmlen != 1) printf("ERROR: Release reason has wrong length %d\n",parmlen); - else tmpcdrptr->CauseCode=(char)buf[x]; - x+=parmlen; - tmpcdrptr->USED_FIELDS |= B_CauseCode; - #ifdef SETDBG - puts("CauseCode"); - #endif - check = MyOperation->setValue("CauseCode",(char*)&tmpcdrptr->CauseCode); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - break; - case 19: /* Redirection information */ - switch (parmlen) { - case 1: - tmpcdrptr->ReroutingIndicator= (char)buf[x]; - tmpcdrptr->USED_FIELDS |= B_ReroutingIndicator; - break; - case 2: - swab(buf+x,buf+x,2); - tmpcdrptr->ReroutingIndicator= buf[x]; - tmpcdrptr->USED_FIELDS |= B_ReroutingIndicator; - break; - default : - snprintf(msg,sizeof(msg),"ERROR: Redirection information has wrong length %d\n",parmlen); - if ((checkchangelog(log,lognamn))==0) - n2log(log,msg); - break; - #ifdef SETDBG - puts("RI"); - #endif - check = MyOperation->setValue("RI",(char*)&tmpcdrptr->ReroutingIndicator); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - } - x+=parmlen; - break; - case 32: /* User to user information */ - if (parmlen != 1) printf("ERROR: User to User information has wrong length %d\n",parmlen); - else tmpcdrptr->UserToUserInformation=(char)buf[x]; - x+=parmlen; - tmpcdrptr->USED_FIELDS |= B_UserToUserInformation; - #ifdef SETDBG - puts("UserToUserInf"); - #endif - check = MyOperation->setValue("UserToUserInf",(char*)&tmpcdrptr->UserToUserInformation); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - break; - case 40: /* Original called number */ - bcd_decode2(parmlen,&buf[x],crap); - strcpy(tmpcdrptr->OriginalCalledNumber,crap); - x=x+(parmlen/2); - if (parmlen % 2) x++; - tmpcdrptr->USED_FIELDS |= B_OriginalCalledNumber; - #ifdef SETDBG - puts("ONumber"); - #endif - check = MyOperation->setValue("ONumber",(char*)&tmpcdrptr->OriginalCalledNumber); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - break; - case 42: /* User to user indicator */ - if (parmlen != 1) printf("ERROR: User to User indicator has wrong length %d\n",parmlen); - else tmpcdrptr->UserToUserIndicatior=(char)buf[x]; - x+=parmlen; - tmpcdrptr->USED_FIELDS |= B_UserToUserIndicatior; - #ifdef SETDBG - puts("UserToUserInd"); - #endif - check = MyOperation->setValue("UserToUserInd",(char*)&tmpcdrptr->UserToUserIndicatior); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - break; - case 63: /* Location number */ - bcd_decode2(parmlen,&buf[x],crap); - strcpy(tmpcdrptr->LocationCode,crap); - x=x+(parmlen/2); - if (parmlen % 2) x++; - tmpcdrptr->USED_FIELDS |= B_LocationCode; - #ifdef SETDBG - puts("LocationCode"); - #endif - check = MyOperation->setValue("LocationCode",(char*)&tmpcdrptr->LocationCode); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - break; - case 240: /* Calling Partys cataegory */ - if (parmlen != 1) printf("ERROR: Calling partys category has wrong length %d\n",parmlen); - else tmpcdrptr->NetworkIndicator=(char)buf[x]; - x+=parmlen; - tmpcdrptr->USED_FIELDS |= B_NetworkIndicator; - #ifdef SETDBG - puts("NIndicator"); - #endif - check = MyOperation->setValue("NIndicator",(char*)&tmpcdrptr->NetworkIndicator); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - break; - case 241: /* Calling Partys cataegory */ - if (parmlen != 1) printf("ERROR: Calling partys category has wrong length %d\n",parmlen); - else tmpcdrptr->TonASubscriberNumber=(char)buf[x]; - x+=parmlen; - tmpcdrptr->USED_FIELDS |= B_TonASubscriberNumber; - #ifdef SETDBG - puts("TonANumber"); - #endif - check = MyOperation->setValue("TonANumber",(char*)&tmpcdrptr->TonASubscriberNumber); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - break; - case 242: /* Calling Partys cataegory */ - if (parmlen != 1) printf("ERROR: Calling partys category has wrong length %d\n",parmlen); - else tmpcdrptr->TonBSubscriberNumber=(char)buf[x]; - x+=parmlen; - tmpcdrptr->USED_FIELDS |= B_TonBSubscriberNumber; - #ifdef SETDBG - puts("TonBNumber"); - #endif - check = MyOperation->setValue("TonBNumber",(char*)&tmpcdrptr->TonBSubscriberNumber); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - break; - case 243: /* Calling Partys cataegory */ - if (parmlen != 1) printf("ERROR: Calling partys category has wrong length %d\n",parmlen); - else tmpcdrptr->TonRedirectingNumber=(char)buf[x]; - x+=parmlen; - tmpcdrptr->USED_FIELDS |= B_TonRedirectingNumber; - #ifdef SETDBG - puts("TonRNumber"); - #endif - check = MyOperation->setValue("TonRNumber",(char*)&tmpcdrptr->TonRedirectingNumber); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - break; - case 244: /* Calling Partys cataegory */ - if (parmlen != 1) printf("ERROR: Calling partys category has wrong length %d\n",parmlen); - else tmpcdrptr->TonOriginalCalledNumber=(char)buf[x]; - x+=parmlen; - tmpcdrptr->USED_FIELDS |= B_TonOriginalCalledNumber; - #ifdef SETDBG - puts("TonONumber"); - #endif - check = MyOperation->setValue("TonONumber",(char*)&tmpcdrptr->TonOriginalCalledNumber); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - break; - case 245: /* Calling Partys cataegory */ - if (parmlen != 1) printf("ERROR: Calling partys category has wrong length %d\n",parmlen); - else tmpcdrptr->TonLocationCode=(char)buf[x]; - x+=parmlen; - tmpcdrptr->USED_FIELDS |= B_TonLocationCode; - #ifdef SETDBG - puts("TonLocationCode"); - #endif - check = MyOperation->setValue("TonLocationCode",(char*)&tmpcdrptr->TonLocationCode); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - break; - case 252: /* RINParameter Parameter */ - switch (parmlen) { - case 1: - tmpcdrptr->RINParameter=buf[x]; - tmpcdrptr->USED_FIELDS |= B_RINParameter; - break; - case 2: - swab(buf+x,buf+x,2); - tmpcdrptr->RINParameter = buf[x] << 8; - tmpcdrptr->USED_FIELDS |= B_RINParameter; - break; - default : - snprintf(msg,sizeof(msg),"ERROR: Rin parameter has wrong length %d\n",parmlen); - if ((checkchangelog(log,lognamn))==0) - n2log(log,msg); - break; - } - x+=parmlen; - #ifdef SETDBG - puts("RINParameter"); - #endif - check = MyOperation->setValue("RINParameter",(char*)&tmpcdrptr->RINParameter); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - break; - case 253: /* OriginatingPointCode */ - switch (parmlen) { - case 2: - swab(buf+x,buf+x,2); - memcpy(&tmpcdrptr->OriginatingPointCode,(buf+x),2); - tmpcdrptr->USED_FIELDS |= B_OriginatingPointCode; - break; - case 3: - swab(buf+x,buf+x,2); - swab(buf+(x+1),buf+(x+1),2); - swab(buf+x,buf+x,2); - memcpy(&tmpcdrptr->OriginatingPointCode,(buf+x),3); - tmpcdrptr->USED_FIELDS |= B_OriginatingPointCode; - break; - default : - snprintf(msg,sizeof(msg),"ERROR: OriginatingPointCode parameter has wrong length %d\n",parmlen); - if ((checkchangelog(log,lognamn))==0) - n2log(log,msg); - break; - } - x+=parmlen; - #ifdef SETDBG - puts("OPC"); - #endif - check = MyOperation->setValue("OPC",(char*)&tmpcdrptr->OriginatingPointCode); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - break; - case 254: /* DestinationPointCode */ - switch (parmlen) { - case 2: - swab(buf+x,buf+x,2); - memcpy(&tmpcdrptr->DestinationPointCode,(buf+x),2); - /* - tmpcdrptr->DestinationPointCode = buf[x] << 8; - */ - tmpcdrptr->USED_FIELDS |= B_DestinationPointCode; - break; - case 3: - swab(buf+x,buf+x,2); - swab(buf+(x+1),buf+(x+1),2); - swab(buf+x,buf+x,2); - memcpy(&tmpcdrptr->DestinationPointCode,(buf+x),3); - tmpcdrptr->USED_FIELDS |= B_DestinationPointCode; - break; - default : - snprintf(msg,sizeof(msg),"ERROR: DestinationPointCode parameter has wrong length %d\n",parmlen); - if ((checkchangelog(log,lognamn))==0) - n2log(log,msg); - break; - } - x+=parmlen; - #ifdef SETDBG - puts("DPC"); - #endif - check = MyOperation->setValue("DPC",(char*)&tmpcdrptr->DestinationPointCode); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - break; - case 255: /* CircuitIdentificationCode */ - swab(buf+x,buf+x,2); - memcpy(&tmpcdrptr->CircuitIdentificationCode,(buf+x),2); - tmpcdrptr->USED_FIELDS |= B_CircuitIdentificationCode; - x+=parmlen; - #ifdef SETDBG - puts("CIC"); - #endif - check = MyOperation->setValue("CIC",(char*)&tmpcdrptr->CircuitIdentificationCode); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - break; - default: - printf("ERROR: Undefined parmtype %d , previous %d, length %d\n",parmtype,parmtype_prev,parmlen); - snprintf(msg,sizeof(msg),"ERROR: Undefined parmtype %d , previous %d, length %d\n",parmtype,parmtype_prev,parmlen); - if ((checkchangelog(log,lognamn))==0) - n2log(log,msg); - if (parmlen == 0) { - x++; - } - x+=parmlen; - break; - } - parmtype_prev=parmtype; - if ((cdrrestlen-x) == 1) { - done=TRUE; - } - } - time(&ourtime); - if (ourtime != tmptime) - { - transfer = tmptransfer; - tmptransfer = 0; - if (++act_index == 30) - { - act_index = 0; - printf("Transfer=%d\n",transfer); - printf("Total operations=%d\n",reqcnt); - printf("CAS1=%d\n",c1/30); - printf("CAS2=%d\n",c2/30); - printf("CAS3=%d\n",c3/30); - c1=0; - c2=0; - c3=0; - } - tmptime = ourtime; - } - switch (cdrsubtype) { - case 0: - tmpcdrptr->ClientId = servernum; - #ifdef SETDBG - puts("ClientId"); - #endif - check = MyOperation->setValue("ClientId",(char*)&tmpcdrptr->ClientId); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - tmpcdrptr->OurSTART_TIME = ourtime; - #ifdef SETDBG - puts("OurSTART_TIME"); - #endif - check = MyOperation->setValue("OurSTART_TIME",(char*)&tmpcdrptr->OurSTART_TIME); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - tmpcdrptr->USED_FIELDS |= B_START_TIME; - #ifdef SETDBG - puts("USED_FIELDS"); - #endif - check = MyOperation->setValue("USED_FIELDS",(char*)&tmpcdrptr->USED_FIELDS); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - break; - - case 1: - tmpcdrptr->OurTimeForStartOfCharge = ourtime; - #ifdef SETDBG - puts("OurStartOfCharge"); - #endif - check = MyOperation->setValue("OurStartOfCharge",(char*)&tmpcdrptr->OurTimeForStartOfCharge); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - tmpcdrptr->USED_FIELDS |= B_TimeForStartOfCharge; - #ifdef SETDBG - puts("USED_FIELDS"); - #endif - check = MyOperation->setValue("USED_FIELDS",(char*)&tmpcdrptr->USED_FIELDS); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - break; - - case 2: - tmpcdrptr->OurTimeForStopOfCharge = ourtime; - #ifdef SETDBG - puts("OurStopOfCharge"); - #endif - check = MyOperation->setValue("OurStopOfCharge",(char*)&tmpcdrptr->OurTimeForStopOfCharge); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - tmpcdrptr->USED_FIELDS |= B_TimeForStopOfCharge; - #ifdef SETDBG - puts("USED_FIELDS"); - #endif - check = MyOperation->setValue("USED_FIELDS",(char*)&tmpcdrptr->USED_FIELDS); - if (check == -1) - error_handler(MyTransaction->getNdbErrorString()); - break; - - case 3: - tmpcdrptr->CallAttemptState = 4; - break; - default: - snprintf(msg,sizeof(msg),"cdrtype %d unknown",cdrsubtype); - if ((checkchangelog(log,lognamn))==0) - n2log(log,msg); - goto errout; - break; - } - ops++; - if (ops == ops_before_exe) { - ops = 0; - #ifdef SETDBG - puts("Going to execute"); - #endif - check = MyTransaction->execute(Commit, CommitAsMuchAsPossible); - if ((check == -1) && (MyTransaction->getNdbError() != 0)) - error_handler(MyTransaction->getNdbErrorString()); - MyNdb.closeTransaction(MyTransaction); - #ifdef SETDBG - puts("Transaction closed"); - #endif - - #ifdef SETDBG - puts("New transaction initiated"); - #endif - }//if - /* Increment the request count. */ - reqcnt++; - - /* Send a response back to the client. */ - - /* if (send(s, buf, 10, 0) != 10) goto errout; */ - } - - /* The loop has terminated, because there are no */ - /* more requests to be serviced. As mentioned above, */ - /* this close will block until all of the sent replies */ - /* have been received by the remote host. The reason */ - /* for lingering on the close is so that the server will */ - /* have a better idea of when the remote has picked up */ - /* all of the data. This will allow the start and finish */ - /* times printed in the log file to reflect more accurately */ - /* the length of time this connection was */ - /* The port number must be converted first to host byte */ - /* order before printing. On most hosts, this is not */ - /* necessary, but the ntohs() call is included here so */ - /* that this program could easily be ported to a host */ - /* that does require it. */ - - snprintf(msg,sizeof(msg),"Completed %s port %u, %d requests",hostname,ntohs(peeraddr_in.sin_port), reqcnt); - if ((checkchangelog(fi,temp))==0) - c2log(fi,msg); - error_from_client = 1; - snprintf(msg,sizeof(msg),"Communicate with threads"); - if ((checkchangelog(log,lognamn))==0) - n2log(log,msg); - snprintf(msg,sizeof(msg),"Waiting for threads to return from work"); - if ((checkchangelog(log,lognamn))==0) - n2log(log,msg); - snprintf(msg,sizeof(msg),"Closing down"); - if ((checkchangelog(log,lognamn))==0) - n2log(log,msg); - close(s); - fclose(log); - return EXIT_SUCCESS; - -errout: - snprintf(msg,sizeof(msg),"Connection with %s aborted on error\n", hostname); - if ((checkchangelog(log,lognamn))==0) - n2log(log,msg); - if ((checkchangelog(fi,temp))==0) - c2log(fi,msg); - error_from_client = 1; - snprintf(msg,sizeof(msg),"Communicate with threads"); - if ((checkchangelog(log,lognamn))==0) - n2log(log,msg); - snprintf(msg,sizeof(msg),"Waiting for threads to return from work"); - if ((checkchangelog(log,lognamn))==0) - n2log(log,msg); - snprintf(msg,sizeof(msg),"Closing down"); - if ((checkchangelog(log,lognamn))==0) - n2log(log,msg); - close(s); - fclose(log); - return EXIT_FAILURE; -} - -void -create_table(Ndb* pMyNdb) -{ - - /**************************************************************** - * Create table and attributes. - * - * create table basictab1( - * col1 int, - * col2 int not null, - * col3 int not null, - * col4 int not null - * ) - * - ***************************************************************/ - - int check; - int i; - NdbSchemaCon *MySchemaTransaction; - NdbSchemaOp *MySchemaOp; - int tAttributeSize; - - tAttributeSize = 1; - - cout << "Creating " << tableName << "..." << endl; - - MySchemaTransaction = pMyNdb->startSchemaTransaction(); - if( MySchemaTransaction == NULL ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - MySchemaOp = MySchemaTransaction->getNdbSchemaOp(); - if( MySchemaOp == NULL ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // Createtable - check = MySchemaOp->createTable( tableName, - 8, // Table Size - TupleKey, // Key Type - 40 // Nr of Pages - ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // CallIdentificationNumber Create first column, primary key - check = MySchemaOp->createAttribute( "CIN", - TupleKey, - 32, - tAttributeSize, - UnSigned, MMBased, - NotNullAttribute - ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - - // USED_FIELDS Create attributes - check = MySchemaOp->createAttribute( "USED_FIELDS", NoKey, 32, - tAttributeSize, UnSigned, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // ClientId Create attributes - check = MySchemaOp->createAttribute( "ClientId", NoKey, 32, - tAttributeSize, UnSigned, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // START_TIME Create attributes - check = MySchemaOp->createAttribute( "START_TIME", NoKey, 32, - tAttributeSize, UnSigned, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // OurSTART_TIME Create attributes - check = MySchemaOp->createAttribute( "OurSTART_TIME", NoKey, 32, - tAttributeSize, UnSigned, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // TimeForStartOfCharge Create attributes - check = MySchemaOp->createAttribute( "StartOfCharge", NoKey, 32, - tAttributeSize, UnSigned, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // TimeForStopOfCharge Create attributes - check = MySchemaOp->createAttribute( "StopOfCharge", NoKey, 32, - tAttributeSize, UnSigned, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // OurTimeForStartOfCharge Create attributes - check = MySchemaOp->createAttribute( "OurStartOfCharge", NoKey, 32, - tAttributeSize, UnSigned, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // OurTimeForStopOfCharge Create attributes - check = MySchemaOp->createAttribute( "OurStopOfCharge", NoKey, 32, - tAttributeSize, UnSigned, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // DestinationPointCode Create attributes - check = MySchemaOp->createAttribute( "DPC", NoKey, 16, - tAttributeSize, UnSigned, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // OriginatingPointCode Create attributes - check = MySchemaOp->createAttribute( "OPC", NoKey, 16, - tAttributeSize, UnSigned, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // CircuitIdentificationCode Create attributes - check = MySchemaOp->createAttribute( "CIC", NoKey, 16, - tAttributeSize, UnSigned, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // ReroutingIndicator Create attributes - check = MySchemaOp->createAttribute( "RI", NoKey, 16, - tAttributeSize, UnSigned, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // RINParameter Create attributes - check = MySchemaOp->createAttribute( "RINParameter", NoKey, 16, - tAttributeSize, UnSigned, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // NetworkIndicator Create attributes - check = MySchemaOp->createAttribute( "NIndicator", NoKey, 8, - tAttributeSize, Signed, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // CallAttemptState Create attributes - check = MySchemaOp->createAttribute( "CAS", NoKey, 8, - tAttributeSize, Signed, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // ACategory Create attributes - check = MySchemaOp->createAttribute( "ACategory", NoKey, 8, - tAttributeSize, Signed, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // EndOfSelectionInformation Create attributes - check = MySchemaOp->createAttribute( "EndOfSelInf", NoKey, 8, - tAttributeSize, Signed, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // UserToUserInformation Create attributes - check = MySchemaOp->createAttribute( "UserToUserInf", NoKey, 8, - tAttributeSize, Signed, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // UserToUserIndicator Create attributes - check = MySchemaOp->createAttribute( "UserToUserInd", NoKey, 8, - tAttributeSize, Signed, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // CauseCode Create attributes - check = MySchemaOp->createAttribute( "CauseCode", NoKey, 8, - tAttributeSize, Signed, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // ASubscriberNumber attributes - check = MySchemaOp->createAttribute( "ANumber", NoKey, 8, - ASubscriberNumber_SIZE, Signed, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // ASubscriberNumberLenght attributes - check = MySchemaOp->createAttribute( "ANumberLength", NoKey, 8, - tAttributeSize, Signed, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // TonASubscriberNumber attributes - check = MySchemaOp->createAttribute( "TonANumber", NoKey, 8, - tAttributeSize, Signed, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // BSubscriberNumber attributes - check = MySchemaOp->createAttribute( "BNumber", NoKey, 8, - BSubscriberNumber_SIZE, Signed, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // BSubscriberNumberLength attributes - check = MySchemaOp->createAttribute( "BNumberLength", NoKey, 8, - tAttributeSize, Signed, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // TonBSubscriberNumber attributes - check = MySchemaOp->createAttribute( "TonBNumber", NoKey, 8, - tAttributeSize, Signed, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // RedirectingNumber attributes - check = MySchemaOp->createAttribute( "RNumber", NoKey, 8, - ASubscriberNumber_SIZE, Signed, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // TonRedirectingNumber attributes - check = MySchemaOp->createAttribute( "TonRNumber", NoKey, 8, - tAttributeSize, Signed, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // OriginalCalledNumber attributes - check = MySchemaOp->createAttribute( "ONumber", NoKey, 8, - ASubscriberNumber_SIZE, Signed, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // TonOriginalCalledNumber attributes - check = MySchemaOp->createAttribute( "TonONumber", NoKey, 8, - tAttributeSize, Signed, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // LocationCode attributes - check = MySchemaOp->createAttribute( "LocationCode", NoKey, 8, - ASubscriberNumber_SIZE, Signed, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - // TonLocationCode attributes - check = MySchemaOp->createAttribute( "TonLocationCode", NoKey, 8, - tAttributeSize, Signed, MMBased, - NullAttribute ); - if( check == -1 ) - error_handler(MySchemaTransaction->getNdbErrorString()); - - if( MySchemaTransaction->execute() == -1 ) { - cout << tableName << " already exist" << endl; - cout << "Message: " << MySchemaTransaction->getNdbErrorString() << endl; - } - else - { - cout << tableName << " created" << endl; - } - pMyNdb->closeSchemaTransaction(MySchemaTransaction); - - return; -} - -void -error_handler(const char* errorText) -{ - // Test failed - cout << endl << "ErrorMessage: " << errorText << endl; - bTestPassed = -1; -} diff --git a/ndb/test/ndbapi/vw_test/script/client_start b/ndb/test/ndbapi/vw_test/script/client_start deleted file mode 100644 index 2965be6fbb5..00000000000 --- a/ndb/test/ndbapi/vw_test/script/client_start +++ /dev/null @@ -1,10 +0,0 @@ -# Argument to the client program is: -# 1. ip-adress to the server -# 2. location to the raw cdr-file -# 3. nanoseconds (0-1000) between writing the buffer to the port -# 4. how many writes to the buffer before the sleep command should accur -# Argument 3 and 4 controlls the flow of the raw cdr-file to the cdrserver - -cd $VCDRPATH/bin -# ./client stat181.xxx.com /ext06/data/indata_fraud1/port2file.data.-2089540139 1000 0 & -./client xxx.xxx.xxx.xxx.xxx /export2/home/ndb/vw/data/port2file_data_-2089540139 0 100000 & diff --git a/ndb/test/ndbapi/vw_test/size.cpp b/ndb/test/ndbapi/vw_test/size.cpp deleted file mode 100644 index c506771ebde..00000000000 --- a/ndb/test/ndbapi/vw_test/size.cpp +++ /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 */ - -#include -#include "utv.h" - -int main(void) -{ - printf("cdrstruct=%d\n",sizeof(struct cdr_record)); - printf("long int=%d\n",sizeof(long int)); - printf("int=%d\n",sizeof(int)); - printf("short int=%d\n",sizeof(short int)); - return 0; -} diff --git a/ndb/test/ndbapi/vw_test/utv.h b/ndb/test/ndbapi/vw_test/utv.h deleted file mode 100644 index 6f378e5595b..00000000000 --- a/ndb/test/ndbapi/vw_test/utv.h +++ /dev/null @@ -1,161 +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 */ - -#include -#include -#include - -#define TESTLEV - -#define ASubscriberNumber_SIZE 16 -#define BSubscriberNumber_SIZE 29 -#define TRUE 1 -#define FALSE 0 -#define WRITE_LIMIT 100000 -#define EVER ;; -#define CONNINFO "/" -#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) - -#define BIT_1 0x1 -#define BIT_2 0x2 -#define BIT_3 0x4 -#define BIT_4 0x8 -#define BIT_5 0x10 -#define BIT_6 0x20 -#define BIT_7 0x40 -#define BIT_8 0x80 - -/*------------------------------------------------------*/ -/* record defines structure over an alarm thresholds */ -/* CallAttemptState Beskriver status på samtal */ -/* 0 - Subscriber is calling */ -/* 1 - Called part answer call */ -/* 2 - Release of call */ -/* 3-255 reserved for furter use */ -/* USED_FILEDS Indicates active fields within call */ -/* bit 1 - START_TIME */ -/* 2 - TimeForStartOfCharge */ -/* 3 - TimeForStopOfCharge */ -/* 4 - ReroutingIndicator */ -/* 5 - RINParameter */ -/* 6 - ACategory */ -/* 7 - EndOfSelectionInformation */ -/* 8 - UserToUserIndicatior */ -/* 9 - UserToUserInformation */ -/* 10 - CauseCode */ -/* 11 - ASubscriberNumber */ -/* 12 - BSubscriberNumber */ -/* 13 - RedirectingNumber */ -/* 14 - OriginalCalledNumber */ -/* 15 - LocationCode */ -/* 16 - OriginatingPointCode */ -/* 17 - DestinationPointCode */ -/* 18 - CircuitIdentificationCode */ -/* 19 - NetworkIndicator */ -/*------------------------------------------------------*/ - -struct cdr_record -{ - unsigned int USED_FIELDS; - unsigned long ClientId; - unsigned int CallIdentificationNumber; - unsigned int START_TIME; - unsigned int OurSTART_TIME; - unsigned int TimeForStartOfCharge; - unsigned int TimeForStopOfCharge; - time_t OurTimeForStartOfCharge; - time_t OurTimeForStopOfCharge; - unsigned short DestinationPointCode; - unsigned short CircuitIdentificationCode; - unsigned short OriginatingPointCode; - unsigned short ReroutingIndicator; - unsigned short RINParameter; - char NetworkIndicator; - char CallAttemptState; - char ACategory; - char EndOfSelectionInformation; - char UserToUserInformation; - char UserToUserIndicatior; - char CauseCode; - char ASubscriberNumber[ASubscriberNumber_SIZE]; - char ASubscriberNumberLength; - char TonASubscriberNumber; - char BSubscriberNumber[BSubscriberNumber_SIZE]; - char BSubscriberNumberLength; - char TonBSubscriberNumber; - char RedirectingNumber[16]; - char TonRedirectingNumber; - char OriginalCalledNumber[16]; - char TonOriginalCalledNumber; - char LocationCode[16]; - char TonLocationCode; -}; - -/*------------------------------------------------------*/ -/* Define switches for each tag */ -/*------------------------------------------------------*/ - -#define B_START_TIME 0x1 -#define B_TimeForStartOfCharge 0x2 -#define B_TimeForStopOfCharge 0x4 -#define B_ReroutingIndicator 0x8 -#define B_RINParameter 0x10 -#define B_ACategory 0x20 -#define B_EndOfSelectionInformation 0x40 -#define B_UserToUserIndicatior 0x80 -#define B_UserToUserInformation 0x100 -#define B_CauseCode 0x200 -#define B_ASubscriberNumber 0x400 -#define B_BSubscriberNumber 0x800 -#define B_RedirectingNumber 0x1000 -#define B_OriginalCalledNumber 0x2000 -#define B_LocationCode 0x4000 -#define B_OriginatingPointCode 0x8000 -#define B_DestinationPointCode 0x10000 -#define B_CircuitIdentificationCode 0x20000 - -#define B_NetworkIndicator 0x40000 -#define B_TonASubscriberNumber 0x80000 -#define B_TonBSubscriberNumber 0x100000 -#define B_TonRedirectingNumber 0x200000 -#define B_TonOriginalCalledNumber 0x4000000 -#define B_TonLocationCode 0x8000000 - -#define K_START_TIME 0xFF01 -#define K_TimeForStartOfCharge 0xFF02 -#define K_TimeForStopOfCharge 0xFF03 -#define K_ReroutingIndicator 0x13 -#define K_RINParameter 0xFC -#define K_ACategory 0x09 -#define K_EndOfSelectionInformation 0x11 -#define K_UserToUserIndicatior 0x2A -#define K_UserToUserInformation 0x20 -#define K_CauseCode 0x12 -#define K_ASubscriberNumber 0x0A -#define K_BSubscriberNumber 0x04 -#define K_RedirectingNumber 0x0B -#define K_OriginalCalledNumber 0x28 -#define K_LocationCode 0x3F -#define K_OriginatingPointCode 0xFD -#define K_DestinationPointCode 0xFE -#define K_CircuitIdentificationCode 0xFF - -#define K_NetworkIndicator 0xF0 -#define K_TonASubscriberNumber 0xF1 -#define K_TonBSubscriberNumber 0xF2 -#define K_TonRedirectingNumber 0xF3 -#define K_TonOriginalCalledNumber 0xF4 -#define K_TonLocationCode 0xF5 diff --git a/ndb/test/ndbapi/vw_test/vcdrfunc.h b/ndb/test/ndbapi/vw_test/vcdrfunc.h deleted file mode 100644 index 3c5444d733b..00000000000 --- a/ndb/test/ndbapi/vw_test/vcdrfunc.h +++ /dev/null @@ -1,55 +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 */ - -/********************************************************/ -/* Common functions */ -/* unix_ps checks if a process is running with a */ -/* name and pid rc 0=not running */ -/* 1=Running */ -/* logname create a log filename */ -/* Parm */ -/* 1 lvl1 name */ -/* 2 lvl2 name */ -/* 3 lvl3 name */ -/* m2log Skriv log rader som moder */ -/* Parm */ -/* 1 pointer to filehandler */ -/* 2 Log text max 600 tecken */ -/* c2log Skriv log rader som barn */ -/* Parm */ -/* 1 pointer to filehandler */ -/* 2 Log text max 600 tecken */ -/* n2log Skriv log rader utan relation */ -/* Parm */ -/* 1 pointer to filehandler */ -/* 2 Log text max 600 tecken */ -/********************************************************/ - -int n2log(FILE *fi,char *text); -int m2log(FILE *fi,char *text); -int c2log(FILE *fi,char *text); -int checkchangelog(FILE* fp,char *filename); -void logname(char *filename, char *lvl1, char *lvl2, char *lvl3); -void logname_unique_day(char *filename, char *lvl1, char *lvl2, char *lvl3); -int unix_ps(char *proc_name,char *pid); -/* -int unix_ps2(char *proc_name,char *pid); -*/ -int unix_ps3(char *proc_name); -int replacetoken(const char* instring,char token,char replace); -int CompAsciiNum(char *, char *); -int CompareIt(char *,char *); -int CompCdrNum(const void *,const void *,void *); diff --git a/ndb/test/run-test/Makefile.am b/ndb/test/run-test/Makefile.am new file mode 100644 index 00000000000..7a7db16ceae --- /dev/null +++ b/ndb/test/run-test/Makefile.am @@ -0,0 +1,16 @@ + +bin_PROGRAMS = atrt + +atrt_SOURCES = main.cpp + +bin_SCRIPTS = atrt-analyze-result.sh atrt-gather-result.sh atrt-setup.sh \ + atrt-clear-result.sh make-config.sh + +INCLUDES_LOC = -I$(top_srcdir)/ndb/include/mgmapi -I$(top_srcdir)/ndb/src/mgmclient +LDADD_LOC = $(top_srcdir)/ndb/src/mgmapi/libmgmapi.la $(top_srcdir)/ndb/src/mgmclient/CpcClient.o + +include $(top_srcdir)/ndb/config/common.mk.am +include $(top_srcdir)/ndb/config/type_util.mk.am + +# Don't update the files from bitkeeper +%::SCCS/s.% diff --git a/ndb/test/tools/Makefile.am b/ndb/test/tools/Makefile.am new file mode 100644 index 00000000000..554a37821fd --- /dev/null +++ b/ndb/test/tools/Makefile.am @@ -0,0 +1,29 @@ + +bin_PROGRAMS = waiter hugoCalculator hugoLoad hugoFill hugoLockRecords hugoPkDelete hugoPkRead hugoPkReadRecord hugoPkUpdate hugoScanRead hugoScanUpdate restart verify_index copy_tab create_index + +# ndb_cpcc +# transproxy + +hugoCalculator_SOURCES = hugoCalculator.cpp +hugoFill_SOURCES = hugoFill.cpp +hugoLoad_SOURCES = hugoLoad.cpp +hugoLockRecords_SOURCES = hugoLockRecords.cpp +hugoPkDelete_SOURCES = hugoPkDelete.cpp +hugoPkRead_SOURCES = hugoPkRead.cpp +hugoPkReadRecord_SOURCES = hugoPkReadRecord.cpp +hugoPkUpdate_SOURCES = hugoPkUpdate.cpp +hugoScanRead_SOURCES = hugoScanRead.cpp +hugoScanUpdate_SOURCES = hugoScanUpdate.cpp +restart_SOURCES = restart.cpp +waiter_SOURCES = waiter.cpp +# transproxy_SOURCES = transproxy.cpp +verify_index_SOURCES = verify_index.cpp +copy_tab_SOURCES = copy_tab.cpp +create_index_SOURCES = create_index.cpp +#ndb_cpcc_SOURCES = cpcc.cpp + +include $(top_srcdir)/ndb/config/common.mk.am +include $(top_srcdir)/ndb/config/type_ndbapitest.mk.am + +# Don't update the files from bitkeeper +%::SCCS/s.% diff --git a/ndb/test/tools/copy_tab.cpp b/ndb/test/tools/copy_tab.cpp new file mode 100644 index 00000000000..33ce8e01d9a --- /dev/null +++ b/ndb/test/tools/copy_tab.cpp @@ -0,0 +1,99 @@ +/* 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 */ + +#include + +#include +#include +#include +#include "UtilTransactions.hpp" + +#include + +int main(int argc, const char** argv){ + + const char* _tabname = NULL; + const char* _to_tabname = NULL; + const char* _dbname = "TEST_DB"; + const char* _connectstr = NULL; + int _copy_data = true; + int _help = 0; + + struct getargs args[] = { + { "database", 'd', arg_string, &_dbname, "dbname", + "Name of database table is in"}, + { "connstr", 'c', arg_string, &_connectstr, "connect string", + "How to connect to NDB"}, + { "copy-data", '\0', arg_negative_flag, &_copy_data, "Don't copy data to new table", + "How to connect to NDB"}, + { "usage", '?', arg_flag, &_help, "Print help", "" } + }; + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + char desc[] = + "srctab desttab\n"\ + "This program will copy one table in Ndb\n"; + + if(getarg(args, num_args, argc, argv, &optind) || + argv[optind] == NULL || argv[optind + 1] == NULL || _help){ + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + _tabname = argv[optind]; + _to_tabname = argv[optind+1]; + + if (_connectstr) + Ndb::setConnectString(_connectstr); + Ndb MyNdb(_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; + + ndbout << "Copying table " << _tabname << " to " << _to_tabname << "..."; + const NdbDictionary::Table* ptab = MyNdb.getDictionary()->getTable(_tabname); + if (ptab){ + NdbDictionary::Table tab2(*ptab); + tab2.setName(_to_tabname); + if (MyNdb.getDictionary()->createTable(tab2) != 0){ + ndbout << endl << MyNdb.getDictionary()->getNdbError() << endl; + return NDBT_ProgramExit(NDBT_FAILED); + } + } else { + ndbout << endl << MyNdb.getDictionary()->getNdbError() << endl; + return NDBT_ProgramExit(NDBT_FAILED); + } + ndbout << "OK" << endl; + if (_copy_data){ + ndbout << "Copying data..."< +#include +#include "CpcClient.hpp" +#include + +#define DEFAULT_PORT 1234 +#define ENV_HOSTS "NDB_CPCC_HOSTS" + +struct settings { + int m_longl; + short m_port; +} g_settings = { 0 , DEFAULT_PORT }; + +Vector g_hosts; +int connect(Vector&); + +class Expression { +public: + virtual bool evaluate(SimpleCpcClient*, const SimpleCpcClient::Process &)= 0; +}; + +int for_each(Vector& list, Expression &); +int start_stop(const char * cmd, Vector& list, + Vector >& procs); + +class True : public Expression { +public: + virtual bool evaluate(SimpleCpcClient*, const SimpleCpcClient::Process & p){ + return true; + } +}; + +class FieldEQ : public Expression { + BaseString m_field; + BaseString m_value; +public: + FieldEQ(const BaseString & field, const BaseString & value){ + m_field = field; + m_value = value; + } + virtual ~FieldEQ(){} + + virtual bool evaluate(SimpleCpcClient*, const SimpleCpcClient::Process & p){ + BaseString v; + if(m_field == "name") v = p.m_name; + + if(m_field == "type") v = p.m_type; + if(m_field == "status") v = p.m_status; + if(m_field == "owner") v = p.m_owner; + if(m_field == "group") v = p.m_group; + if(m_field == "path") v = p.m_path; + if(m_field == "args") v = p.m_args; + if(m_field == "env") v = p.m_env; + if(m_field == "cwd") v = p.m_cwd; + + if(m_field == "stdin") v = p.m_stdin; + if(m_field == "stdout") v = p.m_stdout; + if(m_field == "stderr") v = p.m_stderr; + + return v == m_value; + } +}; + +class Match : public Expression { + Expression & m_cond; + Expression & m_apply; +public: + Match(Expression& condition, Expression & rule) + : m_cond(condition), m_apply(rule) { + } + virtual ~Match(){} + + virtual bool evaluate(SimpleCpcClient* c,const SimpleCpcClient::Process & p){ + if(m_cond.evaluate(c, p)) + return m_apply.evaluate(c, p); + return false; + } +}; + +class Operate : public Expression { + const char * cmd; + SimpleCpcClient * host; + settings & sets; +public: + Operate(const char * c, settings & s) : sets(s) { + cmd = c; + host = 0; + } + + virtual bool evaluate(SimpleCpcClient*, const SimpleCpcClient::Process & p); +}; + +class ProcEQ : public Expression { + SimpleCpcClient * host; + Uint32 id; +public: + ProcEQ(SimpleCpcClient* h, Uint32 i){ + host = h; id = i; + } + + virtual bool evaluate(SimpleCpcClient* c,const SimpleCpcClient::Process & p){ + return p.m_id == (int)id && c == host; + } +}; + +class OrExpr : public Expression { + Expression * m_rule; + Vector m_cond; + bool on_empty; +public: + OrExpr(Expression * rule, bool onEmp = true){ + m_rule = rule; + on_empty = onEmp; + } + + virtual ~OrExpr(){} + + virtual bool evaluate(SimpleCpcClient* c, const SimpleCpcClient::Process & p){ + bool run = on_empty; + for(size_t i = 0; ievaluate(c, p)){ + run = true; + break; + } + } + if(run) + return m_rule->evaluate(c, p); + return false; + } + + void push_back(Expression * expr){ + m_cond.push_back(expr); + } +}; + +void +add_host(Vector & hosts, BaseString tmp){ + Vector split; + tmp.split(split, ":"); + + short port = g_settings.m_port; + if(split.size() > 1) + port = atoi(split[1].c_str()); + + hosts.push_back(new SimpleCpcClient(split[0].c_str(), port)); +} + +void +add_hosts(Vector & hosts, BaseString list){ + Vector split; + list.split(split); + for(size_t i = 0; i 1){ + ndbout_c("Can only specify one command"); + arg_printusage(args, num_args, argv[0], desc); + return 1; + } + + if(list) cmd = "list"; + if(start) cmd = "start"; + if(stop) cmd = "stop"; + if(rm) cmd = "rm"; + if(!cmd) cmd = "list"; + + Expression * m_expr = 0; + + for(int i = optind; i split; + tmp.split(split, ":"); + + if(split.size() > 2){ + Uint32 id = atoi(split[2].c_str()); + orE->push_back(new ProcEQ(g_hosts[i-optind], id)); + } + } + + if(g_hosts.size() == 0){ + char buf[1024]; + if(NdbEnv_GetEnv(ENV_HOSTS, buf, sizeof(buf))){ + add_hosts(g_hosts, BaseString(buf)); + } + } + + if(g_hosts.size() == 0){ + g_hosts.push_back(new SimpleCpcClient("localhost", g_settings.m_port)); + } + + if(group != 0){ + Expression * tmp = new FieldEQ("group", group); + m_expr = new Match(* tmp, * m_expr); + } + + if(name != 0){ + Expression * tmp = new FieldEQ("name", name); + m_expr = new Match(* tmp, * m_expr); + } + + if(owner != 0){ + Expression * tmp = new FieldEQ("owner", owner); + m_expr = new Match(* tmp, * m_expr); + } + + connect(g_hosts); + for_each(g_hosts, * m_expr); + + return 0; +} + +int +connect(Vector& list){ + for(size_t i = 0; iconnect() != 0){ + ndbout_c("Failed to connect to %s:%d", + list[i]->getHost(), list[i]->getPort()); + delete list[i]; list[i] = 0; + } + } + return 0; +} + +int +for_each(Vector& list, Expression & expr){ + for(size_t i = 0; i procs; + if(list[i]->list_processes(procs, p) != 0){ + ndbout << "Failed to list processes on " + << list[i]->getHost() << ":" << list[i]->getPort() << endl; + } + for(size_t j = 0; jstart_process(id, p); + else if(strcasecmp(cmd, "stop") == 0) + res = c->stop_process(id, p); + else if(strcasecmp(cmd, "rm") == 0) + res = c->undefine_process(id, p); + else if(strcasecmp(cmd, "list") == 0){ + if(!sets.m_longl){ + if(host != c){ + ndbout_c("--- %s:%d", c->getHost(), c->getPort()); + host = c; + } + } + + char s = 0; + const char * status = pp.m_status.c_str(); + if(strcmp(status, "stopped") == 0) s = '-'; + if(strcmp(status, "starting") == 0) s = 's'; + if(strcmp(status, "running") == 0) s = 'r'; + if(strcmp(status, "stopping") == 0) s = 'k'; + if(s == 0) s = '?'; + + if(!sets.m_longl){ + ndbout_c("%c%c\t%d\t%s\t%s\t%s(%s)", + s, + pp.m_type.c_str()[0], id, pp.m_owner.c_str(), + pp.m_group.c_str(), pp.m_name.c_str(), pp.m_path.c_str()); + } else { + ndbout_c("%c%c %s:%d:%d %s %s %s(%s)", + s, pp.m_type.c_str()[0], c->getHost(), c->getPort(), + id, pp.m_owner.c_str(), pp.m_group.c_str(), + pp.m_name.c_str(), pp.m_path.c_str()); + } + return true; + } + + if(res != 0){ + BaseString msg; + p.get("errormessage", msg); + ndbout_c("Failed to %s %d on %s:%d - %s", + cmd, id, + c->getHost(), c->getPort(), msg.c_str()); + return false; + } + + return true; +} + diff --git a/ndb/test/tools/create_index.cpp b/ndb/test/tools/create_index.cpp new file mode 100644 index 00000000000..dc9e6c606d6 --- /dev/null +++ b/ndb/test/tools/create_index.cpp @@ -0,0 +1,95 @@ +/* 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 */ + +#include + +#include +#include +#include + +#include + + + +int +main(int argc, const char** argv){ + + const char* _dbname = "TEST_DB"; + int _help = 0; + + struct getargs args[] = { + { "database", 'd', arg_string, &_dbname, "dbname", + "Name of database table is in"}, + { "usage", '?', arg_flag, &_help, "Print help", "" } + }; + + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + char desc[] = + "+\n"\ + "This program will create one unique hash index named ind_ " + " for each table. The index will contain all columns in the table"; + + if(getarg(args, num_args, argc, argv, &optind) || _help || + argv[optind] == NULL){ + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + + + Ndb MyNdb(_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; + + NdbDictionary::Dictionary * dict = MyNdb.getDictionary(); + + for(int i = optind; igetTable(argv[i]); + if(tab == 0){ + g_err << "Unknown table: " << argv[i] << endl; + continue; + } + + if(tab->getNoOfColumns() > 16){ + g_err << "Table " << argv[i] << " has more than 16 columns" << endl; + } + + NdbDictionary::Index ind; + char buf[512]; + sprintf(buf, "IND_%s", argv[i]); + ind.setName(buf); + ind.setTable(argv[i]); + ind.setType(NdbDictionary::Index::UniqueHashIndex); + for(int c = 0; cgetNoOfColumns(); c++) + ind.addIndexColumn(tab->getColumn(c)->getName()); + + ndbout << "creating index " << buf << " on table " << argv[i] << "..."; + const int res = dict->createIndex(ind); + if(res != 0) + ndbout << endl << dict->getNdbError() << endl; + else + ndbout << "OK" << endl; + } + + return NDBT_ProgramExit(NDBT_OK); +} + + diff --git a/ndb/test/tools/hugoCalculator.cpp b/ndb/test/tools/hugoCalculator.cpp new file mode 100644 index 00000000000..7f2751be2ba --- /dev/null +++ b/ndb/test/tools/hugoCalculator.cpp @@ -0,0 +1,70 @@ +/* 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 */ + + +#include + +#include +#include +#include +#include +#include +#include + +//extern NdbOut g_info; + +int main(int argc, const char** argv) +{ + int _row = 0; + int _column = 0; + int _updates = 0; + const char* _tableName = NULL; + + struct getargs args[] = { + { "row", 'r', arg_integer, &_row, "The row number", "row" }, + { "column", 'c', arg_integer, &_column, "The column id", "column" }, + { "updates", 'u', arg_integer, &_updates, "# of updates", "updates" } + }; + + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + + if(getarg(args, num_args, argc, argv, &optind) || argv[optind] == NULL) { + arg_printusage(args, num_args, argv[0], "table name\n"); + return NDBT_WRONGARGS; + } + // Check if table name is supplied + if (argv[optind] != NULL) + _tableName = argv[optind]; + + + const NdbDictionary::Table* table = NDBT_Tables::getTable(_tableName); + const NdbDictionary::Column * attribute = table->getColumn(_column); + + g_info << "Table " << _tableName << endl + << "Row: " << _row << ", " + << "Column(" << attribute->getName() << ")" + << "[" << attribute->getType() << "]" + << ", Updates: " << _updates + << endl; + + HugoCalculator calc(*table); + char buf[8000]; + g_info << "Value: " << calc.calcValue(_row, _column, _updates, buf) + << endl; + + return 0; +} diff --git a/ndb/test/tools/hugoCalculator/Makefile b/ndb/test/tools/hugoCalculator/Makefile deleted file mode 100644 index a29deeaacd3..00000000000 --- a/ndb/test/tools/hugoCalculator/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := hugoCalculator - -# Source files of non-templated classes (.C files) -SOURCES = hugoCalculator.cpp - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/test/tools/hugoCalculator/hugoCalculator.cpp b/ndb/test/tools/hugoCalculator/hugoCalculator.cpp deleted file mode 100644 index 7f2751be2ba..00000000000 --- a/ndb/test/tools/hugoCalculator/hugoCalculator.cpp +++ /dev/null @@ -1,70 +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 */ - - -#include - -#include -#include -#include -#include -#include -#include - -//extern NdbOut g_info; - -int main(int argc, const char** argv) -{ - int _row = 0; - int _column = 0; - int _updates = 0; - const char* _tableName = NULL; - - struct getargs args[] = { - { "row", 'r', arg_integer, &_row, "The row number", "row" }, - { "column", 'c', arg_integer, &_column, "The column id", "column" }, - { "updates", 'u', arg_integer, &_updates, "# of updates", "updates" } - }; - - int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; - - if(getarg(args, num_args, argc, argv, &optind) || argv[optind] == NULL) { - arg_printusage(args, num_args, argv[0], "table name\n"); - return NDBT_WRONGARGS; - } - // Check if table name is supplied - if (argv[optind] != NULL) - _tableName = argv[optind]; - - - const NdbDictionary::Table* table = NDBT_Tables::getTable(_tableName); - const NdbDictionary::Column * attribute = table->getColumn(_column); - - g_info << "Table " << _tableName << endl - << "Row: " << _row << ", " - << "Column(" << attribute->getName() << ")" - << "[" << attribute->getType() << "]" - << ", Updates: " << _updates - << endl; - - HugoCalculator calc(*table); - char buf[8000]; - g_info << "Value: " << calc.calcValue(_row, _column, _updates, buf) - << endl; - - return 0; -} diff --git a/ndb/test/tools/hugoFill.cpp b/ndb/test/tools/hugoFill.cpp new file mode 100644 index 00000000000..dee6ce2e6c8 --- /dev/null +++ b/ndb/test/tools/hugoFill.cpp @@ -0,0 +1,78 @@ +/* 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 */ + +#include + +#include +#include +#include +#include +#include +#include + + +int main(int argc, const char** argv){ + + int _records = 0; + const char* _tabname = NULL; + int _help = 0; + int _batch = 512; + + struct getargs args[] = { + { "batch", 'b', arg_integer, &_batch, "Number of operations in each transaction", "batch" }, + { "usage", '?', arg_flag, &_help, "Print help", "" } + }; + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + char desc[] = + "tabname\n"\ + "This program will load one table in Ndb with calculated data \n"\ + "until the database is full. \n"; + + if(getarg(args, num_args, argc, argv, &optind) || + argv[optind] == NULL || _help) { + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + _tabname = argv[optind]; + + // Connect to Ndb + Ndb MyNdb( "TEST_DB" ); + + if(MyNdb.init() != 0){ + ERR(MyNdb.getNdbError()); + return NDBT_ProgramExit(NDBT_FAILED); + } + + // Connect to Ndb and wait for it to become ready + while(MyNdb.waitUntilReady() != 0) + ndbout << "Waiting for ndb to become ready..." << endl; + + // Check if table exists in db + const NdbDictionary::Table* pTab = NDBT_Table::discoverTableFromDb(&MyNdb, _tabname); + if(pTab == NULL){ + ndbout << " Table " << _tabname << " does not exist!" << endl; + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + + HugoTransactions hugoTrans(*pTab); + if (hugoTrans.fillTable(&MyNdb, + _batch) != 0){ + return NDBT_ProgramExit(NDBT_FAILED); + } + + return NDBT_ProgramExit(NDBT_OK); +} diff --git a/ndb/test/tools/hugoFill/Makefile b/ndb/test/tools/hugoFill/Makefile deleted file mode 100644 index 3da745810b6..00000000000 --- a/ndb/test/tools/hugoFill/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := hugoFill - -# Source files of non-templated classes (.C files) -SOURCES = hugoFill.cpp - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/test/tools/hugoFill/hugoFill.cpp b/ndb/test/tools/hugoFill/hugoFill.cpp deleted file mode 100644 index dee6ce2e6c8..00000000000 --- a/ndb/test/tools/hugoFill/hugoFill.cpp +++ /dev/null @@ -1,78 +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 */ - -#include - -#include -#include -#include -#include -#include -#include - - -int main(int argc, const char** argv){ - - int _records = 0; - const char* _tabname = NULL; - int _help = 0; - int _batch = 512; - - struct getargs args[] = { - { "batch", 'b', arg_integer, &_batch, "Number of operations in each transaction", "batch" }, - { "usage", '?', arg_flag, &_help, "Print help", "" } - }; - int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; - char desc[] = - "tabname\n"\ - "This program will load one table in Ndb with calculated data \n"\ - "until the database is full. \n"; - - if(getarg(args, num_args, argc, argv, &optind) || - argv[optind] == NULL || _help) { - arg_printusage(args, num_args, argv[0], desc); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - _tabname = argv[optind]; - - // Connect to Ndb - Ndb MyNdb( "TEST_DB" ); - - if(MyNdb.init() != 0){ - ERR(MyNdb.getNdbError()); - return NDBT_ProgramExit(NDBT_FAILED); - } - - // Connect to Ndb and wait for it to become ready - while(MyNdb.waitUntilReady() != 0) - ndbout << "Waiting for ndb to become ready..." << endl; - - // Check if table exists in db - const NdbDictionary::Table* pTab = NDBT_Table::discoverTableFromDb(&MyNdb, _tabname); - if(pTab == NULL){ - ndbout << " Table " << _tabname << " does not exist!" << endl; - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - - HugoTransactions hugoTrans(*pTab); - if (hugoTrans.fillTable(&MyNdb, - _batch) != 0){ - return NDBT_ProgramExit(NDBT_FAILED); - } - - return NDBT_ProgramExit(NDBT_OK); -} diff --git a/ndb/test/tools/hugoLoad.cpp b/ndb/test/tools/hugoLoad.cpp new file mode 100644 index 00000000000..be7f878d106 --- /dev/null +++ b/ndb/test/tools/hugoLoad.cpp @@ -0,0 +1,82 @@ +/* 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 */ + + +#include +#include +#include +#include +#include +#include + + +int main(int argc, const char** argv){ + + int _records = 0; + const char* _tabname = NULL; + int _help = 0; + int _batch = 512; + + struct getargs args[] = { + { "records", 'r', arg_integer, &_records, "Number of records", "recs" }, + { "batch", 'b', arg_integer, &_batch, "Number of operations in each transaction", "batch" }, + { "usage", '?', arg_flag, &_help, "Print help", "" } + }; + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + char desc[] = + "tabname\n"\ + "This program will load one table in Ndb with calculated data. \n"\ + "This means that it is possible to check the validity of the data \n"\ + "at a later time. The last column in each table is used as an update \n"\ + "counter, it's initialised to zero and should be incremented for each \n"\ + "update of the record. \n"; + + if(getarg(args, num_args, argc, argv, &optind) || + argv[optind] == NULL || _records == 0 || _help) { + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + _tabname = argv[optind]; + + // Connect to Ndb + Ndb MyNdb( "TEST_DB" ); + + if(MyNdb.init() != 0){ + ERR(MyNdb.getNdbError()); + return NDBT_ProgramExit(NDBT_FAILED); + } + + // Connect to Ndb and wait for it to become ready + while(MyNdb.waitUntilReady() != 0) + ndbout << "Waiting for ndb to become ready..." << endl; + + // Check if table exists in db + const NdbDictionary::Table* pTab = NDBT_Table::discoverTableFromDb(&MyNdb, _tabname); + if(pTab == NULL){ + ndbout << " Table " << _tabname << " does not exist!" << endl; + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + + HugoTransactions hugoTrans(*pTab); + if (hugoTrans.loadTable(&MyNdb, + _records, + _batch) != 0){ + return NDBT_ProgramExit(NDBT_FAILED); + } + + return NDBT_ProgramExit(NDBT_OK); +} diff --git a/ndb/test/tools/hugoLoad/Makefile b/ndb/test/tools/hugoLoad/Makefile deleted file mode 100644 index 7c5756d0d41..00000000000 --- a/ndb/test/tools/hugoLoad/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := hugoLoad - -# Source files of non-templated classes (.C files) -SOURCES = hugoLoad.cpp - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/test/tools/hugoLoad/hugoLoad.cpp b/ndb/test/tools/hugoLoad/hugoLoad.cpp deleted file mode 100644 index be7f878d106..00000000000 --- a/ndb/test/tools/hugoLoad/hugoLoad.cpp +++ /dev/null @@ -1,82 +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 */ - - -#include -#include -#include -#include -#include -#include - - -int main(int argc, const char** argv){ - - int _records = 0; - const char* _tabname = NULL; - int _help = 0; - int _batch = 512; - - struct getargs args[] = { - { "records", 'r', arg_integer, &_records, "Number of records", "recs" }, - { "batch", 'b', arg_integer, &_batch, "Number of operations in each transaction", "batch" }, - { "usage", '?', arg_flag, &_help, "Print help", "" } - }; - int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; - char desc[] = - "tabname\n"\ - "This program will load one table in Ndb with calculated data. \n"\ - "This means that it is possible to check the validity of the data \n"\ - "at a later time. The last column in each table is used as an update \n"\ - "counter, it's initialised to zero and should be incremented for each \n"\ - "update of the record. \n"; - - if(getarg(args, num_args, argc, argv, &optind) || - argv[optind] == NULL || _records == 0 || _help) { - arg_printusage(args, num_args, argv[0], desc); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - _tabname = argv[optind]; - - // Connect to Ndb - Ndb MyNdb( "TEST_DB" ); - - if(MyNdb.init() != 0){ - ERR(MyNdb.getNdbError()); - return NDBT_ProgramExit(NDBT_FAILED); - } - - // Connect to Ndb and wait for it to become ready - while(MyNdb.waitUntilReady() != 0) - ndbout << "Waiting for ndb to become ready..." << endl; - - // Check if table exists in db - const NdbDictionary::Table* pTab = NDBT_Table::discoverTableFromDb(&MyNdb, _tabname); - if(pTab == NULL){ - ndbout << " Table " << _tabname << " does not exist!" << endl; - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - - HugoTransactions hugoTrans(*pTab); - if (hugoTrans.loadTable(&MyNdb, - _records, - _batch) != 0){ - return NDBT_ProgramExit(NDBT_FAILED); - } - - return NDBT_ProgramExit(NDBT_OK); -} diff --git a/ndb/test/tools/hugoLockRecords.cpp b/ndb/test/tools/hugoLockRecords.cpp new file mode 100644 index 00000000000..e2c2cd13f00 --- /dev/null +++ b/ndb/test/tools/hugoLockRecords.cpp @@ -0,0 +1,90 @@ +/* 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 */ + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +int main(int argc, const char** argv){ + + int _records = 0; + int _loops = 1; + int _percentVal = 1; + int _lockTime = 1000; + const char* _tabname = NULL; + int _help = 0; + + struct getargs args[] = { + { "loops", 'l', arg_integer, &_loops, "number of times to run this program(0=infinite loop)", "loops" }, + { "records", 'r', arg_integer, &_records, "Number of records", "recs" }, + { "locktime", 't', arg_integer, &_lockTime, "Time in ms to hold lock(default=1000)", "ms" }, + { "percent", 'p', arg_integer, &_percentVal, "Percent of records to lock(default=1%)", "%" }, + { "usage", '?', arg_flag, &_help, "Print help", "" } + }; + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + char desc[] = + "tabname\n"\ + "This program will lock p% of the records in the table for x milliseconds\n"\ + "then it will lock the next 1% and continue to do so until it has locked \n"\ + "all records in the table\n"; + + if(getarg(args, num_args, argc, argv, &optind) || + argv[optind] == NULL || _records == 0 || _help) { + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + _tabname = argv[optind]; + + // Connect to Ndb + Ndb MyNdb( "TEST_DB" ); + + if(MyNdb.init() != 0){ + ERR(MyNdb.getNdbError()); + return NDBT_ProgramExit(NDBT_FAILED); + } + + 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); + if(pTab == NULL){ + ndbout << " Table " << _tabname << " does not exist!" << endl; + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + + HugoTransactions hugoTrans(*pTab); + int i = 0; + while (i<_loops || _loops==0) { + ndbout << i << ": "; + if (hugoTrans.lockRecords(&MyNdb, _records, _percentVal, _lockTime) != 0){ + return NDBT_ProgramExit(NDBT_FAILED); + } + i++; + } + + return NDBT_ProgramExit(NDBT_OK); +} + diff --git a/ndb/test/tools/hugoLockRecords/Makefile b/ndb/test/tools/hugoLockRecords/Makefile deleted file mode 100644 index 3235750cbf8..00000000000 --- a/ndb/test/tools/hugoLockRecords/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := hugoLockRecords - -SOURCES := hugoLockRecords.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/tools/hugoLockRecords/hugoLockRecords.cpp b/ndb/test/tools/hugoLockRecords/hugoLockRecords.cpp deleted file mode 100644 index e2c2cd13f00..00000000000 --- a/ndb/test/tools/hugoLockRecords/hugoLockRecords.cpp +++ /dev/null @@ -1,90 +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 */ - -#include - -#include - -#include -#include -#include -#include -#include - -#include - -int main(int argc, const char** argv){ - - int _records = 0; - int _loops = 1; - int _percentVal = 1; - int _lockTime = 1000; - const char* _tabname = NULL; - int _help = 0; - - struct getargs args[] = { - { "loops", 'l', arg_integer, &_loops, "number of times to run this program(0=infinite loop)", "loops" }, - { "records", 'r', arg_integer, &_records, "Number of records", "recs" }, - { "locktime", 't', arg_integer, &_lockTime, "Time in ms to hold lock(default=1000)", "ms" }, - { "percent", 'p', arg_integer, &_percentVal, "Percent of records to lock(default=1%)", "%" }, - { "usage", '?', arg_flag, &_help, "Print help", "" } - }; - int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; - char desc[] = - "tabname\n"\ - "This program will lock p% of the records in the table for x milliseconds\n"\ - "then it will lock the next 1% and continue to do so until it has locked \n"\ - "all records in the table\n"; - - if(getarg(args, num_args, argc, argv, &optind) || - argv[optind] == NULL || _records == 0 || _help) { - arg_printusage(args, num_args, argv[0], desc); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - _tabname = argv[optind]; - - // Connect to Ndb - Ndb MyNdb( "TEST_DB" ); - - if(MyNdb.init() != 0){ - ERR(MyNdb.getNdbError()); - return NDBT_ProgramExit(NDBT_FAILED); - } - - 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); - if(pTab == NULL){ - ndbout << " Table " << _tabname << " does not exist!" << endl; - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - - HugoTransactions hugoTrans(*pTab); - int i = 0; - while (i<_loops || _loops==0) { - ndbout << i << ": "; - if (hugoTrans.lockRecords(&MyNdb, _records, _percentVal, _lockTime) != 0){ - return NDBT_ProgramExit(NDBT_FAILED); - } - i++; - } - - return NDBT_ProgramExit(NDBT_OK); -} - diff --git a/ndb/test/tools/hugoPkDelete.cpp b/ndb/test/tools/hugoPkDelete.cpp new file mode 100644 index 00000000000..1855f19796f --- /dev/null +++ b/ndb/test/tools/hugoPkDelete.cpp @@ -0,0 +1,86 @@ +/* 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 */ + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +int main(int argc, const char** argv){ + + int _records = 0; + int _loops = 1; + int _batch = 0; + const char* _tabname = NULL; + int _help = 0; + + struct getargs args[] = { + { "loops", 'l', arg_integer, &_loops, "number of times to run this program(0=infinite loop)", "loops" }, + // { "batch", 'b', arg_integer, &_batch, "batch value", "batch" }, + { "records", 'r', arg_integer, &_records, "Number of records", "records" }, + { "usage", '?', arg_flag, &_help, "Print help", "" } + }; + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + char desc[] = + "tabname\n"\ + "This program will delete all records in a table using PK \n"; + + if(getarg(args, num_args, argc, argv, &optind) || + argv[optind] == NULL || _records == 0 || _help) { + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + _tabname = argv[optind]; + + // Connect to Ndb + Ndb MyNdb( "TEST_DB" ); + + if(MyNdb.init() != 0){ + ERR(MyNdb.getNdbError()); + return NDBT_ProgramExit(NDBT_FAILED); + } + + 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); + if(pTab == NULL){ + ndbout << " Table " << _tabname << " does not exist!" << endl; + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + + HugoTransactions hugoTrans(*pTab); + int i = 0; + while (i<_loops || _loops==0) { + ndbout << i << ": "; + if (hugoTrans.pkDelRecords(&MyNdb, _records) != 0){ + return NDBT_ProgramExit(NDBT_FAILED); + } + i++; + } + + return NDBT_ProgramExit(NDBT_OK); +} + diff --git a/ndb/test/tools/hugoPkDelete/Makefile b/ndb/test/tools/hugoPkDelete/Makefile deleted file mode 100644 index e6d53611c54..00000000000 --- a/ndb/test/tools/hugoPkDelete/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := hugoPkDelete - -SOURCES := hugoPkDel.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/tools/hugoPkDelete/hugoPkDel.cpp b/ndb/test/tools/hugoPkDelete/hugoPkDel.cpp deleted file mode 100644 index 1855f19796f..00000000000 --- a/ndb/test/tools/hugoPkDelete/hugoPkDel.cpp +++ /dev/null @@ -1,86 +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 */ - -#include - -#include - -#include -#include -#include -#include -#include - -#include - -int main(int argc, const char** argv){ - - int _records = 0; - int _loops = 1; - int _batch = 0; - const char* _tabname = NULL; - int _help = 0; - - struct getargs args[] = { - { "loops", 'l', arg_integer, &_loops, "number of times to run this program(0=infinite loop)", "loops" }, - // { "batch", 'b', arg_integer, &_batch, "batch value", "batch" }, - { "records", 'r', arg_integer, &_records, "Number of records", "records" }, - { "usage", '?', arg_flag, &_help, "Print help", "" } - }; - int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; - char desc[] = - "tabname\n"\ - "This program will delete all records in a table using PK \n"; - - if(getarg(args, num_args, argc, argv, &optind) || - argv[optind] == NULL || _records == 0 || _help) { - arg_printusage(args, num_args, argv[0], desc); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - _tabname = argv[optind]; - - // Connect to Ndb - Ndb MyNdb( "TEST_DB" ); - - if(MyNdb.init() != 0){ - ERR(MyNdb.getNdbError()); - return NDBT_ProgramExit(NDBT_FAILED); - } - - 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); - if(pTab == NULL){ - ndbout << " Table " << _tabname << " does not exist!" << endl; - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - - HugoTransactions hugoTrans(*pTab); - int i = 0; - while (i<_loops || _loops==0) { - ndbout << i << ": "; - if (hugoTrans.pkDelRecords(&MyNdb, _records) != 0){ - return NDBT_ProgramExit(NDBT_FAILED); - } - i++; - } - - return NDBT_ProgramExit(NDBT_OK); -} - diff --git a/ndb/test/tools/hugoPkRead.cpp b/ndb/test/tools/hugoPkRead.cpp new file mode 100644 index 00000000000..50351f08195 --- /dev/null +++ b/ndb/test/tools/hugoPkRead.cpp @@ -0,0 +1,91 @@ +/* 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 */ + +#include + +#include + +#include +#include +#include +#include +#include + +#include + + +int main(int argc, const char** argv){ + + int _records = 0; + int _loops = 1; + int _abort = 0; + int _batch = 1; + const char* _tabname = NULL; + int _help = 0; + + struct getargs args[] = { + { "aborts", 'a', arg_integer, &_abort, "percent of transactions that are aborted", "abort%" }, + { "loops", 'l', arg_integer, &_loops, "number of times to run this program(0=infinite loop)", "loops" }, + { "batch", 'b', arg_integer, &_batch, "batch value(not 0)", "batch" }, + { "records", 'r', arg_integer, &_records, "Number of records", "records" }, + { "usage", '?', arg_flag, &_help, "Print help", "" } + }; + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + char desc[] = + "tabname\n"\ + "This program will read 'r' records from one table in Ndb. \n"\ + "It will verify every column read by calculating the expected value.\n"; + + if(getarg(args, num_args, argc, argv, &optind) || + argv[optind] == NULL || _records == 0 || _batch == 0 || _help) { + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + _tabname = argv[optind]; + + + // Connect to Ndb + Ndb MyNdb( "TEST_DB" ); + + if(MyNdb.init() != 0){ + ERR(MyNdb.getNdbError()); + return NDBT_ProgramExit(NDBT_FAILED); + } + + 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); + if(pTab == NULL){ + ndbout << " Table " << _tabname << " does not exist!" << endl; + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + + HugoTransactions hugoTrans(*pTab); + int i = 0; + while (i<_loops || _loops==0) { + ndbout << i << ": "; + if (hugoTrans.pkReadRecords(&MyNdb, _records, _batch) != 0){ + return NDBT_ProgramExit(NDBT_FAILED); + } + i++; + } + + return NDBT_ProgramExit(NDBT_OK); +} + diff --git a/ndb/test/tools/hugoPkRead/Makefile b/ndb/test/tools/hugoPkRead/Makefile deleted file mode 100644 index 03580dc0d18..00000000000 --- a/ndb/test/tools/hugoPkRead/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := hugoPkRead - -SOURCES := hugoPkRead.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/tools/hugoPkRead/hugoPkRead.cpp b/ndb/test/tools/hugoPkRead/hugoPkRead.cpp deleted file mode 100644 index 50351f08195..00000000000 --- a/ndb/test/tools/hugoPkRead/hugoPkRead.cpp +++ /dev/null @@ -1,91 +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 */ - -#include - -#include - -#include -#include -#include -#include -#include - -#include - - -int main(int argc, const char** argv){ - - int _records = 0; - int _loops = 1; - int _abort = 0; - int _batch = 1; - const char* _tabname = NULL; - int _help = 0; - - struct getargs args[] = { - { "aborts", 'a', arg_integer, &_abort, "percent of transactions that are aborted", "abort%" }, - { "loops", 'l', arg_integer, &_loops, "number of times to run this program(0=infinite loop)", "loops" }, - { "batch", 'b', arg_integer, &_batch, "batch value(not 0)", "batch" }, - { "records", 'r', arg_integer, &_records, "Number of records", "records" }, - { "usage", '?', arg_flag, &_help, "Print help", "" } - }; - int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; - char desc[] = - "tabname\n"\ - "This program will read 'r' records from one table in Ndb. \n"\ - "It will verify every column read by calculating the expected value.\n"; - - if(getarg(args, num_args, argc, argv, &optind) || - argv[optind] == NULL || _records == 0 || _batch == 0 || _help) { - arg_printusage(args, num_args, argv[0], desc); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - _tabname = argv[optind]; - - - // Connect to Ndb - Ndb MyNdb( "TEST_DB" ); - - if(MyNdb.init() != 0){ - ERR(MyNdb.getNdbError()); - return NDBT_ProgramExit(NDBT_FAILED); - } - - 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); - if(pTab == NULL){ - ndbout << " Table " << _tabname << " does not exist!" << endl; - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - - HugoTransactions hugoTrans(*pTab); - int i = 0; - while (i<_loops || _loops==0) { - ndbout << i << ": "; - if (hugoTrans.pkReadRecords(&MyNdb, _records, _batch) != 0){ - return NDBT_ProgramExit(NDBT_FAILED); - } - i++; - } - - return NDBT_ProgramExit(NDBT_OK); -} - diff --git a/ndb/test/tools/hugoPkReadRecord.cpp b/ndb/test/tools/hugoPkReadRecord.cpp new file mode 100644 index 00000000000..ac17ffffee8 --- /dev/null +++ b/ndb/test/tools/hugoPkReadRecord.cpp @@ -0,0 +1,194 @@ +/* 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 */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +//extern NdbOut g_info; + +int main(int argc, const char** argv) +{ + int _row = 0; + int _hex = 0; + int _primaryKey = 0; + const char* _tableName = NULL; + + struct getargs args[] = { + { "row", 'r', + arg_integer, &_row, "The row number", "row" }, + { "primarykey", 'p', + arg_integer, &_primaryKey, "The primary key", "primarykey" }, + { "hex", 'h', + arg_flag, &_hex, "Print hex", "hex" } + }; + + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + + if(getarg(args, num_args, argc, argv, &optind) || argv[optind] == NULL) { + arg_printusage(args, num_args, argv[0], "table name\n"); + return NDBT_WRONGARGS; + } + // Check if table name is supplied + if (argv[optind] != NULL) + _tableName = argv[optind]; + + + const NdbDictionary::Table* table = NDBT_Tables::getTable(_tableName); + // const NDBT_Attribute* attribute = table->getAttribute(_column); + + g_info << "Table " << _tableName << endl + << "Row: " << _row << ", PrimaryKey: " << _primaryKey + << endl; + + Ndb* ndb = new Ndb("TEST_DB"); + if (ndb->init() == 0 && ndb->waitUntilReady(30) == 0) + { + NdbConnection* conn = ndb->startTransaction(); + if (conn == NULL) + { + g_info << "ERROR: " << ndb->getNdbError() << endl; + delete ndb; + return -1; + } + NdbOperation* op = conn->getNdbOperation(_tableName); + if (op == NULL) + { + g_info << "ERROR: " << conn->getNdbError() << endl; + delete ndb; + return -1; + } + op->readTuple(); + NdbRecAttr** data = new NdbRecAttr*[table->getNoOfColumns()]; + for (int i = 0; i < table->getNoOfColumns(); i++) + { + const NdbDictionary::Column* c = table->getColumn(i); + if (c->getPrimaryKey()) + { + op->equal(c->getName(), _primaryKey); + data[i] = op->getValue(c->getName(), NULL); + } + else + { + data[i] = op->getValue(c->getName(), NULL); + } + } + + if (conn->execute(Commit) == 0) + { + // Print column names + for (int i = 0; i < table->getNoOfColumns(); i++) + { + const NdbDictionary::Column* c = table->getColumn(i); + + g_info + << c->getName() + << "[" << c->getType() << "] "; + } + g_info << endl; + + if (_hex) + { + g_info << hex; + } + for (int i = 0; i < table->getNoOfColumns(); i++) + { + NdbRecAttr* a = data[i]; + switch(a->getType()) + { + case NdbDictionary::Column::Char: + case NdbDictionary::Column::Varchar: + case NdbDictionary::Column::Binary: + case NdbDictionary::Column::Varbinary: + { + if (_hex) + { + char* b = a->aRef(); + for (int j = 0; j < a->arraySize(); j++) + { + //ndbout_c("%x", b[j]); + g_info << hex << b[j] << "[" << dec << j << "]"; + } + } + else + { + g_info << "\"" + << a->aRef() << "\""; + } + g_info << " "; + } + break; + + case NdbDictionary::Column::Int: + case NdbDictionary::Column::Unsigned: + { + g_info << a->int32_value() << " "; + } + break; + + case NdbDictionary::Column::Bigint: + case NdbDictionary::Column::Bigunsigned: + { + g_info << a->int64_value() << " "; + } + break; + + case NdbDictionary::Column::Float: + { + g_info << a->float_value() << " "; + } + break; + + case NdbDictionary::Column::Undefined: + default: + { + g_info << "Undefined!!! "; + } + break; + + } // case + g_info << " "; + } // for + g_info << endl; + } // if (conn + else + { + g_info << "Failed to commit read transaction... " + << conn->getNdbError() + << ", commitStatus = " << conn->commitStatus() + << endl; + } + + delete[] data; + + ndb->closeTransaction(conn); + } // if (ndb.init + else + { + g_info << "ERROR: Unable to connect to NDB, " + << ndb->getNdbError() << endl; + } + delete ndb; + + return 0; +} diff --git a/ndb/test/tools/hugoPkReadRecord/Makefile b/ndb/test/tools/hugoPkReadRecord/Makefile deleted file mode 100644 index 158a79a5666..00000000000 --- a/ndb/test/tools/hugoPkReadRecord/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := hugoPkReadRecord - -# Source files of non-templated classes (.C files) -SOURCES = hugoPkReadRecord.cpp - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/test/tools/hugoPkReadRecord/hugoPkReadRecord.cpp b/ndb/test/tools/hugoPkReadRecord/hugoPkReadRecord.cpp deleted file mode 100644 index ac17ffffee8..00000000000 --- a/ndb/test/tools/hugoPkReadRecord/hugoPkReadRecord.cpp +++ /dev/null @@ -1,194 +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 */ - -#include - -#include -#include -#include -#include -#include -#include -#include - -//extern NdbOut g_info; - -int main(int argc, const char** argv) -{ - int _row = 0; - int _hex = 0; - int _primaryKey = 0; - const char* _tableName = NULL; - - struct getargs args[] = { - { "row", 'r', - arg_integer, &_row, "The row number", "row" }, - { "primarykey", 'p', - arg_integer, &_primaryKey, "The primary key", "primarykey" }, - { "hex", 'h', - arg_flag, &_hex, "Print hex", "hex" } - }; - - int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; - - if(getarg(args, num_args, argc, argv, &optind) || argv[optind] == NULL) { - arg_printusage(args, num_args, argv[0], "table name\n"); - return NDBT_WRONGARGS; - } - // Check if table name is supplied - if (argv[optind] != NULL) - _tableName = argv[optind]; - - - const NdbDictionary::Table* table = NDBT_Tables::getTable(_tableName); - // const NDBT_Attribute* attribute = table->getAttribute(_column); - - g_info << "Table " << _tableName << endl - << "Row: " << _row << ", PrimaryKey: " << _primaryKey - << endl; - - Ndb* ndb = new Ndb("TEST_DB"); - if (ndb->init() == 0 && ndb->waitUntilReady(30) == 0) - { - NdbConnection* conn = ndb->startTransaction(); - if (conn == NULL) - { - g_info << "ERROR: " << ndb->getNdbError() << endl; - delete ndb; - return -1; - } - NdbOperation* op = conn->getNdbOperation(_tableName); - if (op == NULL) - { - g_info << "ERROR: " << conn->getNdbError() << endl; - delete ndb; - return -1; - } - op->readTuple(); - NdbRecAttr** data = new NdbRecAttr*[table->getNoOfColumns()]; - for (int i = 0; i < table->getNoOfColumns(); i++) - { - const NdbDictionary::Column* c = table->getColumn(i); - if (c->getPrimaryKey()) - { - op->equal(c->getName(), _primaryKey); - data[i] = op->getValue(c->getName(), NULL); - } - else - { - data[i] = op->getValue(c->getName(), NULL); - } - } - - if (conn->execute(Commit) == 0) - { - // Print column names - for (int i = 0; i < table->getNoOfColumns(); i++) - { - const NdbDictionary::Column* c = table->getColumn(i); - - g_info - << c->getName() - << "[" << c->getType() << "] "; - } - g_info << endl; - - if (_hex) - { - g_info << hex; - } - for (int i = 0; i < table->getNoOfColumns(); i++) - { - NdbRecAttr* a = data[i]; - switch(a->getType()) - { - case NdbDictionary::Column::Char: - case NdbDictionary::Column::Varchar: - case NdbDictionary::Column::Binary: - case NdbDictionary::Column::Varbinary: - { - if (_hex) - { - char* b = a->aRef(); - for (int j = 0; j < a->arraySize(); j++) - { - //ndbout_c("%x", b[j]); - g_info << hex << b[j] << "[" << dec << j << "]"; - } - } - else - { - g_info << "\"" - << a->aRef() << "\""; - } - g_info << " "; - } - break; - - case NdbDictionary::Column::Int: - case NdbDictionary::Column::Unsigned: - { - g_info << a->int32_value() << " "; - } - break; - - case NdbDictionary::Column::Bigint: - case NdbDictionary::Column::Bigunsigned: - { - g_info << a->int64_value() << " "; - } - break; - - case NdbDictionary::Column::Float: - { - g_info << a->float_value() << " "; - } - break; - - case NdbDictionary::Column::Undefined: - default: - { - g_info << "Undefined!!! "; - } - break; - - } // case - g_info << " "; - } // for - g_info << endl; - } // if (conn - else - { - g_info << "Failed to commit read transaction... " - << conn->getNdbError() - << ", commitStatus = " << conn->commitStatus() - << endl; - } - - delete[] data; - - ndb->closeTransaction(conn); - } // if (ndb.init - else - { - g_info << "ERROR: Unable to connect to NDB, " - << ndb->getNdbError() << endl; - } - delete ndb; - - return 0; -} diff --git a/ndb/test/tools/hugoPkUpdate.cpp b/ndb/test/tools/hugoPkUpdate.cpp new file mode 100644 index 00000000000..e7edc3a991d --- /dev/null +++ b/ndb/test/tools/hugoPkUpdate.cpp @@ -0,0 +1,88 @@ +/* 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 */ + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +int main(int argc, const char** argv){ + + int _records = 0; + int _loops = 1; + int _abort = 0; + int _batch = 0; + const char* _tabname = NULL; + int _help = 0; + + struct getargs args[] = { + { "aborts", 'a', arg_integer, &_abort, "percent of transactions that are aborted", "abort%" }, + { "loops", 'l', arg_integer, &_loops, "number of times to run this program(0=infinite loop)", "loops" }, + // { "batch", 'b', arg_integer, &_batch, "batch value", "batch" }, + { "records", 'r', arg_integer, &_records, "Number of records", "records" }, + { "usage", '?', arg_flag, &_help, "Print help", "" } + }; + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + char desc[] = + "tabname\n"\ + "This program will update all records in a table using PK\n"; + + if(getarg(args, num_args, argc, argv, &optind) || + argv[optind] == NULL || _records == 0 || _help) { + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + _tabname = argv[optind]; + + // Connect to Ndb + Ndb MyNdb( "TEST_DB" ); + + if(MyNdb.init() != 0){ + ERR(MyNdb.getNdbError()); + return NDBT_ProgramExit(NDBT_FAILED); + } + + 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); + if(pTab == NULL){ + ndbout << " Table " << _tabname << " does not exist!" << endl; + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + + HugoTransactions hugoTrans(*pTab); + int i = 0; + while (i<_loops || _loops==0) { + ndbout << "loop " << i << ": "; + if (hugoTrans.pkUpdateRecords(&MyNdb, + _records) != 0){ + return NDBT_ProgramExit(NDBT_FAILED); + } + i++; + } + + return NDBT_ProgramExit(NDBT_OK); +} diff --git a/ndb/test/tools/hugoPkUpdate/Makefile b/ndb/test/tools/hugoPkUpdate/Makefile deleted file mode 100644 index 48795b62206..00000000000 --- a/ndb/test/tools/hugoPkUpdate/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := hugoPkUpdate - -SOURCES := hugoPkUpd.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/tools/hugoPkUpdate/hugoPkUpd.cpp b/ndb/test/tools/hugoPkUpdate/hugoPkUpd.cpp deleted file mode 100644 index e7edc3a991d..00000000000 --- a/ndb/test/tools/hugoPkUpdate/hugoPkUpd.cpp +++ /dev/null @@ -1,88 +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 */ - -#include - -#include - -#include -#include -#include -#include -#include - -#include - -int main(int argc, const char** argv){ - - int _records = 0; - int _loops = 1; - int _abort = 0; - int _batch = 0; - const char* _tabname = NULL; - int _help = 0; - - struct getargs args[] = { - { "aborts", 'a', arg_integer, &_abort, "percent of transactions that are aborted", "abort%" }, - { "loops", 'l', arg_integer, &_loops, "number of times to run this program(0=infinite loop)", "loops" }, - // { "batch", 'b', arg_integer, &_batch, "batch value", "batch" }, - { "records", 'r', arg_integer, &_records, "Number of records", "records" }, - { "usage", '?', arg_flag, &_help, "Print help", "" } - }; - int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; - char desc[] = - "tabname\n"\ - "This program will update all records in a table using PK\n"; - - if(getarg(args, num_args, argc, argv, &optind) || - argv[optind] == NULL || _records == 0 || _help) { - arg_printusage(args, num_args, argv[0], desc); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - _tabname = argv[optind]; - - // Connect to Ndb - Ndb MyNdb( "TEST_DB" ); - - if(MyNdb.init() != 0){ - ERR(MyNdb.getNdbError()); - return NDBT_ProgramExit(NDBT_FAILED); - } - - 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); - if(pTab == NULL){ - ndbout << " Table " << _tabname << " does not exist!" << endl; - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - - HugoTransactions hugoTrans(*pTab); - int i = 0; - while (i<_loops || _loops==0) { - ndbout << "loop " << i << ": "; - if (hugoTrans.pkUpdateRecords(&MyNdb, - _records) != 0){ - return NDBT_ProgramExit(NDBT_FAILED); - } - i++; - } - - return NDBT_ProgramExit(NDBT_OK); -} diff --git a/ndb/test/tools/hugoScanRead.cpp b/ndb/test/tools/hugoScanRead.cpp new file mode 100644 index 00000000000..47ea8f4a8a7 --- /dev/null +++ b/ndb/test/tools/hugoScanRead.cpp @@ -0,0 +1,90 @@ +/* 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 */ + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +int main(int argc, const char** argv){ + + int _records = 0; + int _loops = 1; + int _abort = 0; + int _parallelism = 1; + const char* _tabname = NULL; + int _help = 0; + + struct getargs args[] = { + { "aborts", 'a', arg_integer, &_abort, "percent of transactions that are aborted", "abort%" }, + { "loops", 'l', arg_integer, &_loops, "number of times to run this program(0=infinite loop)", "loops" }, + { "parallelism", 'p', arg_integer, &_parallelism, "parallelism(1-240)", "para" }, + { "records", 'r', arg_integer, &_records, "Number of records", "recs" }, + { "usage", '?', arg_flag, &_help, "Print help", "" } + }; + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + char desc[] = + " tabname\n"\ + "This program will scan read all records in one table in Ndb.\n"\ + "It will verify every column read by calculating the expected value.\n"; + + if(getarg(args, num_args, argc, argv, &optind) || argv[optind] == NULL || _help) { + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + _tabname = argv[optind]; + + // Connect to Ndb + Ndb MyNdb( "TEST_DB" ); + + if(MyNdb.init() != 0){ + ERR(MyNdb.getNdbError()); + return NDBT_ProgramExit(NDBT_FAILED); + } + + 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); + if(pTab == NULL){ + ndbout << " Table " << _tabname << " does not exist!" << endl; + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + + HugoTransactions hugoTrans(*pTab); + int i = 0; + while (i<_loops || _loops==0) { + ndbout << i << ": "; + if(hugoTrans.scanReadRecords(&MyNdb, + 0, + _abort, + _parallelism) != 0){ + return NDBT_ProgramExit(NDBT_FAILED); + } + i++; + } + + return NDBT_ProgramExit(NDBT_OK); +} diff --git a/ndb/test/tools/hugoScanRead/Makefile b/ndb/test/tools/hugoScanRead/Makefile deleted file mode 100644 index b88377c299e..00000000000 --- a/ndb/test/tools/hugoScanRead/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := hugoScanRead - -SOURCES := hugoScanRead.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/tools/hugoScanRead/hugoScanRead.cpp b/ndb/test/tools/hugoScanRead/hugoScanRead.cpp deleted file mode 100644 index 47ea8f4a8a7..00000000000 --- a/ndb/test/tools/hugoScanRead/hugoScanRead.cpp +++ /dev/null @@ -1,90 +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 */ - -#include - -#include - -#include -#include -#include -#include -#include - -#include - -int main(int argc, const char** argv){ - - int _records = 0; - int _loops = 1; - int _abort = 0; - int _parallelism = 1; - const char* _tabname = NULL; - int _help = 0; - - struct getargs args[] = { - { "aborts", 'a', arg_integer, &_abort, "percent of transactions that are aborted", "abort%" }, - { "loops", 'l', arg_integer, &_loops, "number of times to run this program(0=infinite loop)", "loops" }, - { "parallelism", 'p', arg_integer, &_parallelism, "parallelism(1-240)", "para" }, - { "records", 'r', arg_integer, &_records, "Number of records", "recs" }, - { "usage", '?', arg_flag, &_help, "Print help", "" } - }; - int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; - char desc[] = - " tabname\n"\ - "This program will scan read all records in one table in Ndb.\n"\ - "It will verify every column read by calculating the expected value.\n"; - - if(getarg(args, num_args, argc, argv, &optind) || argv[optind] == NULL || _help) { - arg_printusage(args, num_args, argv[0], desc); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - _tabname = argv[optind]; - - // Connect to Ndb - Ndb MyNdb( "TEST_DB" ); - - if(MyNdb.init() != 0){ - ERR(MyNdb.getNdbError()); - return NDBT_ProgramExit(NDBT_FAILED); - } - - 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); - if(pTab == NULL){ - ndbout << " Table " << _tabname << " does not exist!" << endl; - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - - HugoTransactions hugoTrans(*pTab); - int i = 0; - while (i<_loops || _loops==0) { - ndbout << i << ": "; - if(hugoTrans.scanReadRecords(&MyNdb, - 0, - _abort, - _parallelism) != 0){ - return NDBT_ProgramExit(NDBT_FAILED); - } - i++; - } - - return NDBT_ProgramExit(NDBT_OK); -} diff --git a/ndb/test/tools/hugoScanUpdate.cpp b/ndb/test/tools/hugoScanUpdate.cpp new file mode 100644 index 00000000000..3e2255ca0f3 --- /dev/null +++ b/ndb/test/tools/hugoScanUpdate.cpp @@ -0,0 +1,100 @@ +/* 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 */ + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +int main(int argc, const char** argv){ + + int _records = 0; + int _loops = 1; + int _parallelism = 1; + int _ver2 = 0; + const char* _tabname = NULL; + int _help = 0; + + struct getargs args[] = { + { "loops", 'l', arg_integer, &_loops, "number of times to run this program(0=infinite loop)", "loops" }, + { "parallelism", 'p', arg_integer, &_parallelism, "parallelism(1-240)", "para" }, + { "records", 'r', arg_integer, &_records, "Number of records", "recs" }, + { "ver2", '2', arg_flag, &_ver2, "Use version 2 of scanUpdateRecords", "" }, + { "ver2", '1', arg_negative_flag, &_ver2, "Use version 1 of scanUpdateRecords (default)", "" }, + { "usage", '?', arg_flag, &_help, "Print help", "" } + }; + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + char desc[] = + "tabname\n"\ + "This program will scan update all records in one table in Ndb\n"; + + if(getarg(args, num_args, argc, argv, &optind) || + argv[optind] == NULL || _help) { + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + _tabname = argv[optind]; + + // Connect to Ndb + Ndb MyNdb( "TEST_DB" ); + + if(MyNdb.init() != 0){ + ERR(MyNdb.getNdbError()); + return NDBT_ProgramExit(NDBT_FAILED); + } + + 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); + if(pTab == NULL){ + ndbout << " Table " << _tabname << " does not exist!" << endl; + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + + HugoTransactions hugoTrans(*pTab); + int i = 0; + int res = NDBT_FAILED; + while (i<_loops || _loops==0) { + ndbout << i << ": "; + if (_ver2 == 0){ + res = hugoTrans.scanUpdateRecords(&MyNdb, + _records, + 0, + _parallelism); + } else{ + res = hugoTrans.scanUpdateRecords2(&MyNdb, + _records, + 0, + _parallelism); + } + if (res != NDBT_OK ){ + return NDBT_ProgramExit(NDBT_FAILED); + } + i++; + } + + return NDBT_ProgramExit(NDBT_OK); +} diff --git a/ndb/test/tools/hugoScanUpdate/Makefile b/ndb/test/tools/hugoScanUpdate/Makefile deleted file mode 100644 index ec0e07bfd84..00000000000 --- a/ndb/test/tools/hugoScanUpdate/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := hugoScanUpdate - -SOURCES := hugoScanUpd.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/tools/hugoScanUpdate/hugoScanUpd.cpp b/ndb/test/tools/hugoScanUpdate/hugoScanUpd.cpp deleted file mode 100644 index 3e2255ca0f3..00000000000 --- a/ndb/test/tools/hugoScanUpdate/hugoScanUpd.cpp +++ /dev/null @@ -1,100 +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 */ - -#include - -#include - -#include -#include -#include -#include -#include - -#include - -int main(int argc, const char** argv){ - - int _records = 0; - int _loops = 1; - int _parallelism = 1; - int _ver2 = 0; - const char* _tabname = NULL; - int _help = 0; - - struct getargs args[] = { - { "loops", 'l', arg_integer, &_loops, "number of times to run this program(0=infinite loop)", "loops" }, - { "parallelism", 'p', arg_integer, &_parallelism, "parallelism(1-240)", "para" }, - { "records", 'r', arg_integer, &_records, "Number of records", "recs" }, - { "ver2", '2', arg_flag, &_ver2, "Use version 2 of scanUpdateRecords", "" }, - { "ver2", '1', arg_negative_flag, &_ver2, "Use version 1 of scanUpdateRecords (default)", "" }, - { "usage", '?', arg_flag, &_help, "Print help", "" } - }; - int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; - char desc[] = - "tabname\n"\ - "This program will scan update all records in one table in Ndb\n"; - - if(getarg(args, num_args, argc, argv, &optind) || - argv[optind] == NULL || _help) { - arg_printusage(args, num_args, argv[0], desc); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - _tabname = argv[optind]; - - // Connect to Ndb - Ndb MyNdb( "TEST_DB" ); - - if(MyNdb.init() != 0){ - ERR(MyNdb.getNdbError()); - return NDBT_ProgramExit(NDBT_FAILED); - } - - 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); - if(pTab == NULL){ - ndbout << " Table " << _tabname << " does not exist!" << endl; - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - - HugoTransactions hugoTrans(*pTab); - int i = 0; - int res = NDBT_FAILED; - while (i<_loops || _loops==0) { - ndbout << i << ": "; - if (_ver2 == 0){ - res = hugoTrans.scanUpdateRecords(&MyNdb, - _records, - 0, - _parallelism); - } else{ - res = hugoTrans.scanUpdateRecords2(&MyNdb, - _records, - 0, - _parallelism); - } - if (res != NDBT_OK ){ - return NDBT_ProgramExit(NDBT_FAILED); - } - i++; - } - - return NDBT_ProgramExit(NDBT_OK); -} diff --git a/ndb/test/tools/old_dirs/hugoCalculator/Makefile b/ndb/test/tools/old_dirs/hugoCalculator/Makefile new file mode 100644 index 00000000000..a29deeaacd3 --- /dev/null +++ b/ndb/test/tools/old_dirs/hugoCalculator/Makefile @@ -0,0 +1,11 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := hugoCalculator + +# Source files of non-templated classes (.C files) +SOURCES = hugoCalculator.cpp + +include $(NDB_TOP)/Epilogue.mk + diff --git a/ndb/test/tools/old_dirs/hugoFill/Makefile b/ndb/test/tools/old_dirs/hugoFill/Makefile new file mode 100644 index 00000000000..3da745810b6 --- /dev/null +++ b/ndb/test/tools/old_dirs/hugoFill/Makefile @@ -0,0 +1,11 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := hugoFill + +# Source files of non-templated classes (.C files) +SOURCES = hugoFill.cpp + +include $(NDB_TOP)/Epilogue.mk + diff --git a/ndb/test/tools/old_dirs/hugoLoad/Makefile b/ndb/test/tools/old_dirs/hugoLoad/Makefile new file mode 100644 index 00000000000..7c5756d0d41 --- /dev/null +++ b/ndb/test/tools/old_dirs/hugoLoad/Makefile @@ -0,0 +1,11 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := hugoLoad + +# Source files of non-templated classes (.C files) +SOURCES = hugoLoad.cpp + +include $(NDB_TOP)/Epilogue.mk + diff --git a/ndb/test/tools/old_dirs/hugoLockRecords/Makefile b/ndb/test/tools/old_dirs/hugoLockRecords/Makefile new file mode 100644 index 00000000000..3235750cbf8 --- /dev/null +++ b/ndb/test/tools/old_dirs/hugoLockRecords/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := hugoLockRecords + +SOURCES := hugoLockRecords.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/tools/old_dirs/hugoPkDelete/Makefile b/ndb/test/tools/old_dirs/hugoPkDelete/Makefile new file mode 100644 index 00000000000..e6d53611c54 --- /dev/null +++ b/ndb/test/tools/old_dirs/hugoPkDelete/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := hugoPkDelete + +SOURCES := hugoPkDel.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/tools/old_dirs/hugoPkRead/Makefile b/ndb/test/tools/old_dirs/hugoPkRead/Makefile new file mode 100644 index 00000000000..03580dc0d18 --- /dev/null +++ b/ndb/test/tools/old_dirs/hugoPkRead/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := hugoPkRead + +SOURCES := hugoPkRead.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/tools/old_dirs/hugoPkReadRecord/Makefile b/ndb/test/tools/old_dirs/hugoPkReadRecord/Makefile new file mode 100644 index 00000000000..158a79a5666 --- /dev/null +++ b/ndb/test/tools/old_dirs/hugoPkReadRecord/Makefile @@ -0,0 +1,11 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := hugoPkReadRecord + +# Source files of non-templated classes (.C files) +SOURCES = hugoPkReadRecord.cpp + +include $(NDB_TOP)/Epilogue.mk + diff --git a/ndb/test/tools/old_dirs/hugoPkUpdate/Makefile b/ndb/test/tools/old_dirs/hugoPkUpdate/Makefile new file mode 100644 index 00000000000..48795b62206 --- /dev/null +++ b/ndb/test/tools/old_dirs/hugoPkUpdate/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := hugoPkUpdate + +SOURCES := hugoPkUpd.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/tools/old_dirs/hugoScanRead/Makefile b/ndb/test/tools/old_dirs/hugoScanRead/Makefile new file mode 100644 index 00000000000..b88377c299e --- /dev/null +++ b/ndb/test/tools/old_dirs/hugoScanRead/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := hugoScanRead + +SOURCES := hugoScanRead.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/tools/old_dirs/hugoScanUpdate/Makefile b/ndb/test/tools/old_dirs/hugoScanUpdate/Makefile new file mode 100644 index 00000000000..ec0e07bfd84 --- /dev/null +++ b/ndb/test/tools/old_dirs/hugoScanUpdate/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := hugoScanUpdate + +SOURCES := hugoScanUpd.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/tools/old_dirs/restart/Makefile b/ndb/test/tools/old_dirs/restart/Makefile new file mode 100644 index 00000000000..05d9e98c5bc --- /dev/null +++ b/ndb/test/tools/old_dirs/restart/Makefile @@ -0,0 +1,11 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := restart + +# Source files of non-templated classes (.C files) +SOURCES = restart.cpp + +include $(NDB_TOP)/Epilogue.mk + diff --git a/ndb/test/tools/old_dirs/transproxy/Makefile b/ndb/test/tools/old_dirs/transproxy/Makefile new file mode 100644 index 00000000000..d6a76ed2e3d --- /dev/null +++ b/ndb/test/tools/old_dirs/transproxy/Makefile @@ -0,0 +1,29 @@ +include .defs.mk + +TYPE = + +BIN_TARGET = transproxy + +SOURCES = transproxy.cpp + +CCFLAGS_LOC +=\ + -I$(NDB_TOP)/include/kernel \ + -I$(NDB_TOP)/include/mgmcommon \ + -I$(NDB_TOP)/src/common/mgmcommon \ + -I$(NDB_TOP)/src/mgmsrv + +LIBS_LOC +=\ + -L$(NDB_TOP)/lib + +LIBS_SPEC +=\ + $(NDB_TOP)/src/mgmsrv/InitConfigFileParser.o \ + $(NDB_TOP)/src/mgmsrv/Config.o \ + $(NDB_TOP)/src/mgmsrv/Container.o \ + $(NDB_TOP)/src/mgmsrv/Str.o \ + $(NDB_TOP)/src/mgmsrv/convertStrToInt.o \ + -lNDB_API \ + -leventlogger \ + -llogger \ + -lportlib + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/tools/old_dirs/verify_index/Makefile b/ndb/test/tools/old_dirs/verify_index/Makefile new file mode 100644 index 00000000000..f6b31e4dc8e --- /dev/null +++ b/ndb/test/tools/old_dirs/verify_index/Makefile @@ -0,0 +1,9 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := verify_index + +SOURCES := verify_index.cpp + +include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/tools/old_dirs/waiter/Makefile_old b/ndb/test/tools/old_dirs/waiter/Makefile_old new file mode 100644 index 00000000000..da2c9daff00 --- /dev/null +++ b/ndb/test/tools/old_dirs/waiter/Makefile_old @@ -0,0 +1,11 @@ +include .defs.mk + +TYPE := ndbapitest + +BIN_TARGET := waiter + +# Source files of non-templated classes (.C files) +SOURCES = waiter.cpp + +include $(NDB_TOP)/Epilogue.mk + diff --git a/ndb/test/tools/old_dirs/waiter/waiter.cpp b/ndb/test/tools/old_dirs/waiter/waiter.cpp new file mode 100644 index 00000000000..d57daff3aea --- /dev/null +++ b/ndb/test/tools/old_dirs/waiter/waiter.cpp @@ -0,0 +1,56 @@ +/* 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 */ + + +#include "mgmapi.h" +#include +#include +#include +#include +#include + + +#include +#include + +int main(int argc, const char** argv){ + + const char* _hostName = NULL; + int _help = 0; + + struct getargs args[] = { + { "usage", '?', arg_flag, &_help, "Print help", "" } + }; + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + char desc[] = + "hostname:port\n"\ + "This program will connect to the mgmsrv of a NDB cluster.\n"\ + "It will then wait for all nodes to be started\n"; + + if(getarg(args, num_args, argc, argv, &optind) || _help) { + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + _hostName = argv[optind]; + + NdbRestarter restarter(_hostName); + + if (restarter.waitClusterStarted() != 0) + return NDBT_ProgramExit(NDBT_FAILED); + + return NDBT_ProgramExit(NDBT_OK); +} diff --git a/ndb/test/tools/restart.cpp b/ndb/test/tools/restart.cpp new file mode 100644 index 00000000000..88cfb231a72 --- /dev/null +++ b/ndb/test/tools/restart.cpp @@ -0,0 +1,83 @@ +/* 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 */ + + +#include + +#include +#include +#include +#include +#include + +#include +#include + +int main(int argc, const char** argv){ + + const char* _hostName = NULL; + int _initial = 0; + int _help = 0; + int _wait = 1; + + + struct getargs args[] = { + { "initial", 'i', arg_flag, &_initial, "Do initial restart"}, + { "wait", '\0', arg_negative_flag, &_wait, "Wait until restarted(default=true)"}, + { "usage", '?', arg_flag, &_help, "Print help", "" } + + }; + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + char desc[] = + "hostname:port\n"\ + "This program will connect to the mgmsrv of a NDB cluster\n"\ + " and restart the cluster. \n"; + + if(getarg(args, num_args, argc, argv, &optind) || _help) { + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + _hostName = argv[optind]; + + NdbRestarter restarter(_hostName); + setOutputLevel(1); // Show only g_err + int result = NDBT_OK; + if (_initial){ + ndbout << "Restarting cluster with initial restart" << endl; + if (restarter.restartAll(true, false, false) != 0) + result = NDBT_FAILED; + } else { + ndbout << "Restarting cluster " << endl; + if (restarter.restartAll() != 0) + result = NDBT_FAILED; + } + if (result == NDBT_FAILED){ + g_err << "Failed to restart cluster" << endl; + return NDBT_ProgramExit(NDBT_FAILED); + } + + if (_wait == 1){ + ndbout << "Waiting for cluster to start" << endl; + if ( restarter.waitClusterStarted(120) != 0){ + ndbout << "Failed waiting for restart of cluster" << endl; + result = NDBT_FAILED; + } + } + ndbout << "Cluster restarted" << endl; + + return NDBT_ProgramExit(result); +} diff --git a/ndb/test/tools/restart/Makefile b/ndb/test/tools/restart/Makefile deleted file mode 100644 index 05d9e98c5bc..00000000000 --- a/ndb/test/tools/restart/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := restart - -# Source files of non-templated classes (.C files) -SOURCES = restart.cpp - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/test/tools/restart/restart.cpp b/ndb/test/tools/restart/restart.cpp deleted file mode 100644 index 88cfb231a72..00000000000 --- a/ndb/test/tools/restart/restart.cpp +++ /dev/null @@ -1,83 +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 */ - - -#include - -#include -#include -#include -#include -#include - -#include -#include - -int main(int argc, const char** argv){ - - const char* _hostName = NULL; - int _initial = 0; - int _help = 0; - int _wait = 1; - - - struct getargs args[] = { - { "initial", 'i', arg_flag, &_initial, "Do initial restart"}, - { "wait", '\0', arg_negative_flag, &_wait, "Wait until restarted(default=true)"}, - { "usage", '?', arg_flag, &_help, "Print help", "" } - - }; - int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; - char desc[] = - "hostname:port\n"\ - "This program will connect to the mgmsrv of a NDB cluster\n"\ - " and restart the cluster. \n"; - - if(getarg(args, num_args, argc, argv, &optind) || _help) { - arg_printusage(args, num_args, argv[0], desc); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - _hostName = argv[optind]; - - NdbRestarter restarter(_hostName); - setOutputLevel(1); // Show only g_err - int result = NDBT_OK; - if (_initial){ - ndbout << "Restarting cluster with initial restart" << endl; - if (restarter.restartAll(true, false, false) != 0) - result = NDBT_FAILED; - } else { - ndbout << "Restarting cluster " << endl; - if (restarter.restartAll() != 0) - result = NDBT_FAILED; - } - if (result == NDBT_FAILED){ - g_err << "Failed to restart cluster" << endl; - return NDBT_ProgramExit(NDBT_FAILED); - } - - if (_wait == 1){ - ndbout << "Waiting for cluster to start" << endl; - if ( restarter.waitClusterStarted(120) != 0){ - ndbout << "Failed waiting for restart of cluster" << endl; - result = NDBT_FAILED; - } - } - ndbout << "Cluster restarted" << endl; - - return NDBT_ProgramExit(result); -} diff --git a/ndb/test/tools/transproxy.cpp b/ndb/test/tools/transproxy.cpp new file mode 100644 index 00000000000..384a8a34f03 --- /dev/null +++ b/ndb/test/tools/transproxy.cpp @@ -0,0 +1,362 @@ +/* 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 */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void +fatal(char const* fmt, ...) +{ + va_list ap; + char buf[200]; + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + ndbout << "FATAL: " << buf << endl; + sleep(1); + exit(1); +} + +static void +debug(char const* fmt, ...) +{ + va_list ap; + char buf[200]; + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + ndbout << buf << endl; +} + +// node +struct Node { + enum Type { MGM = 1, DB = 2, API = 3 }; + Type type; + unsigned id; // node id + static Node* list; + static unsigned count; + static Node* find(unsigned n) { + for (unsigned i = 0; i < count; i++) { + if (list[i].id == n) + return &list[i]; + } + return 0; + } +}; + +unsigned Node::count = 0; +Node* Node::list = 0; + +struct Copy { + int rfd; // read from + int wfd; // write to + unsigned char* buf; + unsigned bufsiz; + NdbThread* thread; + void run(); + char info[20]; +}; + +// connection between nodes 0-server side 1-client side +// we are client to 0 and server to 1 +struct Conn { + Node* node[2]; // the nodes + unsigned port; // server port + unsigned proxy; // proxy port + static unsigned count; + static unsigned proxycount; + static Conn* list; + NdbThread* thread; // thread handling this connection + void run(); // run the connection + int sockfd[2]; // socket 0-on server side 1-client side + void conn0(); // connect to side 0 + void conn1(); // connect to side 0 + char info[20]; + Copy copy[2]; // 0-to-1 and 1-to-0 +}; + +unsigned Conn::count = 0; +unsigned Conn::proxycount = 0; +Conn* Conn::list = 0; + +// global data +static char* hostname = 0; +static struct sockaddr_in hostaddr; +static char* localcfgfile = 0; +static char* initcfgfile = 0; +static unsigned ownnodeid = 0; + +static void +properr(const Properties* props, const char* name, int i = -1) +{ + if (i < 0) { + fatal("get %s failed: errno = %d", name, props->getPropertiesErrno()); + } else { + fatal("get %s_%d failed: errno = %d", name, i, props->getPropertiesErrno()); + } +} + +// read config and load it into our structs +static void +getcfg() +{ + LocalConfig lcfg; + if (! lcfg.read(localcfgfile)) { + fatal("read %s failed", localcfgfile); + } + ownnodeid = lcfg._ownNodeId; + debug("ownnodeid = %d", ownnodeid); + InitConfigFileParser pars(initcfgfile); + Config icfg; + if (! pars.getConfig(icfg)) { + fatal("parse %s failed", initcfgfile); + } + Properties* ccfg = icfg.getConfig(ownnodeid); + if (ccfg == 0) { + const char* err = "unknown error"; + fatal("getConfig: %s", err); + } + ccfg->put("NodeId", ownnodeid); + ccfg->put("NodeType", "MGM"); + if (! ccfg->get("NoOfNodes", &Node::count)) { + properr(ccfg, "NoOfNodes", -1); + } + debug("Node::count = %d", Node::count); + Node::list = new Node[Node::count]; + for (unsigned i = 0; i < Node::count; i++) { + Node& node = Node::list[i]; + const Properties* nodecfg; + if (! ccfg->get("Node", 1+i, &nodecfg)) { + properr(ccfg, "Node", 1+i); + } + const char* type; + if (! nodecfg->get("Type", &type)) { + properr(nodecfg, "Type"); + } + if (strcmp(type, "MGM") == 0) { + node.type = Node::MGM; + } else if (strcmp(type, "DB") == 0) { + node.type = Node::DB; + } else if (strcmp(type, "API") == 0) { + node.type = Node::API; + } else { + fatal("prop %s_%d bad Type = %s", "Node", 1+i, type); + } + if (! nodecfg->get("NodeId", &node.id)) { + properr(nodecfg, "NodeId"); + } + debug("node id=%d type=%d", node.id, node.type); + } + IPCConfig ipccfg(ccfg); + if (ipccfg.init() != 0) { + fatal("ipccfg init failed"); + } + if (! ccfg->get("NoOfConnections", &Conn::count)) { + properr(ccfg, "NoOfConnections"); + } + debug("Conn::count = %d", Conn::count); + Conn::list = new Conn[Conn::count]; + for (unsigned i = 0; i < Conn::count; i++) { + Conn& conn = Conn::list[i]; + const Properties* conncfg; + if (! ccfg->get("Connection", i, &conncfg)) { + properr(ccfg, "Connection", i); + } + unsigned n; + if (! conncfg->get("NodeId1", &n)) { + properr(conncfg, "NodeId1"); + } + if ((conn.node[0] = Node::find(n)) == 0) { + fatal("node %d not found", n); + } + if (! conncfg->get("NodeId2", &n)) { + properr(conncfg, "NodeId2"); + } + if ((conn.node[1] = Node::find(n)) == 0) { + fatal("node %d not found", n); + } + if (! conncfg->get("PortNumber", &conn.port)) { + properr(conncfg, "PortNumber"); + } + conn.proxy = 0; + const char* proxy; + if (conncfg->get("Proxy", &proxy)) { + conn.proxy = atoi(proxy); + if (conn.proxy > 0) { + Conn::proxycount++; + } + } + sprintf(conn.info, "conn %d-%d", conn.node[0]->id, conn.node[1]->id); + } +} + +void +Conn::conn0() +{ + int fd; + while (1) { + if ((fd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { + fatal("%s: create client socket failed: %s", info, strerror(errno)); + } + struct sockaddr_in servaddr; + memset(&servaddr, 0, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(port); + servaddr.sin_addr = hostaddr.sin_addr; +#if 0 // coredump + if (Ndb_getInAddr(&servaddr.sin_addr, hostname) != 0) { + fatal("%s: hostname %s lookup failed", info, hostname); + } +#endif + if (connect(fd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == 0) + break; + if (errno != ECONNREFUSED) { + fatal("%s: connect failed: %s", info, strerror(errno)); + } + close(fd); + NdbSleep_MilliSleep(100); + } + sockfd[0] = fd; + debug("%s: side 0 connected", info); +} + +void +Conn::conn1() +{ + int servfd; + if ((servfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { + fatal("%s: create server socket failed: %s", info, strerror(errno)); + } + struct sockaddr_in servaddr; + memset(&servaddr, 0, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(proxy); + const int on = 1; + setsockopt(servfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)); + if (bind(servfd, (struct sockaddr*) &servaddr, sizeof(servaddr)) == -1) { + fatal("%s: bind %d failed: %s", info, proxy, strerror(errno)); + } + if (listen(servfd, 1) == -1) { + fatal("%s: listen %d failed: %s", info, proxy, strerror(errno)); + } + int fd; + if ((fd = accept(servfd, 0, 0)) == -1) { + fatal("%s: accept failed: %s", info, strerror(errno)); + } + sockfd[1] = fd; + close(servfd); + debug("%s: side 1 connected", info); +} + +void +Copy::run() +{ + debug("%s: start", info); + int n, m; + while (1) { + n = read(rfd, buf, sizeof(buf)); + if (n < 0) + fatal("read error: %s", strerror(errno)); + m = write(wfd, buf, n); + if (m != n) + fatal("write error: %s", strerror(errno)); + } + debug("%s: stop", info); +} + +extern "C" void* +copyrun_C(void* copy) +{ + ((Copy*) copy)->run(); + NdbThread_Exit(0); + return 0; +} + +void +Conn::run() +{ + debug("%s: start", info); + conn1(); + conn0(); + const unsigned siz = 32 * 1024; + for (int i = 0; i < 2; i++) { + Copy& copy = this->copy[i]; + copy.rfd = sockfd[i]; + copy.wfd = sockfd[1-i]; + copy.buf = new unsigned char[siz]; + copy.bufsiz = siz; + sprintf(copy.info, "copy %d-%d", this->node[i]->id, this->node[1-i]->id); + copy.thread = NdbThread_Create(copyrun_C, (void**)©, + 8192, "copyrun", NDB_THREAD_PRIO_LOW); + if (copy.thread == 0) { + fatal("%s: create thread %d failed errno=%d", i, errno); + } + } + debug("%s: stop", info); +} + +extern "C" void* +connrun_C(void* conn) +{ + ((Conn*) conn)->run(); + NdbThread_Exit(0); + return 0; +} + +static void +start() +{ + NdbThread_SetConcurrencyLevel(3 * Conn::proxycount + 2); + for (unsigned i = 0; i < Conn::count; i++) { + Conn& conn = Conn::list[i]; + if (! conn.proxy) + continue; + conn.thread = NdbThread_Create(connrun_C, (void**)&conn, + 8192, "connrun", NDB_THREAD_PRIO_LOW); + if (conn.thread == 0) { + fatal("create thread %d failed errno=%d", i, errno); + } + } + sleep(3600); +} + +int +main(int av, char** ac) +{ + debug("start"); + hostname = "ndb-srv7"; + if (Ndb_getInAddr(&hostaddr.sin_addr, hostname) != 0) { + fatal("hostname %s lookup failed", hostname); + } + localcfgfile = "Ndb.cfg"; + initcfgfile = "config.txt"; + getcfg(); + start(); + debug("done"); + return 0; +} + +// vim: set sw=4 noet: diff --git a/ndb/test/tools/verify_index.cpp b/ndb/test/tools/verify_index.cpp new file mode 100644 index 00000000000..1295b657e9b --- /dev/null +++ b/ndb/test/tools/verify_index.cpp @@ -0,0 +1,85 @@ +/* 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 */ + +#include + +#include + +#include +#include +#include +#include +#include +#include + + +int main(int argc, const char** argv){ + int _parallelism = 240; + const char* _tabname = NULL; + const char* _indexname = NULL; + int _help = 0; + + struct getargs args[] = { + { "parallelism", 's', arg_integer, &_parallelism, "parallelism", "parallelism" }, + { "usage", '?', arg_flag, &_help, "Print help", "" } + }; + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + char desc[] = + "tabname indexname\n"\ + "This program will verify the index [indexname] and compare it to data\n" + "in table [tablename]\n"; + + if(getarg(args, num_args, argc, argv, &optind) || + argv[optind] == NULL || argv[optind+1] == NULL || _help) { + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + _tabname = argv[optind]; + _indexname = argv[optind+1]; + + // Connect to Ndb + Ndb MyNdb( "TEST_DB" ); + + if(MyNdb.init() != 0){ + ERR(MyNdb.getNdbError()); + return NDBT_ProgramExit(NDBT_FAILED); + } + + // Connect to Ndb and wait for it to become ready + while(MyNdb.waitUntilReady() != 0) + ndbout << "Waiting for ndb to become ready..." << endl; + + // Check if table exists in db + const NdbDictionary::Table * pTab = NDBT_Table::discoverTableFromDb(&MyNdb, _tabname); + if(pTab == NULL){ + ndbout << " Table " << _tabname << " does not exist!" << endl; + return NDBT_ProgramExit(NDBT_FAILED); + } + + int rows = 0; + UtilTransactions utilTrans(*pTab); + if (utilTrans.verifyIndex(&MyNdb, + _indexname, + _parallelism) != 0){ + return NDBT_ProgramExit(NDBT_FAILED); + } + + return NDBT_ProgramExit(NDBT_OK); +} + + + diff --git a/ndb/test/tools/waiter.cpp b/ndb/test/tools/waiter.cpp new file mode 100644 index 00000000000..d57daff3aea --- /dev/null +++ b/ndb/test/tools/waiter.cpp @@ -0,0 +1,56 @@ +/* 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 */ + + +#include "mgmapi.h" +#include +#include +#include +#include +#include + + +#include +#include + +int main(int argc, const char** argv){ + + const char* _hostName = NULL; + int _help = 0; + + struct getargs args[] = { + { "usage", '?', arg_flag, &_help, "Print help", "" } + }; + int num_args = sizeof(args) / sizeof(args[0]); + int optind = 0; + char desc[] = + "hostname:port\n"\ + "This program will connect to the mgmsrv of a NDB cluster.\n"\ + "It will then wait for all nodes to be started\n"; + + if(getarg(args, num_args, argc, argv, &optind) || _help) { + arg_printusage(args, num_args, argv[0], desc); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + _hostName = argv[optind]; + + NdbRestarter restarter(_hostName); + + if (restarter.waitClusterStarted() != 0) + return NDBT_ProgramExit(NDBT_FAILED); + + return NDBT_ProgramExit(NDBT_OK); +} diff --git a/ndb/test/tools/waiter/Makefile b/ndb/test/tools/waiter/Makefile deleted file mode 100644 index da2c9daff00..00000000000 --- a/ndb/test/tools/waiter/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -include .defs.mk - -TYPE := ndbapitest - -BIN_TARGET := waiter - -# Source files of non-templated classes (.C files) -SOURCES = waiter.cpp - -include $(NDB_TOP)/Epilogue.mk - diff --git a/ndb/test/tools/waiter/waiter.cpp b/ndb/test/tools/waiter/waiter.cpp deleted file mode 100644 index d57daff3aea..00000000000 --- a/ndb/test/tools/waiter/waiter.cpp +++ /dev/null @@ -1,56 +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 */ - - -#include "mgmapi.h" -#include -#include -#include -#include -#include - - -#include -#include - -int main(int argc, const char** argv){ - - const char* _hostName = NULL; - int _help = 0; - - struct getargs args[] = { - { "usage", '?', arg_flag, &_help, "Print help", "" } - }; - int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; - char desc[] = - "hostname:port\n"\ - "This program will connect to the mgmsrv of a NDB cluster.\n"\ - "It will then wait for all nodes to be started\n"; - - if(getarg(args, num_args, argc, argv, &optind) || _help) { - arg_printusage(args, num_args, argv[0], desc); - return NDBT_ProgramExit(NDBT_WRONGARGS); - } - _hostName = argv[optind]; - - NdbRestarter restarter(_hostName); - - if (restarter.waitClusterStarted() != 0) - return NDBT_ProgramExit(NDBT_FAILED); - - return NDBT_ProgramExit(NDBT_OK); -} -- cgit v1.2.1