Commit ddf645b1 authored by msvensson@shellback.(none)'s avatar msvensson@shellback.(none)
Browse files

Add SqlResultSet

parent 0d514c93
Loading
Loading
Loading
Loading
+56 −0
Original line number Diff line number Diff line
/* Copyright (C) 2003 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 of the License.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#ifndef ATRT_CLIENT_HPP
#define ATRT_CLIENT_HPP

#include <DbUtil.hpp>

class AtrtClient: public DbUtil {
public:

  enum AtrtCommandType {
    ATCT_CHANGE_VERSION= 1,
    ATCT_RESET_PROC= 2
  };

  AtrtClient(const char* _user= "root",
             const char* _password= "",
             const char* _suffix= ".1.atrt");
  AtrtClient(MYSQL*);
  ~AtrtClient();


  // Command functions
  bool changeVersion(int process_id, const char* process_args);
  bool resetProc(int process_id);

  // Query functions
  bool getConnectString(int cluster_id, SqlResultSet& result);
  bool getClusters(SqlResultSet& result);
  bool getMgmds(int cluster_id, SqlResultSet& result);
  bool getNdbds(int cluster_id, SqlResultSet& result);

private:
  int writeCommand(AtrtCommandType _type,
                   const Properties& args);
  bool readCommand(uint command_id,
                   SqlResultSet& result);

  bool doCommand(AtrtCommandType _type,
                 const Properties& args);
};

#endif
+71 −21
Original line number Diff line number Diff line
@@ -19,14 +19,11 @@
#ifndef DBUTIL_HPP
#define DBUTIL_HPP

#include <time.h>
#include <stdio.h>
#include <string.h>
#include <NDBT.hpp>
#include <BaseString.hpp>
#include <Properties.hpp>
#include <Vector.hpp>
#include <mysql.h>
//include "rand.h"
#include <stdlib.h>
#include "BaseString.hpp"
#include "NDBT.hpp"

//#define DEBUG
#define  DIE_UNLESS(expr) \
@@ -49,6 +46,41 @@ if (r) \
DIE_UNLESS(r == 0);\
}


class SqlResultSet : public Properties {
public:

  // Get row with number
  bool get_row(int row_num);
  // Load next row
  bool next(void);
  // Reset iterator
  void reset(void);
  // Remove current row from resultset
  void remove();

  SqlResultSet();
  ~SqlResultSet();

  const char* column(const char* col_name);
  uint columnAsInt(const char* col_name);

  uint insertId();
  uint affectedRows();
  uint numRows(void);
  uint mysqlErrno();
  const char* mysqlError();
  const char* mysqlSqlstate();

private:
  uint get_int(const char* name);
  const char* get_string(const char* name);

  const Properties* m_curr_row;
  uint m_curr_row_num;
};


#define DBU_FAILED 1
#define DBU_OK 0

@@ -56,11 +88,23 @@ class DbUtil
{
public:

  /* Deprecated, see DbUtil(dbname, suffix) */
  DbUtil(const char * databaseName);
  DbUtil(const char* dbname, const char* suffix = NULL);
  DbUtil(MYSQL* mysql);
  DbUtil(const char* dbname = "mysql",
         const char* user = "root",
         const char* pass = "",
         const char* suffix = NULL);
  ~DbUtil();

  bool doQuery(const char* query);
  bool doQuery(const char* query, SqlResultSet& result);
  bool doQuery(const char* query, const Properties& args, SqlResultSet& result);

  bool doQuery(BaseString& str);
  bool doQuery(BaseString& str, SqlResultSet& result);
  bool doQuery(BaseString& str, const Properties& args, SqlResultSet& result);

  bool waitConnected(int timeout);

  /* Deprecated, see connect() */
  void  databaseLogin(const char * system,
                      const char * usr,
@@ -74,25 +118,35 @@ public:
  const char * getPassword(){return m_pass.c_str();};
  const char * getHost()    {return m_host.c_str();};
  const char * getSocket()  {return m_socket.c_str();};
  const char * getServerType(){return mysql_get_server_info(mysql);};
  const char * getServerType(){return mysql_get_server_info(m_mysql);};
  const char * getError();

  MYSQL * getMysql(){return mysql;};
  MYSQL * getMysql(){return m_mysql;};
  MYSQL_STMT * STDCALL mysqlSimplePrepare(const char *query);

  void databaseLogout();
  void mysqlCloseStmHandle(MYSQL_STMT *my_stmt);

  int connect();
  void disconnect();
  int selectDb();
  int selectDb(const char *);
  int createDb(BaseString&);
  int doQuery(BaseString&);
  int doQuery(const char *);
  int getErrorNumber();

  unsigned long selectCountTable(const char * table);

protected:

  bool runQuery(const char* query,
               const Properties& args,
               SqlResultSet& rows);

  bool isConnected();

  MYSQL * m_mysql;
  bool m_free_mysql; /* Don't free mysql* if allocated elsewhere */

private:

  bool m_connected;
@@ -102,15 +156,11 @@ private:
  BaseString m_pass;       // MySQL User Password
  BaseString m_dbname;     // Database to use
  BaseString m_socket;     // MySQL Server Unix Socket
  BaseString default_file;
  BaseString default_group;
  BaseString m_default_file;
  BaseString m_default_group;

  unsigned int m_port;     // MySQL Server port

  MYSQL * mysql;
  MYSQL_RES * m_result;
  MYSQL_ROW m_row;

  void setDbName(const char * name){m_dbname.assign(name);};
  void setUser(const char * user_name){m_user.assign(user_name);};
  void setPassword(const char * password){m_pass.assign(password);};
+3 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ DbCreate DbAsyncGenerator \
testSRBank \
test_event_merge \
testIndexStat \
testNDBT \
NdbRepStress

EXTRA_PROGRAMS = \
@@ -99,6 +100,8 @@ ndbapi_slow_select_SOURCES = slow_select.cpp
testReadPerf_SOURCES = testReadPerf.cpp
testLcp_SOURCES = testLcp.cpp
testPartitioning_SOURCES = testPartitioning.cpp
testNDBT_SOURCES = testNDBT.cpp
testNDBT_LDADD = $(LDADD) $(top_srcdir)/libmysql_r/libmysqlclient_r.la
testBitfield_SOURCES = testBitfield.cpp
NdbRepStress_SOURCES = acrt/NdbRepStress.cpp
DbCreate_SOURCES = bench/mainPopulate.cpp bench/dbPopulate.cpp bench/userInterface.cpp bench/dbPopulate.h bench/userInterface.h bench/testData.h bench/testDefinitions.h bench/ndb_schema.hpp bench/ndb_error.hpp
+173 −0
Original line number Diff line number Diff line
/* Copyright (C) 2003 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 of the License.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#include <NDBT.hpp>
#include <NDBT_Test.hpp>
#include <DbUtil.hpp>
#include <AtrtClient.hpp>


int runTestAtrtClient(NDBT_Context* ctx, NDBT_Step* step){
  AtrtClient atrt;

  SqlResultSet clusters;
  if (!atrt.getClusters(clusters))
    return NDBT_FAILED;

  int i= 0;
  while(clusters.next())
  {
    ndbout << clusters.column("name") << endl;
    if (i++ == 1){
      ndbout << "removing: " << clusters.column("name") << endl;
      clusters.remove();
    }
  }

  clusters.reset();
  while(clusters.next())
  {
    ndbout << clusters.column("name") << endl;
  }

  return NDBT_OK;
}


int runTestDbUtil(NDBT_Context* ctx, NDBT_Step* step){
  DbUtil sql;

  {
    // Select all rows from mysql.user
    SqlResultSet result;
    if (!sql.doQuery("SELECT * FROM mysql.user", result))
      return NDBT_FAILED;
    // result.print();

    while(result.next())
    {
      ndbout << result.column("host") << ", "
             << result.column("uSer") << ", "
             << result.columnAsInt("max_updates") << ", "
             << endl;
    }

    result.reset();
    while(result.next())
    {
      ndbout << result.column("host") << endl;
    }
  }

  {
    // No column name, query should fail
    Properties args;
    SqlResultSet result;
    if (sql.doQuery("SELECT * FROM mysql.user WHERE name=?", args, result))
      return NDBT_FAILED;
    result.print();
  }

  {
    // Select nonexisiting rows from mysql.user
    Properties args;
    SqlResultSet result;
    args.put("0", "no_such_host");
    if (!sql.doQuery("SELECT * FROM mysql.user WHERE host=?", args, result))
      return NDBT_FAILED;
    ndbout << "no rows" << endl;
    result.print();

    // Change args to an find one row
    args.clear();
    args.put("0", "localhost");
    if (!sql.doQuery("SELECT host, user FROM mysql.user WHERE host=?",
                     args, result))
      return NDBT_FAILED;
    result.print();
  }

  {
    if (!sql.doQuery("CREATE TABLE sql_client_test (a int, b varchar(255))"))
      return NDBT_FAILED;

    if (!sql.doQuery("INSERT INTO sql_client_test VALUES(1, 'hello'), (2, 'bye')"))
      return NDBT_FAILED;

    // Select all rows from sql_client_test
    SqlResultSet result;
    if (!sql.doQuery("SELECT * FROM sql_client_test", result))
      return NDBT_FAILED;
    // result.print();

    while(result.next())
    {
    }

    // Select second row from sql_client_test
    Properties args;
    args.put("0", 2);
    if (!sql.doQuery("SELECT * FROM sql_client_test WHERE a=?", args,result))
      return NDBT_FAILED;
    result.print();

    result.reset();
    while(result.next())
    {
      ndbout << "a: " << result.columnAsInt("a") << endl;
        ndbout << "b: " << result.column("b") << endl;
      if (result.columnAsInt("a") != 2){
        ndbout << "hepp1" << endl;
        return NDBT_FAILED;
      }

      if (strcmp(result.column("b"), "bye")){
        ndbout << "hepp2" << endl;
        return NDBT_FAILED;
      }

    }

    if (sql.selectCountTable("sql_client_test") != 2)
    {
      ndbout << "Got wrong count" << endl;
      return NDBT_FAILED;
    }


    if (!sql.doQuery("DROP TABLE sql_client_test"))
      return NDBT_FAILED;

  }

  return NDBT_OK;
}

NDBT_TESTSUITE(testNDBT);
TESTCASE("AtrtClient",
	 "Test AtrtClient class"){
  INITIALIZER(runTestAtrtClient);
}
TESTCASE("DbUtil",
	 "Test DbUtil class"){
  INITIALIZER(runTestDbUtil);
}
NDBT_TESTSUITE_END(testNDBT);

int main(int argc, const char** argv){
  ndb_init();
  return testNDBT.execute(argc, argv);
}
+215 −0
Original line number Diff line number Diff line
/* Copyright (C) 2008 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 of the License.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#include <AtrtClient.hpp>
#include <NDBT_Output.hpp>
#include <NdbSleep.h>

AtrtClient::AtrtClient(const char* _user,
                       const char* _password,
                       const char* _group_suffix)
 : DbUtil(_user, _password, _group_suffix)
{
}


AtrtClient::AtrtClient(MYSQL* mysql)
  : DbUtil(mysql)
{
}


AtrtClient::~AtrtClient(){
}


int
AtrtClient::writeCommand(AtrtCommandType _type,
                         const Properties& args){
  if (!isConnected())
    return false;

  BaseString sql;
  sql.assfmt("INSERT  command ( ");

  const char* name;
  {
    Properties::Iterator iter(&args);
    while((name= iter.next())){
      sql.appfmt("%s, ", name);
    }
  }

  sql.appfmt(" state, cmd) VALUES (");

  {
    Properties::Iterator iter(&args);
    while((name= iter.next())){
      PropertiesType t;
      Uint32 val_i;
      BaseString val_s;
      args.getTypeOf(name, &t);
      switch(t) {
      case PropertiesType_Uint32:
        args.get(name, &val_i);
        sql.appfmt("%d, ", val_i);
        break;
      case PropertiesType_char:
        args.get(name, val_s);
        sql.appfmt("'%s', ", val_s.c_str());
        break;
      default:
        assert(false);
        break;
      }
    }
  }

  sql.appfmt("'new', %d)", _type);
  if (!doQuery(sql)){
    return -1;
  }

  return mysql_insert_id(m_mysql);
}


bool
AtrtClient::readCommand(uint command_id,
                        SqlResultSet& result){
  Properties args;
  args.put("0", command_id);
  return runQuery("SELECT * FROM command WHERE id = ?",
                  args,
                  result);
}


bool
AtrtClient::doCommand(AtrtCommandType type,
                      const Properties& args){

  int running_timeout= 10;
  int total_timeout= 120;
  int commandId= writeCommand(type,
                              args);
  if (commandId == -1){
    g_err << "Failed to write command" << endl;
    return false;
  }

  while (true){

    SqlResultSet result;
    if (!readCommand(commandId, result))
    {
      result.print();
      g_err << "Failed to read command "<< commandId << endl;
      return false;
    }

    // Get first row
    result.next();

    // Check if command has completed
    BaseString state(result.column("state"));
    if (state == "done") {
      return true;
    }

    if (state == "new"){
      if (!running_timeout--){
        g_err << "Timeout while waiting for command "
              << commandId << " to start run" << endl;
        return false;
      }
    }
    else if (!total_timeout--){
      g_err << "Timeout while waiting for result of command "
            << commandId << endl;
      return false;
    }


    NdbSleep_SecSleep(1);
  }

  return false;
}


bool
AtrtClient::changeVersion(int process_id,
                          const char* process_args){
  Properties args;
  args.put("process_id", process_id);
  args.put("process_args", process_args);
  return doCommand(ATCT_CHANGE_VERSION, args);
}


bool
AtrtClient::resetProc(int process_id){
  Properties args;
  args.put("process_id", process_id);
  return doCommand(ATCT_RESET_PROC, args);
}


bool
AtrtClient::getConnectString(int cluster_id, SqlResultSet& result){
  Properties args;
  args.put("0", cluster_id);
  return doQuery("SELECT value as connectstring " \
                 "FROM cluster c, process p, host h, options o "    \
                 "WHERE c.id=p.cluster_id AND p.host_id=h.id AND "  \
                 "p.id=o.process_id AND c.id=? AND "                    \
                 "o.name='--ndb-connectstring=' AND type='ndb_mgmd'",
                 args,
                 result);
}


bool
AtrtClient::getClusters(SqlResultSet& result){
  Properties args;
  return runQuery("SELECT id, name FROM cluster WHERE name != '.atrt'",
                  args,
                  result);
}


bool
AtrtClient::getMgmds(int cluster_id, SqlResultSet& result){
  Properties args;
  args.put("0", cluster_id);
  return runQuery("SELECT * FROM process WHERE cluster_id=? and type='ndb_mgmd'",
                  args,
                  result);
}

bool
AtrtClient::getNdbds(int cluster_id, SqlResultSet& result){
  Properties args;
  args.put("0", cluster_id);
  return runQuery("SELECT * FROM process WHERE cluster_id=? and type='ndbd'",
                  args,
                  result);
}




Loading