<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <title>ndbapi_simple.cpp</title> <link href="doxygen.css" rel="stylesheet" type="text/css"> <link href="tabs.css" rel="stylesheet" type="text/css"> </head><body> <!-- Generated by Doxygen 1.5.5 --> <div class="contents"> <h1><a class="anchor" name="ndbapi_simple.cpp">ndbapi_simple.cpp </a></h1><div class="fragment"><pre class="fragment"><span class="comment">/* Copyright (C) 2003 MySQL AB</span> <span class="comment"></span> <span class="comment"> This program is free software; you can redistribute it and/or modify</span> <span class="comment"> it under the terms of the GNU General Public License as published by</span> <span class="comment"> the Free Software Foundation; version 2 of the License.</span> <span class="comment"></span> <span class="comment"> This program is distributed in the hope that it will be useful,</span> <span class="comment"> but WITHOUT ANY WARRANTY; without even the implied warranty of</span> <span class="comment"> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span> <span class="comment"> GNU General Public License for more details.</span> <span class="comment"></span> <span class="comment"> You should have received a copy of the GNU General Public License</span> <span class="comment"> along with this program; if not, write to the Free Software</span> <span class="comment"> Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */</span> <span class="comment">/* </span> <span class="comment"> * ndbapi_simple.cpp: Using synchronous transactions in NDB API</span> <span class="comment"> *</span> <span class="comment"> * Correct output from this program is:</span> <span class="comment"> *</span> <span class="comment"> * ATTR1 ATTR2</span> <span class="comment"> * 0 10</span> <span class="comment"> * 1 1</span> <span class="comment"> * 2 12</span> <span class="comment"> * Detected that deleted tuple doesn't exist!</span> <span class="comment"> * 4 14</span> <span class="comment"> * 5 5</span> <span class="comment"> * 6 16</span> <span class="comment"> * 7 7</span> <span class="comment"> * 8 18</span> <span class="comment"> * 9 9</span> <span class="comment"> *</span> <span class="comment"> */</span> <span class="preprocessor">#include <mysql.h></span> <span class="preprocessor">#include <NdbApi.hpp></span> <span class="comment">// Used for cout</span> <span class="preprocessor">#include <stdio.h></span> <span class="preprocessor">#include <iostream></span> <span class="keyword">static</span> <span class="keywordtype">void</span> run_application(MYSQL &, <a class="code" href="classNdb__cluster__connection.html" title="Represents a connection to a cluster of storage nodes.">Ndb_cluster_connection</a> &); <span class="preprocessor">#define PRINT_ERROR(code,msg) \</span> <span class="preprocessor"> std::cout << "Error in " << __FILE__ << ", line: " << __LINE__ \</span> <span class="preprocessor"> << ", code: " << code \</span> <span class="preprocessor"> << ", msg: " << msg << "." << std::endl</span> <span class="preprocessor"></span><span class="preprocessor">#define MYSQLERROR(mysql) { \</span> <span class="preprocessor"> PRINT_ERROR(mysql_errno(&mysql),mysql_error(&mysql)); \</span> <span class="preprocessor"> exit(-1); }</span> <span class="preprocessor"></span><span class="preprocessor">#define APIERROR(error) { \</span> <span class="preprocessor"> PRINT_ERROR(error.code,error.message); \</span> <span class="preprocessor"> exit(-1); }</span> <span class="preprocessor"></span> <span class="keywordtype">int</span> main() { <span class="comment">// ndb_init must be called first</span> ndb_init(); <span class="comment">// connect to mysql server and cluster and run application</span> { <span class="comment">// Object representing the cluster</span> <a class="code" href="classNdb__cluster__connection.html" title="Represents a connection to a cluster of storage nodes.">Ndb_cluster_connection</a> cluster_connection; <span class="comment">// Connect to cluster management server (ndb_mgmd)</span> <span class="keywordflow">if</span> (cluster_connection.<a class="code" href="classNdb__cluster__connection.html#1c1523c47bc56f17beb5c7e9124f7f47">connect</a>(4 <span class="comment">/* retries */</span>, 5 <span class="comment">/* delay between retries */</span>, 1 <span class="comment">/* verbose */</span>)) { std::cout << <span class="stringliteral">"Cluster management server was not ready within 30 secs.\n"</span>; exit(-1); } <span class="comment">// Optionally connect and wait for the storage nodes (ndbd's)</span> <span class="keywordflow">if</span> (cluster_connection.<a class="code" href="classNdb__cluster__connection.html#02f01d4e1dba63679a4796838e3c3c7a">wait_until_ready</a>(30,0) < 0) { std::cout << <span class="stringliteral">"Cluster was not ready within 30 secs.\n"</span>; exit(-1); } <span class="comment">// connect to mysql server</span> MYSQL mysql; <span class="keywordflow">if</span> ( !mysql_init(&mysql) ) { std::cout << <span class="stringliteral">"mysql_init failed\n"</span>; exit(-1); } <span class="keywordflow">if</span> ( !mysql_real_connect(&mysql, <span class="stringliteral">"localhost"</span>, <span class="stringliteral">"root"</span>, <span class="stringliteral">""</span>, <span class="stringliteral">""</span>, 3306, <span class="stringliteral">"/tmp/mysql.sock"</span>, 0) ) MYSQLERROR(mysql); <span class="comment">// run the application code</span> run_application(mysql, cluster_connection); } ndb_end(0); std::cout << <span class="stringliteral">"\nTo drop created table use:\n"</span> << <span class="stringliteral">"echo \"drop table MYTABLENAME\" | mysql TEST_DB_1 -u root\n"</span>; <span class="keywordflow">return</span> 0; } <span class="keyword">static</span> <span class="keywordtype">void</span> create_table(MYSQL &); <span class="keyword">static</span> <span class="keywordtype">void</span> do_insert(<a class="code" href="classNdb.html" title="Represents the NDB kernel and is the main class of the NDB API.">Ndb</a> &); <span class="keyword">static</span> <span class="keywordtype">void</span> do_update(<a class="code" href="classNdb.html" title="Represents the NDB kernel and is the main class of the NDB API.">Ndb</a> &); <span class="keyword">static</span> <span class="keywordtype">void</span> do_delete(<a class="code" href="classNdb.html" title="Represents the NDB kernel and is the main class of the NDB API.">Ndb</a> &); <span class="keyword">static</span> <span class="keywordtype">void</span> do_read(<a class="code" href="classNdb.html" title="Represents the NDB kernel and is the main class of the NDB API.">Ndb</a> &); <span class="keyword">static</span> <span class="keywordtype">void</span> run_application(MYSQL &mysql, <a class="code" href="classNdb__cluster__connection.html" title="Represents a connection to a cluster of storage nodes.">Ndb_cluster_connection</a> &cluster_connection) { <span class="comment">/********************************************</span> <span class="comment"> * Connect to database via mysql-c *</span> <span class="comment"> ********************************************/</span> mysql_query(&mysql, <span class="stringliteral">"CREATE DATABASE TEST_DB_1"</span>); <span class="keywordflow">if</span> (mysql_query(&mysql, <span class="stringliteral">"USE TEST_DB_1"</span>) != 0) MYSQLERROR(mysql); create_table(mysql); <span class="comment">/********************************************</span> <span class="comment"> * Connect to database via NdbApi *</span> <span class="comment"> ********************************************/</span> <span class="comment">// Object representing the database</span> <a class="code" href="classNdb.html" title="Represents the NDB kernel and is the main class of the NDB API.">Ndb</a> myNdb( &cluster_connection, <span class="stringliteral">"TEST_DB_1"</span> ); <span class="keywordflow">if</span> (myNdb.init()) APIERROR(myNdb.getNdbError()); <span class="comment">/*</span> <span class="comment"> * Do different operations on database</span> <span class="comment"> */</span> do_insert(myNdb); do_update(myNdb); do_delete(myNdb); do_read(myNdb); } <span class="comment">/*********************************************************</span> <span class="comment"> * Create a table named MYTABLENAME if it does not exist *</span> <span class="comment"> *********************************************************/</span> <span class="keyword">static</span> <span class="keywordtype">void</span> create_table(MYSQL &mysql) { <span class="keywordflow">if</span> (mysql_query(&mysql, <span class="stringliteral">"CREATE TABLE"</span> <span class="stringliteral">" MYTABLENAME"</span> <span class="stringliteral">" (ATTR1 INT UNSIGNED NOT NULL PRIMARY KEY,"</span> <span class="stringliteral">" ATTR2 INT UNSIGNED NOT NULL)"</span> <span class="stringliteral">" ENGINE=NDB"</span>)) MYSQLERROR(mysql); } <span class="comment">/**************************************************************************</span> <span class="comment"> * Using 5 transactions, insert 10 tuples in table: (0,0),(1,1),...,(9,9) *</span> <span class="comment"> **************************************************************************/</span> <span class="keyword">static</span> <span class="keywordtype">void</span> do_insert(<a class="code" href="classNdb.html" title="Represents the NDB kernel and is the main class of the NDB API.">Ndb</a> &myNdb) { <span class="keyword">const</span> <a class="code" href="classNdbDictionary_1_1Dictionary.html" title="Dictionary for defining and retreiving meta data.">NdbDictionary::Dictionary</a>* myDict= myNdb.<a class="code" href="classNdb.html#f27ca0f4e5c074211252a7c83060a3a4">getDictionary</a>(); <span class="keyword">const</span> <a class="code" href="classNdbDictionary_1_1Table.html" title="Represents a table in NDB Cluster.">NdbDictionary::Table</a> *myTable= myDict-><a class="code" href="classNdbDictionary_1_1Dictionary.html#1a30b1bb5fa164113cb839eed64eb3b6">getTable</a>(<span class="stringliteral">"MYTABLENAME"</span>); <span class="keywordflow">if</span> (myTable == NULL) APIERROR(myDict-><a class="code" href="classNdbDictionary_1_1Dictionary.html#0af68ea9b273172b46528ee1bd806f71">getNdbError</a>()); <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i < 5; i++) { <a class="code" href="classNdbTransaction.html" title="Represents a transaction.">NdbTransaction</a> *myTransaction= myNdb.<a class="code" href="classNdb.html#7e34bb5d8e3d878a54ebb7c0e6d0c5f1">startTransaction</a>(); <span class="keywordflow">if</span> (myTransaction == NULL) APIERROR(myNdb.<a class="code" href="classNdb.html#80b53a037bb2e93b3cd6830eda58643a">getNdbError</a>()); <a class="code" href="classNdbOperation.html" title="Class of operations for use in transactions.">NdbOperation</a> *myOperation= myTransaction-><a class="code" href="classNdbTransaction.html#2aeb211e54f84bd2de6cfb8fccec8166">getNdbOperation</a>(myTable); <span class="keywordflow">if</span> (myOperation == NULL) APIERROR(myTransaction-><a class="code" href="classNdbTransaction.html#f4af91ca21b97c4fe6256a18903020fc">getNdbError</a>()); myOperation->insertTuple(); myOperation->equal(<span class="stringliteral">"ATTR1"</span>, i); myOperation->setValue(<span class="stringliteral">"ATTR2"</span>, i); myOperation= myTransaction-><a class="code" href="classNdbTransaction.html#2aeb211e54f84bd2de6cfb8fccec8166">getNdbOperation</a>(myTable); <span class="keywordflow">if</span> (myOperation == NULL) APIERROR(myTransaction-><a class="code" href="classNdbTransaction.html#f4af91ca21b97c4fe6256a18903020fc">getNdbError</a>()); myOperation->insertTuple(); myOperation->equal(<span class="stringliteral">"ATTR1"</span>, i+5); myOperation->setValue(<span class="stringliteral">"ATTR2"</span>, i+5); <span class="keywordflow">if</span> (myTransaction-><a class="code" href="classNdbTransaction.html#361d5a82078f86a5d18923f56d43cc84">execute</a>( <a class="code" href="classNdbTransaction.html#2d2a5911b91e5cf78da970a1e97f7e3ecaba2931e541dd138044b61f38918391" title="Execute and try to commit the transaction.">NdbTransaction::Commit</a> ) == -1) APIERROR(myTransaction-><a class="code" href="classNdbTransaction.html#f4af91ca21b97c4fe6256a18903020fc">getNdbError</a>()); myNdb.<a class="code" href="classNdb.html#afbf5620c516bf18e0a3d3bacaf38e67">closeTransaction</a>(myTransaction); } } <span class="comment">/*****************************************************************</span> <span class="comment"> * Update the second attribute in half of the tuples (adding 10) *</span> <span class="comment"> *****************************************************************/</span> <span class="keyword">static</span> <span class="keywordtype">void</span> do_update(<a class="code" href="classNdb.html" title="Represents the NDB kernel and is the main class of the NDB API.">Ndb</a> &myNdb) { <span class="keyword">const</span> <a class="code" href="classNdbDictionary_1_1Dictionary.html" title="Dictionary for defining and retreiving meta data.">NdbDictionary::Dictionary</a>* myDict= myNdb.<a class="code" href="classNdb.html#f27ca0f4e5c074211252a7c83060a3a4">getDictionary</a>(); <span class="keyword">const</span> <a class="code" href="classNdbDictionary_1_1Table.html" title="Represents a table in NDB Cluster.">NdbDictionary::Table</a> *myTable= myDict-><a class="code" href="classNdbDictionary_1_1Dictionary.html#1a30b1bb5fa164113cb839eed64eb3b6">getTable</a>(<span class="stringliteral">"MYTABLENAME"</span>); <span class="keywordflow">if</span> (myTable == NULL) APIERROR(myDict-><a class="code" href="classNdbDictionary_1_1Dictionary.html#0af68ea9b273172b46528ee1bd806f71">getNdbError</a>()); <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i < 10; i+=2) { <a class="code" href="classNdbTransaction.html" title="Represents a transaction.">NdbTransaction</a> *myTransaction= myNdb.<a class="code" href="classNdb.html#7e34bb5d8e3d878a54ebb7c0e6d0c5f1">startTransaction</a>(); <span class="keywordflow">if</span> (myTransaction == NULL) APIERROR(myNdb.<a class="code" href="classNdb.html#80b53a037bb2e93b3cd6830eda58643a">getNdbError</a>()); <a class="code" href="classNdbOperation.html" title="Class of operations for use in transactions.">NdbOperation</a> *myOperation= myTransaction-><a class="code" href="classNdbTransaction.html#2aeb211e54f84bd2de6cfb8fccec8166">getNdbOperation</a>(myTable); <span class="keywordflow">if</span> (myOperation == NULL) APIERROR(myTransaction-><a class="code" href="classNdbTransaction.html#f4af91ca21b97c4fe6256a18903020fc">getNdbError</a>()); myOperation->updateTuple(); myOperation->equal( <span class="stringliteral">"ATTR1"</span>, i ); myOperation->setValue( <span class="stringliteral">"ATTR2"</span>, i+10); <span class="keywordflow">if</span>( myTransaction-><a class="code" href="classNdbTransaction.html#361d5a82078f86a5d18923f56d43cc84">execute</a>( <a class="code" href="classNdbTransaction.html#2d2a5911b91e5cf78da970a1e97f7e3ecaba2931e541dd138044b61f38918391" title="Execute and try to commit the transaction.">NdbTransaction::Commit</a> ) == -1 ) APIERROR(myTransaction-><a class="code" href="classNdbTransaction.html#f4af91ca21b97c4fe6256a18903020fc">getNdbError</a>()); myNdb.<a class="code" href="classNdb.html#afbf5620c516bf18e0a3d3bacaf38e67">closeTransaction</a>(myTransaction); } } <span class="comment">/*************************************************</span> <span class="comment"> * Delete one tuple (the one with primary key 3) *</span> <span class="comment"> *************************************************/</span> <span class="keyword">static</span> <span class="keywordtype">void</span> do_delete(<a class="code" href="classNdb.html" title="Represents the NDB kernel and is the main class of the NDB API.">Ndb</a> &myNdb) { <span class="keyword">const</span> <a class="code" href="classNdbDictionary_1_1Dictionary.html" title="Dictionary for defining and retreiving meta data.">NdbDictionary::Dictionary</a>* myDict= myNdb.<a class="code" href="classNdb.html#f27ca0f4e5c074211252a7c83060a3a4">getDictionary</a>(); <span class="keyword">const</span> <a class="code" href="classNdbDictionary_1_1Table.html" title="Represents a table in NDB Cluster.">NdbDictionary::Table</a> *myTable= myDict-><a class="code" href="classNdbDictionary_1_1Dictionary.html#1a30b1bb5fa164113cb839eed64eb3b6">getTable</a>(<span class="stringliteral">"MYTABLENAME"</span>); <span class="keywordflow">if</span> (myTable == NULL) APIERROR(myDict-><a class="code" href="classNdbDictionary_1_1Dictionary.html#0af68ea9b273172b46528ee1bd806f71">getNdbError</a>()); <a class="code" href="classNdbTransaction.html" title="Represents a transaction.">NdbTransaction</a> *myTransaction= myNdb.<a class="code" href="classNdb.html#7e34bb5d8e3d878a54ebb7c0e6d0c5f1">startTransaction</a>(); <span class="keywordflow">if</span> (myTransaction == NULL) APIERROR(myNdb.<a class="code" href="classNdb.html#80b53a037bb2e93b3cd6830eda58643a">getNdbError</a>()); <a class="code" href="classNdbOperation.html" title="Class of operations for use in transactions.">NdbOperation</a> *myOperation= myTransaction->getNdbOperation(myTable); <span class="keywordflow">if</span> (myOperation == NULL) APIERROR(myTransaction->getNdbError()); myOperation->deleteTuple(); myOperation->equal( <span class="stringliteral">"ATTR1"</span>, 3 ); <span class="keywordflow">if</span> (myTransaction->execute(<a class="code" href="classNdbTransaction.html#2d2a5911b91e5cf78da970a1e97f7e3ecaba2931e541dd138044b61f38918391" title="Execute and try to commit the transaction.">NdbTransaction::Commit</a>) == -1) APIERROR(myTransaction->getNdbError()); myNdb.<a class="code" href="classNdb.html#afbf5620c516bf18e0a3d3bacaf38e67">closeTransaction</a>(myTransaction); } <span class="comment">/*****************************</span> <span class="comment"> * Read and print all tuples *</span> <span class="comment"> *****************************/</span> <span class="keyword">static</span> <span class="keywordtype">void</span> do_read(<a class="code" href="classNdb.html" title="Represents the NDB kernel and is the main class of the NDB API.">Ndb</a> &myNdb) { <span class="keyword">const</span> <a class="code" href="classNdbDictionary_1_1Dictionary.html" title="Dictionary for defining and retreiving meta data.">NdbDictionary::Dictionary</a>* myDict= myNdb.<a class="code" href="classNdb.html#f27ca0f4e5c074211252a7c83060a3a4">getDictionary</a>(); <span class="keyword">const</span> <a class="code" href="classNdbDictionary_1_1Table.html" title="Represents a table in NDB Cluster.">NdbDictionary::Table</a> *myTable= myDict-><a class="code" href="classNdbDictionary_1_1Dictionary.html#1a30b1bb5fa164113cb839eed64eb3b6">getTable</a>(<span class="stringliteral">"MYTABLENAME"</span>); <span class="keywordflow">if</span> (myTable == NULL) APIERROR(myDict-><a class="code" href="classNdbDictionary_1_1Dictionary.html#0af68ea9b273172b46528ee1bd806f71">getNdbError</a>()); std::cout << <span class="stringliteral">"ATTR1 ATTR2"</span> << std::endl; <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i < 10; i++) { <a class="code" href="classNdbTransaction.html" title="Represents a transaction.">NdbTransaction</a> *myTransaction= myNdb.<a class="code" href="classNdb.html#7e34bb5d8e3d878a54ebb7c0e6d0c5f1">startTransaction</a>(); <span class="keywordflow">if</span> (myTransaction == NULL) APIERROR(myNdb.<a class="code" href="classNdb.html#80b53a037bb2e93b3cd6830eda58643a">getNdbError</a>()); <a class="code" href="classNdbOperation.html" title="Class of operations for use in transactions.">NdbOperation</a> *myOperation= myTransaction-><a class="code" href="classNdbTransaction.html#2aeb211e54f84bd2de6cfb8fccec8166">getNdbOperation</a>(myTable); <span class="keywordflow">if</span> (myOperation == NULL) APIERROR(myTransaction-><a class="code" href="classNdbTransaction.html#f4af91ca21b97c4fe6256a18903020fc">getNdbError</a>()); myOperation->readTuple(<a class="code" href="classNdbOperation.html#bb62acf3797243787ce5814417f455103b3e1f6d331193a0ff6aeb4831435890" title="Read with shared lock.">NdbOperation::LM_Read</a>); myOperation->equal(<span class="stringliteral">"ATTR1"</span>, i); <a class="code" href="classNdbRecAttr.html" title="Contains value of an attribute.">NdbRecAttr</a> *myRecAttr= myOperation->getValue(<span class="stringliteral">"ATTR2"</span>, NULL); <span class="keywordflow">if</span> (myRecAttr == NULL) APIERROR(myTransaction-><a class="code" href="classNdbTransaction.html#f4af91ca21b97c4fe6256a18903020fc">getNdbError</a>()); <span class="keywordflow">if</span>(myTransaction-><a class="code" href="classNdbTransaction.html#361d5a82078f86a5d18923f56d43cc84">execute</a>( <a class="code" href="classNdbTransaction.html#2d2a5911b91e5cf78da970a1e97f7e3ecaba2931e541dd138044b61f38918391" title="Execute and try to commit the transaction.">NdbTransaction::Commit</a> ) == -1) <span class="keywordflow">if</span> (i == 3) { std::cout << <span class="stringliteral">"Detected that deleted tuple doesn't exist!"</span> << std::endl; } <span class="keywordflow">else</span> { APIERROR(myTransaction-><a class="code" href="classNdbTransaction.html#f4af91ca21b97c4fe6256a18903020fc">getNdbError</a>()); } <span class="keywordflow">if</span> (i != 3) { printf(<span class="stringliteral">" %2d %2d\n"</span>, i, myRecAttr-><a class="code" href="classNdbRecAttr.html#21767995531c0ff23f110d682bd7df67">u_32_value</a>()); } myNdb.<a class="code" href="classNdb.html#afbf5620c516bf18e0a3d3bacaf38e67">closeTransaction</a>(myTransaction); } } </pre></div> </div> <hr> <address> <small> <center> Documentation generated Sun Apr 20 06:25:31 2008 from mysql source files.<br> © 2003-2004 <a href="http://www.mysql.com">MySQL AB</a> <br> </center> </small></address> </body> </html>