/*
   Copyright 2009 Sun Microsystems, Inc.  All rights reserved.

   The MySQL Connector/C++ is licensed under the terms of the GPL
   <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
   MySQL Connectors. There are special exceptions to the terms and
   conditions of the GPL as it is applied to this software, see the
   FLOSS License Exception
   <http://www.mysql.com/about/legal/licensing/foss-exception.html>.
*/

#ifndef _MYSQL_LIBMYSQL_API_H_
#define _MYSQL_LIBMYSQL_API_H_

#include "mysql_private_iface.h"
#include <boost/shared_ptr.hpp>

namespace sql
{
class SQLString;

namespace mysql
{
namespace NativeAPI
{

typedef my_ulonglong (STDCALL *ptr2mysql_affected_rows)(MYSQL *);

typedef my_bool (STDCALL *ptr2mysql_autocommit)(MYSQL *, my_bool);

typedef void (STDCALL *ptr2mysql_close)(MYSQL *mysql);

typedef my_bool (STDCALL *ptr2mysql_commit)(MYSQL *mysql);

typedef void (STDCALL *ptr2mysql_data_seek)(MYSQL_RES *, my_ulonglong);

typedef void (STDCALL *ptr2mysql_debug)(const char *debug);

typedef unsigned int (STDCALL *ptr2mysql_errno)(MYSQL *mysql);

typedef const char * (STDCALL *ptr2mysql_error)(MYSQL *mysql);

typedef MYSQL_FIELD * (STDCALL *ptr2mysql_fetch_field)(MYSQL_RES *);

typedef MYSQL_FIELD * (STDCALL *ptr2mysql_fetch_field_direct)(MYSQL_RES *, unsigned int);

typedef unsigned long * (STDCALL *ptr2mysql_fetch_lengths)(MYSQL_RES *);

typedef MYSQL_ROW (STDCALL *ptr2mysql_fetch_row)(MYSQL_RES *);

typedef unsigned int (STDCALL *ptr2mysql_field_count)(MYSQL *);

typedef void (STDCALL *ptr2mysql_free_result)(MYSQL_RES *);

typedef unsigned long (STDCALL *ptr2mysql_get_client_version)();

typedef const char * (STDCALL *ptr2mysql_get_server_info)(MYSQL *);

typedef unsigned long (STDCALL *ptr2mysql_get_server_version)(MYSQL *);

typedef MYSQL * (STDCALL *ptr2mysql_init)(MYSQL *mysql);

typedef int (STDCALL *ptr2mysql_library_init)(int, char **, char **);

typedef void (STDCALL *ptr2mysql_library_end)(void);

typedef my_bool (STDCALL *ptr2mysql_more_results)(MYSQL *);

typedef int (STDCALL *ptr2mysql_next_result)(MYSQL *);

typedef unsigned int (STDCALL *ptr2mysql_num_fields)(MYSQL_RES *);

typedef my_ulonglong (STDCALL *ptr2mysql_num_rows)(MYSQL_RES *);

typedef int (STDCALL *ptr2mysql_options)(MYSQL *, enum mysql_option, const void *);

typedef int (STDCALL *ptr2mysql_query)(MYSQL *, const char *);

typedef MYSQL * (STDCALL *ptr2mysql_real_connect)(MYSQL *, const char *, const char *, const char * , const char *, unsigned int, const char *, unsigned long);

typedef int (STDCALL *ptr2mysql_real_query)(MYSQL *, const char *, unsigned long);

typedef my_bool (STDCALL *ptr2mysql_rollback)(MYSQL *mysql);

typedef const char * (STDCALL *ptr2mysql_sqlstate)(MYSQL *mysql);

typedef my_bool (STDCALL *ptr2mysql_ssl_set)(MYSQL *, const char *, const char *, const char *, const char *, const char *);

typedef MYSQL_RES * (STDCALL *ptr2mysql_store_result)(MYSQL *);

typedef MYSQL_RES * (STDCALL *ptr2mysql_use_result)(MYSQL *);

/* Prepared Statement stmt_* functions */
typedef my_ulonglong (STDCALL *ptr2mysql_stmt_affected_rows)(MYSQL_STMT *);

typedef my_bool (STDCALL *ptr2mysql_stmt_attr_set)(MYSQL_STMT *, enum enum_stmt_attr_type, const void *);

typedef my_bool (STDCALL *ptr2mysql_stmt_bind_param)(MYSQL_STMT *, MYSQL_BIND *);

typedef my_bool (STDCALL *ptr2mysql_stmt_bind_result)(MYSQL_STMT *, MYSQL_BIND *);

typedef my_bool (STDCALL *ptr2mysql_stmt_close)(MYSQL_STMT *);

typedef void (STDCALL *ptr2mysql_stmt_data_seek)(MYSQL_STMT *, my_ulonglong);

typedef unsigned int (STDCALL *ptr2mysql_stmt_errno)(MYSQL_STMT *);

typedef const char * (STDCALL *ptr2mysql_stmt_error)(MYSQL_STMT *);

typedef int (STDCALL *ptr2mysql_stmt_execute)(MYSQL_STMT *);

typedef int (STDCALL *ptr2mysql_stmt_fetch)(MYSQL_STMT *);

typedef unsigned int (STDCALL *ptr2mysql_stmt_field_count)(MYSQL_STMT *);

typedef MYSQL_STMT * (STDCALL *ptr2mysql_stmt_init)(MYSQL *);

typedef my_ulonglong (STDCALL *ptr2mysql_stmt_num_rows)(MYSQL_STMT *);

typedef unsigned long (STDCALL *ptr2mysql_stmt_param_count)(MYSQL_STMT *);

typedef int (STDCALL *ptr2mysql_stmt_prepare)(MYSQL_STMT *, const char *, unsigned long);

typedef MYSQL_RES * (STDCALL *ptr2mysql_stmt_result_metadata)(MYSQL_STMT *);

typedef my_bool (STDCALL *ptr2mysql_stmt_send_long_data)(MYSQL_STMT *, unsigned int, const char *, unsigned long);

typedef const char * (STDCALL *ptr2mysql_stmt_sqlstate)(MYSQL_STMT *);

typedef int (STDCALL *ptr2mysql_stmt_store_result)(MYSQL_STMT *);


/*
 * Interface MySQL C-API wrapper class should implement.
 * At the moment we must have at least 2 implementation - for static and dynamic
 * mysql client library linking
 */
class IMySQLCAPI
{
public:
	virtual my_ulonglong affected_rows(MYSQL *) = 0;

	virtual my_bool autocommit(MYSQL *, my_bool) = 0;

	virtual void close(MYSQL *mysql) = 0;

	virtual my_bool commit(MYSQL *mysql) = 0;

	virtual void data_seek(MYSQL_RES *, my_ulonglong) = 0;

	virtual void debug(const char *) = 0;

	virtual unsigned int mysql_errno(MYSQL *mysql) = 0;

	virtual const char * error(MYSQL *mysql) = 0;

	virtual MYSQL_FIELD * fetch_field(MYSQL_RES *) = 0;

	virtual MYSQL_FIELD * fetch_field_direct (MYSQL_RES *, unsigned int) = 0;

	virtual unsigned long * fetch_lengths(MYSQL_RES * ) = 0;

	virtual MYSQL_ROW fetch_row(MYSQL_RES * ) = 0;

	virtual unsigned int field_count(MYSQL *) = 0;

	virtual void free_result(MYSQL_RES * ) = 0;

	virtual unsigned long get_client_version() = 0;

	virtual const char * get_server_info(MYSQL *) = 0;

	virtual unsigned long get_server_version(MYSQL *) = 0;

	virtual MYSQL * init(MYSQL *mysql) = 0;

	virtual int library_init(int argc, char **argv, char **groups) = 0;

	virtual void library_end() = 0;

	virtual my_bool more_results(MYSQL *) = 0;

	virtual int next_result(MYSQL *) = 0;

	virtual unsigned int num_fields(MYSQL_RES * ) = 0;

	virtual my_ulonglong num_rows(MYSQL_RES * ) = 0;

	virtual int options(MYSQL *, enum mysql_option option , const void *arg) = 0;

	virtual int query(MYSQL *, const char *) = 0;

	virtual MYSQL * real_connect(MYSQL * mysql,
								const char *  host,
								const char *  user,
								const char *  passwd,
								const char *  db,
								unsigned int  port,
								const char *  unix_socket,
								unsigned long client_flag) = 0;

	virtual int real_query(MYSQL *
									 , const char *
									 , unsigned long) = 0;

	virtual my_bool rollback(MYSQL *) = 0;

	virtual const char * sqlstate(MYSQL *) = 0;

	virtual my_bool ssl_set(MYSQL * mysql,
							const char * key,
							const char * cert,
							const char * ca,
							const char * capath,
							const char * cipher) = 0;

	virtual MYSQL_RES * store_result(MYSQL *) = 0;

	virtual MYSQL_RES * use_result(MYSQL *) = 0;

	/* Methods - wrappers of prepared statement stmt_* functions */
	virtual my_ulonglong  stmt_affected_rows (MYSQL_STMT *) = 0;

	virtual my_bool stmt_attr_set(MYSQL_STMT *stmt, enum enum_stmt_attr_type option , const void *arg) = 0;

	virtual my_bool stmt_bind_param(MYSQL_STMT *, MYSQL_BIND *) = 0;

	virtual my_bool stmt_bind_result(MYSQL_STMT *, MYSQL_BIND *) = 0;

	virtual my_bool stmt_close(MYSQL_STMT *) = 0;

	virtual void stmt_data_seek(MYSQL_STMT *, my_ulonglong) = 0;

	virtual unsigned int stmt_errno(MYSQL_STMT *) = 0;

	virtual const char * stmt_error(MYSQL_STMT *) = 0;

	virtual int stmt_execute(MYSQL_STMT *) = 0;

	virtual int stmt_fetch(MYSQL_STMT *) = 0;

	virtual unsigned int stmt_field_count(MYSQL_STMT *) = 0;

	virtual MYSQL_STMT * stmt_init(MYSQL *) = 0;

	virtual my_ulonglong stmt_num_rows(MYSQL_STMT *) = 0;

	virtual unsigned long stmt_param_count(MYSQL_STMT *) = 0;

	virtual int stmt_prepare(MYSQL_STMT *, const char *, unsigned long) = 0;

	virtual MYSQL_RES * stmt_result_metadata(MYSQL_STMT *) = 0;

	virtual my_bool stmt_send_long_data(MYSQL_STMT * stmt , unsigned int par_number, const char * data, unsigned long len) = 0;

	virtual const char *  stmt_sqlstate(MYSQL_STMT *) = 0;

	virtual int stmt_store_result(MYSQL_STMT *) = 0;
};

boost::shared_ptr<IMySQLCAPI> getCApiHandle(const sql::SQLString & name);

} /* namespace NativeAPI */
} /* namespace mysql */
} /* namespace sql*/

#endif

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
