Commit d18541d9 authored by jmiller/ndbdev@mysql.com/ndb15.mysql.com's avatar jmiller/ndbdev@mysql.com/ndb15.mysql.com
Browse files

DbUtil.cpp:

  Rename: storage/ndb/test/src/dbutil.cpp -> storage/ndb/test/src/DbUtil.cpp
DbUtil.hpp, DbUtil.cpp:
  Many changes based off a review from Magnus
DbUtil.hpp:
  Rename: storage/ndb/test/include/dbutil.hpp -> storage/ndb/test/include/DbUtil.hpp
parent c9ecf312
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
set autocommit=1;
reset master;
create table bug16206 (a int);
insert into bug16206 values(1);
start transaction;
insert into bug16206 values(2);
commit;
show binlog events;
Log_name	Pos	Event_type	Server_id	End_log_pos	Info
f	n	Format_desc	1	n	Server ver: VERSION, Binlog ver: 4
f	n	Query	1	n	use `test`; create table bug16206 (a int)
f	n	Query	1	n	use `test`; insert into bug16206 values(1)
f	n	Query	1	n	use `test`; insert into bug16206 values(2)
drop table bug16206;
reset master;
create table bug16206 (a int) engine=         bdb;
insert into bug16206 values(0);
insert into bug16206 values(1);
start transaction;
insert into bug16206 values(2);
commit;
insert into bug16206 values(3);
show binlog events;
Log_name	Pos	Event_type	Server_id	End_log_pos	Info
f	n	Format_desc	1	n	Server ver: VERSION, Binlog ver: 4
f	n	Query	1	n	use `test`; create table bug16206 (a int) engine=         bdb
f	n	Query	1	n	use `test`; insert into bug16206 values(0)
f	n	Query	1	n	use `test`; insert into bug16206 values(1)
f	n	Query	1	n	use `test`; BEGIN
f	n	Query	1	n	use `test`; insert into bug16206 values(2)
f	n	Query	1	n	use `test`; COMMIT
f	n	Query	1	n	use `test`; insert into bug16206 values(3)
drop table bug16206;
set autocommit=0;
End of 5.0 tests
+38 −0
Original line number Diff line number Diff line
-- source include/not_embedded.inc
-- source include/have_bdb.inc

#
# Bug #16206: Superfluous COMMIT event in binlog when updating BDB in autocommit mode
#
set autocommit=1;

let $VERSION=`select version()`;

reset master;
create table bug16206 (a int);
insert into bug16206 values(1);
start transaction;
insert into bug16206 values(2);
commit;
--replace_result $VERSION VERSION
--replace_column 1 f 2 n 5 n
show binlog events;
drop table bug16206;

reset master;
create table bug16206 (a int) engine=         bdb;
insert into bug16206 values(0);
insert into bug16206 values(1);
start transaction;
insert into bug16206 values(2);
commit;
insert into bug16206 values(3);
--replace_result $VERSION VERSION
--replace_column 1 f 2 n 5 n
show binlog events;
drop table bug16206;

set autocommit=0;


--echo End of 5.0 tests
+129 −0
Original line number Diff line number Diff line
/* Copyright (C) 2007 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 */

// dbutil.h: interface for the database utilities class.
// Supplies a database to the test application

#ifndef DBUTIL_HPP
#define DBUTIL_HPP

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <mysql.h>
//include "rand.h"
#include <stdlib.h>
#include "BaseString.hpp"
#include "NDBT.hpp"

//#define DEBUG
#define  DIE_UNLESS(expr) \
           ((void) ((expr) ? 0 : (Die(__FILE__, __LINE__, #expr), 0)))
#define DIE(expr) \
          Die(__FILE__, __LINE__, #expr)
#define myerror(msg) printError(msg)
#define mysterror(stmt, msg) printStError(stmt, msg)
#define  CheckStmt(stmt) \
{ \
if ( stmt == 0) \
  myerror(NULL); \
DIE_UNLESS(stmt != 0); \
}

#define  check_execute(stmt, r) \
{ \
if (r) \
  mysterror(stmt, NULL); \
DIE_UNLESS(r == 0);\
}

#define DBU_TRUE 1
#define DBU_FALSE 0
#define DBU_FAILED 1
#define DBU_OK 0

class DbUtil
{
public:

  /* Deprecated, see DbUtil(dbname, suffix) */
  DbUtil(const char * databaseName);
  DbUtil(const char* dbname, const char* suffix = NULL);
  ~DbUtil();

  /* Deprecated, see connect() */
  void  databaseLogin(const char * system,
                      const char * usr,
                      const char * password,
                      unsigned int portIn,
                      const char * sockIn,
                      bool transactional);

  const char * getDbName()  {return m_dbname.c_str();};
  const char * getUser()    {return m_user.c_str();};
  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 * getError();

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

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

  int connect();
  int select_DB();
  int doQuery(char * stm);
  int doQuery(const char * stm);
  int getErrorNumber();

  unsigned long selectCountTable(const char * table);

private:

  bool m_connected;

  BaseString m_host;       // Computer to connect to
  BaseString m_user;       // MySQL User
  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;

  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);};
  void setHost(const char * system){m_host.assign(system);};
  void setPort(unsigned int portIn){m_port=portIn;};
  void setSocket(const char * sockIn){m_socket.assign(sockIn);};
  void printError(const char *msg);
  void printStError(MYSQL_STMT *stmt, const char *msg);
  void die(const char *file, int line, const char *expr); // stop program
  
};
#endif
+0 −97
Original line number Diff line number Diff line
// dbutil.h: interface for the database utilities class.
//////////////////////////////////////////////////////////////////////
// Supplies a database to the test application
//////////////////////////////////////////////////////////////////////

#ifndef DBUTIL_HPP
#define DBUTIL_HPP

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <mysql.h>
//include "rand.h"
#include <stdlib.h>

//#define DEBUG
#define  DIE_UNLESS(expr) \
           ((void) ((expr) ? 0 : (Die(__FILE__, __LINE__, #expr), 0)))
#define DIE(expr) \
          Die(__FILE__, __LINE__, #expr)
#define myerror(msg) PrintError(msg)
#define mysterror(stmt, msg) PrintStError(stmt, msg)
#define  CheckStmt(stmt) \
{ \
if ( stmt == 0) \
  myerror(NULL); \
DIE_UNLESS(stmt != 0); \
}

#define  check_execute(stmt, r) \
{ \
if (r) \
  mysterror(stmt, NULL); \
DIE_UNLESS(r == 0);\
}

#define TRUE 1
#define FALSE 0


class dbutil
{
public:

  dbutil(const char * databaseName);
  ~dbutil();

  void  DatabaseLogin(const char * system,
                      const char * usr,
                      const char * password,
                      unsigned int portIn,
                      const char * sockIn,
                      bool transactional);
  char * GetDbName(){return dbs;};
  char * GetUser(){return user;};
  char * GetPassword(){return pass;};
  char * GetHost(){return host;};
  char * GetSocket(){return socket;};
  const char * GetServerType(){return mysql_get_server_info(myDbHandel);};
  MYSQL* GetDbHandel(){return myDbHandel;};
  MYSQL_STMT *STDCALL MysqlSimplePrepare(const char *query);
  int Select_DB();
  int Do_Query(char * stm);
  const char * GetError();
  int GetErrorNumber();
  unsigned long SelectCountTable(const char * table);

private:

  //Connect variables
  char * databaseName; //hold results file name
  char host[256];                   // Computer to connect to
  char user[256];                   // MySQL User
  char pass[256];                   // MySQL User Password
  char dbs[256];                    // Database to use (TPCB)
  unsigned int port;               // MySQL Server port
  char socket[256];             // MySQL Server Unix Socket
  MYSQL  *myDbHandel;

  void DatabaseLogout();

  void SetDbName(const char * name){strcpy((char *)dbs, name);};
  void SetUser(const char * userName){strcpy((char *)user, userName);};
  void SetPassword(const char * password){strcpy((char *)pass,password);};
  void SetHost(const char * system){strcpy((char*)host, system);};
  void SetPort(unsigned int portIn){port=portIn;};
  void SetSocket(const char * sockIn){strcpy((char *)socket, sockIn);};
  void PrintError(const char *msg);
  void PrintStError(MYSQL_STMT *stmt, const char *msg);
  void Die(const char *file, int line, const char *expr); // stop program
  
};
#endif
+285 −0
Original line number Diff line number Diff line
/* Copyright (C) 2007 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 */

/* DbUtil.cpp: implementation of the database utilities class.*/

#include "DbUtil.hpp"

/* Constructors */

DbUtil::DbUtil(const char * dbname)
{
  m_port = 0;
  m_connected = false;
  this->setDbName(dbname);
}

DbUtil::DbUtil(const char * dbname, const char* suffix)
{
  this->setDbName(dbname);
  m_connected = false;

  const char* env= getenv("MYSQL_HOME");
  if (env && strlen(env))
  {
    default_file.assfmt("%s/my.cnf", env);
  }

  if (suffix != NULL){
    default_group.assfmt("client%s", suffix);
  }
  else {
    default_group.assign("client.1.master");
  }

  ndbout << "default_file: " << default_file.c_str() << endl;
  ndbout << "default_group: " << default_group.c_str() << endl;
}

/* Destructor*/

DbUtil::~DbUtil()
{
  this->databaseLogout();
}

/* Database Login */

void 
DbUtil::databaseLogin(const char* system, const char* usr,
                           const char* password, unsigned int portIn,
                           const char* sockIn, bool transactional)
{
  if (!(mysql = mysql_init(NULL)))
  {
    myerror("DB Login-> mysql_init() failed");
    exit(DBU_FAILED);
  }
  this->setUser(usr);
  this->setHost(system);
  this->setPassword(password);
  this->setPort(portIn);
  this->setSocket(sockIn);

  if (!(mysql_real_connect(mysql, 
                           m_host.c_str(), 
                           m_user.c_str(), 
                           m_pass.c_str(), 
                           "test", 
                           m_port, 
                           m_socket.c_str(), 0)))
  {
    myerror("connection failed");
    mysql_close(mysql);
    exit(DBU_FAILED);
  }

  mysql->reconnect = DBU_TRUE;

  /* set AUTOCOMMIT */
  if(!transactional)
    mysql_autocommit(mysql, DBU_TRUE);
  else
    mysql_autocommit(mysql, DBU_FALSE);

  #ifdef DEBUG
    printf("\n\tConnected to MySQL server version: %s (%lu)\n\n", 
           mysql_get_server_info(mysql),
           (unsigned long) mysql_get_server_version(mysql));
  #endif
}

/* Database Connect */

int 
DbUtil::connect()
{
  if (!(mysql = mysql_init(NULL)))
  {
    myerror("DB connect-> mysql_init() failed");
    return DBU_FAILED;
  }

  /* Load connection parameters file and group */
  if (mysql_options(mysql, MYSQL_READ_DEFAULT_FILE, default_file.c_str()) ||
      mysql_options(mysql, MYSQL_READ_DEFAULT_GROUP, default_group.c_str()))
  {
    myerror("DB Connect -> mysql_options failed");
    return DBU_FAILED;
  }

  /*
    Connect, read settings from my.cnf
    NOTE! user and password can be stored there as well
   */

  if (mysql_real_connect(mysql, NULL, "root","", m_dbname.c_str(), 
                         0, NULL, 0) == NULL)
  {
    myerror("connection failed");
    mysql_close(mysql);
    return DBU_FAILED;
  }

  m_connected = true;
  return DBU_OK;
}


/* Database Logout */

void 
DbUtil::databaseLogout()
{
  if (mysql){
    #ifdef DEBUG
      printf("\n\tClosing the MySQL database connection ...\n\n");
    #endif
    mysql_close(mysql);
  }
}

/* Prepare MySQL Statements Cont */

MYSQL_STMT *STDCALL 
DbUtil::mysqlSimplePrepare(const char *query)
{
  #ifdef DEBUG
    printf("Inside DbUtil::mysqlSimplePrepare\n");
  #endif
  int m_res = DBU_OK;

  MYSQL_STMT *my_stmt= mysql_stmt_init(this->getMysql());
  if (my_stmt && (m_res = mysql_stmt_prepare(my_stmt, query, strlen(query)))){
    this->printStError(my_stmt,"Prepare Statement Failed");
    mysql_stmt_close(my_stmt);
    exit(DBU_FAILED);
  }
  return my_stmt;
}

/* Close MySQL Statements Handle */

void 
DbUtil::mysqlCloseStmHandle(MYSQL_STMT *my_stmt)
{
  mysql_stmt_close(my_stmt);
}
 
/* Error Printing */

void 
DbUtil::printError(const char *msg)
{
  if (this->getMysql() && mysql_errno(this->getMysql()))
  {
    if (this->getMysql()->server_version)
      printf("\n [MySQL-%s]", this->getMysql()->server_version);
    else
      printf("\n [MySQL]");
      printf("[%d] %s\n", this->getErrorNumber(), this->getError());
  }
  else if (msg)
    printf(" [MySQL] %s\n", msg);
}

void 
DbUtil::printStError(MYSQL_STMT *stmt, const char *msg)
{
  if (stmt && mysql_stmt_errno(stmt))
  {
    if (this->getMysql() && this->getMysql()->server_version)
      printf("\n [MySQL-%s]", this->getMysql()->server_version);
    else
      printf("\n [MySQL]");

    printf("[%d] %s\n", mysql_stmt_errno(stmt),
    mysql_stmt_error(stmt));
  }
  else if (msg)
    printf("[MySQL] %s\n", msg);
}

/* Select which database to use */

int 
DbUtil::select_DB()
{
  return mysql_select_db(this->getMysql(), this->getDbName());
}

/* Run Simple Queries */

int 
DbUtil::doQuery(char * stm)
{
  return mysql_query(this->getMysql(), stm);
}

int 
DbUtil::doQuery(const char * stm)
{
  return mysql_query(this->getMysql(), stm);
}

/* Return MySQL Error String */

const char * 
DbUtil::getError()
{
  return mysql_error(this->getMysql());
}

/* Retrun MySQL Error Number */

int 
DbUtil::getErrorNumber()
{
  return mysql_errno(this->getMysql());
}

/* Count Table Rows */

unsigned long 
DbUtil::selectCountTable(const char * table)
{
  unsigned long m_count = 0;
  BaseString m_query;
       
  m_query.assfmt("select count(*) from %s", table);
  if (mysql_query(this->getMysql(),m_query.c_str()) || 
      !(m_result=mysql_store_result(this->getMysql())))
  {
    this->printError("selectCountTable\n");
    return DBU_FAILED;
  }
  m_row = mysql_fetch_row(m_result);
  m_count = (ulong) strtoull(m_row[0], (char**) 0, 10);
  mysql_free_result(m_result);
    
  return m_count;
}

/* DIE */

void 
DbUtil::die(const char *file, int line, const char *expr)
{
  printf("%s:%d: check failed: '%s'\n", file, line, expr);
  abort();
}

/* EOF */
Loading