You've already forked mariadb-connector-c
mirror of
https://github.com/mariadb-corporation/mariadb-connector-c.git
synced 2025-08-07 02:42:49 +03:00
Merge remote-tracking branch 'origin/master' into cio
Conflicts: CMakeLists.txt include/mysql/client_plugin.h libmariadb/client_plugin.c.in libmariadb/libmariadb.c libmariadb/ma_secure.c libmariadb/my_malloc.c libmariadb/net.c plugins/io/CMakeLists.txt unittest/libmariadb/misc.c
This commit is contained in:
@@ -4,8 +4,8 @@
|
|||||||
# This is the LGPL libmariadb project.
|
# This is the LGPL libmariadb project.
|
||||||
PROJECT(mariadb-connector-c C)
|
PROJECT(mariadb-connector-c C)
|
||||||
|
|
||||||
SET(CPACK_PACKAGE_VERSION_MAJOR 3)
|
SET(CPACK_PACKAGE_VERSION_MAJOR 2)
|
||||||
SET(CPACK_PACKAGE_VERSION_MINOR 0)
|
SET(CPACK_PACKAGE_VERSION_MINOR 2)
|
||||||
SET(CPACK_PACKAGE_VERSION_PATCH 0)
|
SET(CPACK_PACKAGE_VERSION_PATCH 0)
|
||||||
SET(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
|
SET(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
|
||||||
|
|
||||||
@@ -26,6 +26,7 @@ ELSE()
|
|||||||
OPTION(WITH_SIGNCODE "digitally sign files" OFF)
|
OPTION(WITH_SIGNCODE "digitally sign files" OFF)
|
||||||
OPTION(WITH_RTC "enables run time checks for debug builds" OFF)
|
OPTION(WITH_RTC "enables run time checks for debug builds" OFF)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
OPTION(WITH_REMOTEIO "enables remote io support (requires libcurl)" OFF)
|
||||||
|
|
||||||
OPTION(WITH_EXTERNAL_ZLIB "Enables use of external zlib" OFF)
|
OPTION(WITH_EXTERNAL_ZLIB "Enables use of external zlib" OFF)
|
||||||
###############
|
###############
|
||||||
@@ -204,15 +205,18 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/include)
|
|||||||
IF(WIN32)
|
IF(WIN32)
|
||||||
SET(SYSTEM_LIBS ws2_32 advapi32 kernel32)
|
SET(SYSTEM_LIBS ws2_32 advapi32 kernel32)
|
||||||
ELSE()
|
ELSE()
|
||||||
SET(SYSTEM_LIBS ${LIBPTHREAD} ${LIBDL} ${LIBM} ${LIBICONV})
|
SET(SYSTEM_LIBS ${LIBPTHREAD} ${LIBDL} ${LIBM})
|
||||||
|
IF(ICONV_EXTERNAL)
|
||||||
|
SET(SYSTEM_LIBS ${SYSTEM_LIBS} ${ICONV_LIBRARIES})
|
||||||
|
ENDIF()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
IF(WITH_SSL)
|
IF(WITH_SSL)
|
||||||
SET(SYSTEM_LIBS ${SYSTEM_LIBS} ${SSL_LIBRARIES})
|
SET(SYSTEM_LIBS ${SYSTEM_LIBS} ${SSL_LIBRARIES})
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
ADD_SUBDIRECTORY(include)
|
ADD_SUBDIRECTORY(include)
|
||||||
ADD_SUBDIRECTORY(plugins)
|
|
||||||
ADD_SUBDIRECTORY(libmariadb)
|
ADD_SUBDIRECTORY(libmariadb)
|
||||||
|
ADD_SUBDIRECTORY(plugins)
|
||||||
IF(NOT WIN32)
|
IF(NOT WIN32)
|
||||||
ADD_SUBDIRECTORY(mariadb_config)
|
ADD_SUBDIRECTORY(mariadb_config)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
@@ -246,35 +250,29 @@ INCLUDE(cmake/ConnectorName.cmake)
|
|||||||
SET(CPACK_SOURCE_PACKAGE_FILE_NAME "mariadb-connector-c-${CPACK_PACKAGE_VERSION}-src")
|
SET(CPACK_SOURCE_PACKAGE_FILE_NAME "mariadb-connector-c-${CPACK_PACKAGE_VERSION}-src")
|
||||||
|
|
||||||
SET(CPACK_SOURCE_IGNORE_FILES
|
SET(CPACK_SOURCE_IGNORE_FILES
|
||||||
.bzr/
|
\\\\.git/
|
||||||
.bzrignore
|
\\\\.gitignore
|
||||||
CMakeCache.txt
|
CMakeCache\\\\.txt
|
||||||
cmake_dist.cmake
|
cmake_dist\\\\.cmake
|
||||||
CPackSourceConfig.cmake
|
CPackConfig\\\\.cmake
|
||||||
CPackConfig.cmake
|
mariadb_config/mariadb_config\\\\.c$
|
||||||
mariadb_config/mariadb_config.c$
|
\\\\.build/
|
||||||
.build/
|
|
||||||
html/
|
html/
|
||||||
unittest
|
unittest
|
||||||
/cmake_install.cmake
|
/cmake_install.cmake
|
||||||
/CTestTestfile.cmake
|
/CTestTestfile.cmake
|
||||||
|
/CPackSourceConfig.cmake
|
||||||
/CMakeFiles/
|
/CMakeFiles/
|
||||||
/version_resources/
|
/version_resources/
|
||||||
/_CPack_Packages/
|
/_CPack_Packages/
|
||||||
.*gz$
|
\\\\.gz$
|
||||||
.*zip$
|
\\\\.zip$
|
||||||
.*so$
|
mariadb_config/mariadb_config
|
||||||
.*so.*$
|
|
||||||
.*dll$
|
|
||||||
.*a$
|
|
||||||
.*pdb$
|
|
||||||
/CMakeFiles/
|
/CMakeFiles/
|
||||||
/version_resources/
|
/version_resources/
|
||||||
/_CPack_Packages/
|
/_CPack_Packages/
|
||||||
Makefile$
|
Makefile$
|
||||||
include/my_config.h$
|
include/my_config\\\\.h$
|
||||||
/autom4te.cache/
|
|
||||||
errmsg.sys$
|
|
||||||
)
|
)
|
||||||
|
|
||||||
IF(WIN32)
|
IF(WIN32)
|
||||||
|
@@ -19,6 +19,7 @@ IF(APPLE)
|
|||||||
/opt/local/lib/
|
/opt/local/lib/
|
||||||
/usr/lib/
|
/usr/lib/
|
||||||
NO_CMAKE_SYSTEM_PATH)
|
NO_CMAKE_SYSTEM_PATH)
|
||||||
|
SET(ICONV_EXTERNAL TRUE)
|
||||||
ELSE()
|
ELSE()
|
||||||
find_library(ICONV_LIBRARIES NAMES iconv libiconv libiconv-2)
|
find_library(ICONV_LIBRARIES NAMES iconv libiconv libiconv-2)
|
||||||
IF(ICONV_LIBRARIES)
|
IF(ICONV_LIBRARIES)
|
||||||
|
30
cmake/symlink.cmake
Normal file
30
cmake/symlink.cmake
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
MACRO(create_symlink symlink_name target install_path)
|
||||||
|
# According to cmake documentation symlinks work on unix systems only
|
||||||
|
IF(UNIX)
|
||||||
|
# Get target components
|
||||||
|
GET_TARGET_PROPERTY(target_location ${target} LOCATION)
|
||||||
|
GET_FILENAME_COMPONENT(target_path ${target_location} PATH)
|
||||||
|
GET_FILENAME_COMPONENT(target_name ${target_location} NAME)
|
||||||
|
|
||||||
|
ADD_CUSTOM_COMMAND(
|
||||||
|
OUTPUT ${target_path}/${symlink_name}
|
||||||
|
COMMAND ${CMAKE_COMMAND} ARGS -E remove -f ${target_path}/${symlink_name}
|
||||||
|
COMMAND ${CMAKE_COMMAND} ARGS -E create_symlink ${target_name} ${symlink_name}
|
||||||
|
WORKING_DIRECTORY ${target_path}
|
||||||
|
DEPENDS ${target}
|
||||||
|
)
|
||||||
|
|
||||||
|
ADD_CUSTOM_TARGET(SYM_${symlink_name}
|
||||||
|
ALL
|
||||||
|
DEPENDS ${target_path}/${symlink_name})
|
||||||
|
SET_TARGET_PROPERTIES(SYM_${symlink_name} PROPERTIES CLEAN_DIRECT_OUTPUT 1)
|
||||||
|
|
||||||
|
IF(CMAKE_GENERATOR MATCHES "Xcode")
|
||||||
|
# For Xcode, replace project config with install config
|
||||||
|
STRING(REPLACE "${CMAKE_CFG_INTDIR}"
|
||||||
|
"\${CMAKE_INSTALL_CONFIG_NAME}" output ${target_path}/${symlink_name})
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
INSTALL(FILES ${target_path}/${symlink_name} DESTINATION ${install_path})
|
||||||
|
ENDIF()
|
||||||
|
ENDMACRO()
|
@@ -18,6 +18,7 @@
|
|||||||
#ifndef _ma_io_h_
|
#ifndef _ma_io_h_
|
||||||
#define _ma_io_h_
|
#define _ma_io_h_
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_CURL
|
#ifdef HAVE_CURL
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -34,6 +35,7 @@ typedef struct
|
|||||||
void *ptr;
|
void *ptr;
|
||||||
} MA_FILE;
|
} MA_FILE;
|
||||||
|
|
||||||
|
#ifdef HAVE_REMOTEIO
|
||||||
struct st_rio_methods {
|
struct st_rio_methods {
|
||||||
MA_FILE *(*open)(const char *url, const char *mode);
|
MA_FILE *(*open)(const char *url, const char *mode);
|
||||||
int (*close)(MA_FILE *ptr);
|
int (*close)(MA_FILE *ptr);
|
||||||
@@ -41,6 +43,7 @@ struct st_rio_methods {
|
|||||||
size_t (*read)(void *ptr, size_t size, size_t nmemb, MA_FILE *file);
|
size_t (*read)(void *ptr, size_t size, size_t nmemb, MA_FILE *file);
|
||||||
char * (*gets)(char *ptr, size_t size, MA_FILE *file);
|
char * (*gets)(char *ptr, size_t size, MA_FILE *file);
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
/* function prototypes */
|
/* function prototypes */
|
||||||
MA_FILE *ma_open(const char *location, const char *mode, MYSQL *mysql);
|
MA_FILE *ma_open(const char *location, const char *mode, MYSQL *mysql);
|
||||||
|
@@ -454,7 +454,7 @@ typedef SOCKET_SIZE_TYPE size_socket;
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define NO_DIR_LIBRARY /* Not standar dir-library */
|
#define NO_DIR_LIBRARY /* Not standar dir-library */
|
||||||
#define USE_MY_STAT_STRUCT /* For my_lib */
|
#define USE_MY_STAT_STRUCT /* For my_lib */
|
||||||
#ifdef _SIZE_T_DEFINED
|
#ifdef _MSC_VER
|
||||||
typedef SSIZE_T ssize_t;
|
typedef SSIZE_T ssize_t;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@@ -144,6 +144,7 @@ typedef char *(*mysql_authentication_dialog_ask_t)(struct st_mysql *mysql,
|
|||||||
int type, const char *prompt, char *buf, int buf_len);
|
int type, const char *prompt, char *buf, int buf_len);
|
||||||
|
|
||||||
/********************** remote IO plugin **********************/
|
/********************** remote IO plugin **********************/
|
||||||
|
#ifdef HAVE_REMOTEIO
|
||||||
#include <mariadb/ma_io.h>
|
#include <mariadb/ma_io.h>
|
||||||
|
|
||||||
/* Remote IO plugin */
|
/* Remote IO plugin */
|
||||||
@@ -152,6 +153,7 @@ struct st_mysql_client_plugin_REMOTEIO
|
|||||||
MYSQL_CLIENT_PLUGIN_HEADER
|
MYSQL_CLIENT_PLUGIN_HEADER
|
||||||
struct st_rio_methods *methods;
|
struct st_rio_methods *methods;
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
/******** using plugins ************/
|
/******** using plugins ************/
|
||||||
|
|
||||||
|
@@ -224,6 +224,12 @@ IF(WITH_SSL)
|
|||||||
SET(EXPORTS ${EXPORTS} mariadb_deinitialize_ssl)
|
SET(EXPORTS ${EXPORTS} mariadb_deinitialize_ssl)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
# some gcc versions fail to compile asm parts of my_context.c,
|
||||||
|
# if build type is "Release" (see CONC-133), so we need to add -g flag
|
||||||
|
IF(CMAKE_COMPILER_IS_GNUCC AND CMAKE_BUILD_TYPE MATCHES "Release")
|
||||||
|
SET_SOURCE_FILES_PROPERTIES(my_context.c PROPERTIES COMPILE_FLAGS -g)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
IF(WIN32)
|
IF(WIN32)
|
||||||
SET(EXPORT_CONTENT "EXPORTS\n")
|
SET(EXPORT_CONTENT "EXPORTS\n")
|
||||||
FOREACH(SYMBOL ${EXPORT_SYMBOLS})
|
FOREACH(SYMBOL ${EXPORT_SYMBOLS})
|
||||||
@@ -366,10 +372,17 @@ IF(UNIX)
|
|||||||
SET_TARGET_PROPERTIES(mariadb_obj PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS}")
|
SET_TARGET_PROPERTIES(mariadb_obj PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS}")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
ADD_LIBRARY(mariadbclient STATIC $<TARGET_OBJECTS:mariadb_obj> ${EXPORT_LINK})
|
# Xcode doesn't support targets that have only object files,
|
||||||
|
# so let's add an empty file to keep Xcode happy
|
||||||
|
IF(CMAKE_GENERATOR MATCHES Xcode)
|
||||||
|
FILE(WRITE ${CMAKE_SOURCE_DIR}/libmariadb/empty.c "")
|
||||||
|
SET(EMPTY_FILE ${CMAKE_SOURCE_DIR}/libmariadb/empty.c)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
ADD_LIBRARY(mariadbclient STATIC $<TARGET_OBJECTS:mariadb_obj> ${EMPTY_FILE} ${EXPORT_LINK})
|
||||||
TARGET_LINK_LIBRARIES(mariadbclient ${SYSTEM_LIBS})
|
TARGET_LINK_LIBRARIES(mariadbclient ${SYSTEM_LIBS})
|
||||||
|
|
||||||
ADD_LIBRARY(libmariadb SHARED $<TARGET_OBJECTS:mariadb_obj> ${EXPORT_LINK})
|
ADD_LIBRARY(libmariadb SHARED $<TARGET_OBJECTS:mariadb_obj> ${EMPTY_FILE} ${EXPORT_LINK})
|
||||||
TARGET_LINK_LIBRARIES(libmariadb ${SYSTEM_LIBS})
|
TARGET_LINK_LIBRARIES(libmariadb ${SYSTEM_LIBS})
|
||||||
IF(UNIX)
|
IF(UNIX)
|
||||||
SET_TARGET_PROPERTIES(libmariadb PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS}")
|
SET_TARGET_PROPERTIES(libmariadb PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS}")
|
||||||
@@ -391,33 +404,18 @@ SET_TARGET_PROPERTIES(libmariadb PROPERTIES VERSION
|
|||||||
#
|
#
|
||||||
# Installation
|
# Installation
|
||||||
#
|
#
|
||||||
|
INCLUDE(${CMAKE_SOURCE_DIR}/cmake/symlink.cmake)
|
||||||
|
|
||||||
|
|
||||||
# There are still several projects which don't make use
|
# There are still several projects which don't make use
|
||||||
# of the config program. To make sure these programs can
|
# of the config program. To make sure these programs can
|
||||||
# use mariadb client library we provide libmysql symlinks
|
# use mariadb client library we provide libmysql symlinks
|
||||||
IF(NOT WIN32 AND WITH_MYSQLCOMPAT)
|
IF(NOT WIN32 AND WITH_MYSQLCOMPAT)
|
||||||
ADD_CUSTOM_COMMAND(OUTPUT "libmysql${CMAKE_SHARED_LIBRARY_SUFFIX}"
|
SET(INSTALL_PATH ${LIB_INSTALL_DIR}/${SUFFIX_INSTALL_DIR})
|
||||||
"libmysqlclient${CMAKE_SHARED_LIBRARY_SUFFIX}"
|
create_symlink(libmysqlclient${CMAKE_SHARED_LIBRARY_SUFFIX} libmariadb ${INSTALL_PATH})
|
||||||
"libmysqlclient_r${CMAKE_SHARED_LIBRARY_SUFFIX}"
|
create_symlink(libmysqlclient_r${CMAKE_SHARED_LIBRARY_SUFFIX} libmariadb ${INSTALL_PATH})
|
||||||
"libmysqlclient${CMAKE_STATIC_LIBRARY_SUFFIX}"
|
create_symlink(libmysqlclient${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_PATH})
|
||||||
COMMAND ${CMAKE_COMMAND} ARGS -E remove -f libmysql${CMAKE_SHARED_LIBRARY_SUFFIX}
|
create_symlink(libmysqlclient_r${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_PATH})
|
||||||
COMMAND ${CMAKE_COMMAND} ARGS -E create_symlink libmariadb${CMAKE_SHARED_LIBRARY_SUFFIX} libmysql${CMAKE_SHARED_LIBRARY_SUFFIX}
|
|
||||||
COMMAND ${CMAKE_COMMAND} ARGS -E remove -f libmysqlclient_r${CMAKE_SHARED_LIBRARY_SUFFIX}
|
|
||||||
COMMAND ${CMAKE_COMMAND} ARGS -E create_symlink libmariadb${CMAKE_SHARED_LIBRARY_SUFFIX} libmysqlclient_r${CMAKE_SHARED_LIBRARY_SUFFIX}
|
|
||||||
COMMAND ${CMAKE_COMMAND} ARGS -E remove -f libmysqlclient${CMAKE_SHARED_LIBRARY_SUFFIX}
|
|
||||||
COMMAND ${CMAKE_COMMAND} ARGS -E create_symlink libmariadb${CMAKE_SHARED_LIBRARY_SUFFIX} libmysqlclient${CMAKE_SHARED_LIBRARY_SUFFIX}
|
|
||||||
COMMAND ${CMAKE_COMMAND} ARGS -E remove -f libmysqlclient${CMAKE_STATIC_LIBRARY_SUFFIX}
|
|
||||||
COMMAND ${CMAKE_COMMAND} ARGS -E create_symlink libmariadbclient${CMAKE_STATIC_LIBRARY_SUFFIX} libmysqlclient${CMAKE_STATIC_LIBRARY_SUFFIX}
|
|
||||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/libmariadb
|
|
||||||
DEPENDS libmariadb mariadbclient)
|
|
||||||
|
|
||||||
ADD_CUSTOM_TARGET(LIBMYSQL_SYMLINKS
|
|
||||||
ALL
|
|
||||||
DEPENDS "libmysql${CMAKE_SHARED_LIBRARY_SUFFIX}"
|
|
||||||
"libmysqlclient_r${CMAKE_SHARED_LIBRARY_SUFFIX}"
|
|
||||||
"libmysqlclient${CMAKE_SHARED_LIBRARY_SUFFIX}"
|
|
||||||
"libmysqlclient${CMAKE_STATIC_LIBRARY_SUFFIX}"
|
|
||||||
VERBATIM)
|
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
|
||||||
@@ -427,14 +425,6 @@ INSTALL(TARGETS
|
|||||||
LIBRARY DESTINATION "${LIB_INSTALL_DIR}/${SUFFIX_INSTALL_DIR}"
|
LIBRARY DESTINATION "${LIB_INSTALL_DIR}/${SUFFIX_INSTALL_DIR}"
|
||||||
ARCHIVE DESTINATION "${LIB_INSTALL_DIR}/${SUFFIX_INSTALL_DIR}")
|
ARCHIVE DESTINATION "${LIB_INSTALL_DIR}/${SUFFIX_INSTALL_DIR}")
|
||||||
|
|
||||||
IF(NOT WIN32 AND WITH_MYSQLCOMPAT)
|
|
||||||
INSTALL(FILES "${CMAKE_BINARY_DIR}/libmariadb/libmysql${CMAKE_SHARED_LIBRARY_SUFFIX}"
|
|
||||||
"${CMAKE_BINARY_DIR}/libmariadb/libmysqlclient${CMAKE_SHARED_LIBRARY_SUFFIX}"
|
|
||||||
"${CMAKE_BINARY_DIR}/libmariadb/libmysqlclient_r${CMAKE_SHARED_LIBRARY_SUFFIX}"
|
|
||||||
"${CMAKE_BINARY_DIR}/libmariadb/libmysqlclient${CMAKE_STATIC_LIBRARY_SUFFIX}"
|
|
||||||
DESTINATION ${LIB_INSTALL_DIR}/mariadb)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/include/
|
INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/include/
|
||||||
DESTINATION ${INCLUDE_INSTALL_DIR}/${SUFFIX_INSTALL_DIR})
|
DESTINATION ${INCLUDE_INSTALL_DIR}/${SUFFIX_INSTALL_DIR})
|
||||||
INSTALL(FILES
|
INSTALL(FILES
|
||||||
|
@@ -58,6 +58,7 @@ static MEM_ROOT mem_root;
|
|||||||
|
|
||||||
#define plugin_declarations_sym "_mysql_client_plugin_declaration_"
|
#define plugin_declarations_sym "_mysql_client_plugin_declaration_"
|
||||||
|
|
||||||
|
|
||||||
static uint valid_plugins[][2]= {
|
static uint valid_plugins[][2]= {
|
||||||
{MYSQL_CLIENT_AUTHENTICATION_PLUGIN, MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION},
|
{MYSQL_CLIENT_AUTHENTICATION_PLUGIN, MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION},
|
||||||
{MARIADB_CLIENT_CIO_PLUGIN, MARIADB_CLIENT_CIO_PLUGIN_INTERFACE_VERSION},
|
{MARIADB_CLIENT_CIO_PLUGIN, MARIADB_CLIENT_CIO_PLUGIN_INTERFACE_VERSION},
|
||||||
@@ -138,7 +139,6 @@ static struct st_mysql_client_plugin *find_plugin(const char *name, int type)
|
|||||||
int plugin_nr= get_plugin_nr(type);
|
int plugin_nr= get_plugin_nr(type);
|
||||||
|
|
||||||
DBUG_ASSERT(initialized);
|
DBUG_ASSERT(initialized);
|
||||||
DBUG_ASSERT(plugin_nr != -1);
|
|
||||||
if (plugin_nr == -1)
|
if (plugin_nr == -1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -472,7 +472,7 @@ struct st_mysql_client_plugin * STDCALL
|
|||||||
mysql_client_find_plugin(MYSQL *mysql, const char *name, int type)
|
mysql_client_find_plugin(MYSQL *mysql, const char *name, int type)
|
||||||
{
|
{
|
||||||
struct st_mysql_client_plugin *p;
|
struct st_mysql_client_plugin *p;
|
||||||
int plugin_nr= find_plugin(name, type);
|
int plugin_nr= get_plugin_nr(type);
|
||||||
|
|
||||||
if (is_not_initialized(mysql, name))
|
if (is_not_initialized(mysql, name))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@@ -1380,8 +1380,6 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user,
|
|||||||
unix_socket=mysql->options.unix_socket;
|
unix_socket=mysql->options.unix_socket;
|
||||||
|
|
||||||
|
|
||||||
/* Since 5.0.3 reconnect is not enabled by default!!
|
|
||||||
mysql->reconnect=1; */
|
|
||||||
mysql->server_status=SERVER_STATUS_AUTOCOMMIT;
|
mysql->server_status=SERVER_STATUS_AUTOCOMMIT;
|
||||||
|
|
||||||
|
|
||||||
@@ -2729,7 +2727,7 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
|
|||||||
break;
|
break;
|
||||||
case MYSQL_OPT_SSL_CERT:
|
case MYSQL_OPT_SSL_CERT:
|
||||||
my_free(mysql->options.ssl_cert);
|
my_free(mysql->options.ssl_cert);
|
||||||
mysql->options.ssl_cert=my_strdup((char *)arg1,MYF(MY_WME | MY_ALLOW_ZERO_PTR));
|
mysql->options.ssl_cert=my_strdup((char *)arg1,MYF(MY_WME | MY_ALLOW_ZERO_PTR));
|
||||||
break;
|
break;
|
||||||
case MYSQL_OPT_SSL_CA:
|
case MYSQL_OPT_SSL_CA:
|
||||||
my_free(mysql->options.ssl_ca);
|
my_free(mysql->options.ssl_ca);
|
||||||
|
@@ -23,10 +23,13 @@
|
|||||||
#include <errmsg.h>
|
#include <errmsg.h>
|
||||||
#include <mysql.h>
|
#include <mysql.h>
|
||||||
#include <mysql/client_plugin.h>
|
#include <mysql/client_plugin.h>
|
||||||
|
#include <mariadb/ma_io.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_REMOTEIO
|
||||||
struct st_mysql_client_plugin_REMOTEIO *rio_plugin= NULL;
|
struct st_mysql_client_plugin_REMOTEIO *rio_plugin= NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* {{{ ma_open */
|
/* {{{ ma_open */
|
||||||
MA_FILE *ma_open(const char *location, const char *mode, MYSQL *mysql)
|
MA_FILE *ma_open(const char *location, const char *mode, MYSQL *mysql)
|
||||||
@@ -37,9 +40,10 @@ MA_FILE *ma_open(const char *location, const char *mode, MYSQL *mysql)
|
|||||||
|
|
||||||
if (!location || !location[0])
|
if (!location || !location[0])
|
||||||
return NULL;
|
return NULL;
|
||||||
|
#ifdef HAVE_REMOTEIO
|
||||||
if (strstr(location, "://"))
|
if (strstr(location, "://"))
|
||||||
goto remote;
|
goto remote;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (mysql && mysql->charset)
|
if (mysql && mysql->charset)
|
||||||
@@ -118,6 +122,7 @@ MA_FILE *ma_open(const char *location, const char *mode, MYSQL *mysql)
|
|||||||
ma_file->ptr= (void *)fp;
|
ma_file->ptr= (void *)fp;
|
||||||
}
|
}
|
||||||
return ma_file;
|
return ma_file;
|
||||||
|
#ifdef HAVE_REMOTEIO
|
||||||
remote:
|
remote:
|
||||||
/* check if plugin for remote io is available and try
|
/* check if plugin for remote io is available and try
|
||||||
* to open location */
|
* to open location */
|
||||||
@@ -128,6 +133,7 @@ remote:
|
|||||||
return rio_plugin->methods->open(location, mode);
|
return rio_plugin->methods->open(location, mode);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
@@ -143,9 +149,11 @@ int ma_close(MA_FILE *file)
|
|||||||
rc= fclose((FILE *)file->ptr);
|
rc= fclose((FILE *)file->ptr);
|
||||||
my_free(file);
|
my_free(file);
|
||||||
break;
|
break;
|
||||||
|
#ifdef HAVE_REMOTEIO
|
||||||
case MA_FILE_REMOTE:
|
case MA_FILE_REMOTE:
|
||||||
rc= rio_plugin->methods->close(file);
|
rc= rio_plugin->methods->close(file);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -163,9 +171,11 @@ int ma_feof(MA_FILE *file)
|
|||||||
case MA_FILE_LOCAL:
|
case MA_FILE_LOCAL:
|
||||||
return feof((FILE *)file->ptr);
|
return feof((FILE *)file->ptr);
|
||||||
break;
|
break;
|
||||||
|
#ifdef HAVE_REMOTEIO
|
||||||
case MA_FILE_REMOTE:
|
case MA_FILE_REMOTE:
|
||||||
return rio_plugin->methods->feof(file);
|
return rio_plugin->methods->feof(file);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -184,9 +194,11 @@ size_t ma_read(void *ptr, size_t size, size_t nmemb, MA_FILE *file)
|
|||||||
s= fread(ptr, size, nmemb, (FILE *)file->ptr);
|
s= fread(ptr, size, nmemb, (FILE *)file->ptr);
|
||||||
return s;
|
return s;
|
||||||
break;
|
break;
|
||||||
|
#ifdef HAVE_REMOTEIO
|
||||||
case MA_FILE_REMOTE:
|
case MA_FILE_REMOTE:
|
||||||
return rio_plugin->methods->read(ptr, size, nmemb, file);
|
return rio_plugin->methods->read(ptr, size, nmemb, file);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -203,9 +215,11 @@ char *ma_gets(char *ptr, size_t size, MA_FILE *file)
|
|||||||
case MA_FILE_LOCAL:
|
case MA_FILE_LOCAL:
|
||||||
return fgets(ptr, size, (FILE *)file->ptr);
|
return fgets(ptr, size, (FILE *)file->ptr);
|
||||||
break;
|
break;
|
||||||
|
#ifdef HAVE_REMOTEIO
|
||||||
case MA_FILE_REMOTE:
|
case MA_FILE_REMOTE:
|
||||||
return rio_plugin->methods->gets(ptr, size, file);
|
return rio_plugin->methods->gets(ptr, size, file);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@@ -79,12 +79,10 @@ my_string my_strdup(const char *from, myf MyFlags)
|
|||||||
gptr ptr;
|
gptr ptr;
|
||||||
uint length;
|
uint length;
|
||||||
|
|
||||||
if (MyFlags & MY_ALLOW_ZERO_PTR)
|
if ((MyFlags & MY_ALLOW_ZERO_PTR) && !from)
|
||||||
if (!from)
|
return NULL;
|
||||||
return NULL;
|
|
||||||
|
|
||||||
length=(uint) strlen(from)+1;
|
length=(uint) strlen(from)+1;
|
||||||
|
|
||||||
if ((ptr=my_malloc(length,MyFlags)) != 0)
|
if ((ptr=my_malloc(length,MyFlags)) != 0)
|
||||||
memcpy((unsigned char*) ptr, (unsigned char*) from,(size_t) length);
|
memcpy((unsigned char*) ptr, (unsigned char*) from,(size_t) length);
|
||||||
return((my_string) ptr);
|
return((my_string) ptr);
|
||||||
|
@@ -1887,6 +1887,7 @@ int STDCALL mysql_stmt_next_result(MYSQL_STMT *stmt)
|
|||||||
|
|
||||||
if (mysql_next_result(stmt->mysql))
|
if (mysql_next_result(stmt->mysql))
|
||||||
{
|
{
|
||||||
|
stmt->state= MYSQL_STMT_FETCH_DONE;
|
||||||
SET_CLIENT_STMT_ERROR(stmt, stmt->mysql->net.last_errno, stmt->mysql->net.sqlstate,
|
SET_CLIENT_STMT_ERROR(stmt, stmt->mysql->net.last_errno, stmt->mysql->net.sqlstate,
|
||||||
stmt->mysql->net.last_error);
|
stmt->mysql->net.last_error);
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
@@ -825,7 +825,7 @@ mysql_close_start(MYSQL *sock)
|
|||||||
int res;
|
int res;
|
||||||
|
|
||||||
/* It is legitimate to have NULL sock argument, which will do nothing. */
|
/* It is legitimate to have NULL sock argument, which will do nothing. */
|
||||||
if (sock)
|
if (sock && sock->net.cio)
|
||||||
{
|
{
|
||||||
res= mysql_close_slow_part_start(sock);
|
res= mysql_close_slow_part_start(sock);
|
||||||
/* If we need to block, return now and do the rest in mysql_close_cont(). */
|
/* If we need to block, return now and do the rest in mysql_close_cont(). */
|
||||||
|
@@ -164,7 +164,7 @@ static my_bool net_realloc(NET *net, size_t length)
|
|||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1);
|
pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1);
|
||||||
/* reallocate buffer:
|
/* reallocate buffer:
|
||||||
size= pkt_length + NET_HEADER_SIZE + COMP_HEADER_SIZE */
|
size= pkt_length + NET_HEADER_SIZE + COMP_HEADER_SIZE */
|
||||||
if (!(buff=(uchar*) my_realloc((char*) net->buff,
|
if (!(buff=(uchar*) my_realloc((char*) net->buff,
|
||||||
pkt_length + NET_HEADER_SIZE + COMP_HEADER_SIZE,
|
pkt_length + NET_HEADER_SIZE + COMP_HEADER_SIZE,
|
||||||
|
19
plugins/connection/CMakeLists.txt
Normal file
19
plugins/connection/CMakeLists.txt
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
IF(WIN32)
|
||||||
|
SET(EXPORT_FILE "../plugin.def")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
SET(CMAKE_SHARED_LIBRARY_PREFIX "")
|
||||||
|
|
||||||
|
IF(REPLICATION_PLUGIN_TYPE MATCHES "DYNAMIC")
|
||||||
|
ADD_DEFINITIONS(-DHAVE_REPLICATION_DYNAMIC=1)
|
||||||
|
ADD_LIBRARY(replication SHARED replication.c ${EXPORT_FILE})
|
||||||
|
SET(INSTALL_LIBS replication)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
IF(INSTALL_LIBS)
|
||||||
|
INSTALL(TARGETS
|
||||||
|
${INSTALL_LIBS}
|
||||||
|
RUNTIME DESTINATION "${PLUGIN_INSTALL_DIR}"
|
||||||
|
LIBRARY DESTINATION "${PLUGIN_INSTALL_DIR}"
|
||||||
|
ARCHIVE DESTINATION "${PLUGIN_INSTALL_DIR}")
|
||||||
|
ENDIF()
|
325
plugins/connection/replication.c
Normal file
325
plugins/connection/replication.c
Normal file
@@ -0,0 +1,325 @@
|
|||||||
|
/************************************************************************************
|
||||||
|
Copyright (C) 2015 MariaDB Corporation AB
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Library General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Library General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public
|
||||||
|
License along with this library; if not see <http://www.gnu.org/licenses>
|
||||||
|
or write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin St., Fifth Floor, Boston, MA 02110, USA
|
||||||
|
|
||||||
|
Part of this code includes code from the PHP project which
|
||||||
|
is freely available from http://www.php.net
|
||||||
|
*************************************************************************************/
|
||||||
|
|
||||||
|
/* MariaDB Connection plugin for load balancing */
|
||||||
|
|
||||||
|
#include <my_global.h>
|
||||||
|
#include <my_sys.h>
|
||||||
|
#include <errmsg.h>
|
||||||
|
#include <mysql.h>
|
||||||
|
#include <mysql/client_plugin.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <m_string.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
/* function prototypes */
|
||||||
|
MYSQL *repl_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd,
|
||||||
|
const char *db, unsigned int port, const char *unix_socket, unsigned long clientflag);
|
||||||
|
void repl_close(MYSQL *mysql);
|
||||||
|
int repl_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
|
||||||
|
size_t length, my_bool skipp_check, void *opt_arg);
|
||||||
|
int repl_set_options(MYSQL *msql, enum mysql_option option, void *arg);
|
||||||
|
|
||||||
|
#ifdef HAVE_REPLICATION_DYNAMIC
|
||||||
|
|
||||||
|
#undef my_free
|
||||||
|
#define my_malloc(a,b) malloc(a)
|
||||||
|
#define my_free(a) free(a)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MARIADB_MASTER 0
|
||||||
|
#define MARIADB_SLAVE 1
|
||||||
|
|
||||||
|
#ifndef HAVE_REPLICATION_DYNAMIC
|
||||||
|
MARIADB_CONNECTION_PLUGIN connection_replication_plugin =
|
||||||
|
#else
|
||||||
|
MARIADB_CONNECTION_PLUGIN _mysql_client_plugin_declaration_ =
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
MARIADB_CLIENT_CONNECTION_PLUGIN,
|
||||||
|
MARIADB_CLIENT_CONNECTION_PLUGIN_INTERFACE_VERSION,
|
||||||
|
"replication",
|
||||||
|
"Georg Richter",
|
||||||
|
"MariaDB connection plugin for load balancing",
|
||||||
|
{1, 0, 0},
|
||||||
|
"LGPL",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
repl_connect,
|
||||||
|
repl_close,
|
||||||
|
repl_set_options,
|
||||||
|
repl_command
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct st_conn_repl {
|
||||||
|
MARIADB_CIO *cio[2];
|
||||||
|
MYSQL *slave_mysql;
|
||||||
|
my_bool read_only;
|
||||||
|
my_bool round_robin;
|
||||||
|
char *url;
|
||||||
|
char *host[2];
|
||||||
|
int port[2];
|
||||||
|
} REPL_DATA;
|
||||||
|
|
||||||
|
#define SET_SLAVE(mysql, data) mysql->net.cio= data->cio[MARIADB_SLAVE]
|
||||||
|
#define SET_MASTER(mysql, data) mysql->net.cio= data->cio[MARIADB_MASTER]
|
||||||
|
|
||||||
|
|
||||||
|
/* parse url
|
||||||
|
* Url has the following format:
|
||||||
|
* master[:port],slave1[:port],slave2[:port],..,slaven[:port]
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
my_bool repl_parse_url(const char *url, REPL_DATA *data)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
char *slaves[64];
|
||||||
|
int port[64], i,num_slaves= 0;
|
||||||
|
|
||||||
|
if (!url || url[0] == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
bzero(slaves, 64 * sizeof(char *));
|
||||||
|
bzero(&port, 64 * sizeof(int));
|
||||||
|
|
||||||
|
memset(data->host, 0, 2 * sizeof(char *));
|
||||||
|
memset(data->port, 0, 2 * sizeof(int));
|
||||||
|
|
||||||
|
if (data->url)
|
||||||
|
my_free(data->url);
|
||||||
|
|
||||||
|
data->url= my_strdup(url, MYF(0));
|
||||||
|
data->host[MARIADB_MASTER]= p= data->url;
|
||||||
|
|
||||||
|
/* get slaves */
|
||||||
|
while((p && (p= strchr(p, ','))))
|
||||||
|
{
|
||||||
|
*p= '\0';
|
||||||
|
p++;
|
||||||
|
if (*p)
|
||||||
|
{
|
||||||
|
slaves[num_slaves]= p;
|
||||||
|
num_slaves++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!num_slaves)
|
||||||
|
return 0;
|
||||||
|
if (num_slaves == 1)
|
||||||
|
data->host[MARIADB_SLAVE]= slaves[0];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct timeval tp;
|
||||||
|
int random_nr;
|
||||||
|
gettimeofday(&tp,NULL);
|
||||||
|
srand(tp.tv_usec / 1000 + tp.tv_sec * 1000);
|
||||||
|
|
||||||
|
random_nr= rand() % num_slaves;
|
||||||
|
data->host[MARIADB_SLAVE]= slaves[random_nr];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check ports */
|
||||||
|
for (i=0; i < 2 && data->host[i]; i++)
|
||||||
|
{
|
||||||
|
/* We need to be aware of IPv6 addresses: According to RFC3986 sect. 3.2.2
|
||||||
|
hostnames have to be enclosed in square brackets if a port is given */
|
||||||
|
if (data->host[i][0]= '[' && strchr(data->host[i], ':') && (p= strchr(data->host[i],']')))
|
||||||
|
{
|
||||||
|
/* ignore first square bracket */
|
||||||
|
data->host[i]++;
|
||||||
|
*p= 0;
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
p= data->host[i];
|
||||||
|
if (p && (p= strchr(p, ':')))
|
||||||
|
{
|
||||||
|
*p= '\0';
|
||||||
|
p++;
|
||||||
|
data->port[i]= atoi(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MYSQL *repl_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd,
|
||||||
|
const char *db, unsigned int port, const char *unix_socket, unsigned long clientflag)
|
||||||
|
{
|
||||||
|
REPL_DATA *data= NULL;
|
||||||
|
MA_CONNECTION_HANDLER *hdlr= mysql->net.conn_hdlr;
|
||||||
|
|
||||||
|
if (!(data= calloc(1, sizeof(REPL_DATA))))
|
||||||
|
{
|
||||||
|
mysql->methods->set_error(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(data->cio, 0, 2 * sizeof(MARIADB_CIO *));
|
||||||
|
|
||||||
|
if (repl_parse_url(host, data))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/* try to connect to master */
|
||||||
|
if (!(mysql->methods->db_connect(mysql, data->host[MARIADB_MASTER], user, passwd, db,
|
||||||
|
data->port[MARIADB_MASTER] ? data->port[MARIADB_MASTER] : port, unix_socket, clientflag)))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
data->cio[MARIADB_MASTER]= mysql->net.cio;
|
||||||
|
hdlr->data= data;
|
||||||
|
|
||||||
|
/* to allow immediate access without connection delay, we will start
|
||||||
|
* connecting to slave(s) in background */
|
||||||
|
|
||||||
|
/* if slave connection will fail, we will not return error but use master instead */
|
||||||
|
if (!(data->slave_mysql= mysql_init(NULL)) ||
|
||||||
|
!(mysql->methods->db_connect(data->slave_mysql, data->host[MARIADB_SLAVE], user, passwd, db,
|
||||||
|
data->port[MARIADB_SLAVE] ? data->port[MARIADB_SLAVE] : port, unix_socket, clientflag)))
|
||||||
|
{
|
||||||
|
if (data->slave_mysql)
|
||||||
|
mysql_close(data->slave_mysql);
|
||||||
|
data->cio[MARIADB_SLAVE]= NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data->cio[MARIADB_SLAVE]= data->slave_mysql->net.cio;
|
||||||
|
data->slave_mysql->net.cio->mysql= mysql;
|
||||||
|
}
|
||||||
|
return mysql;
|
||||||
|
error:
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
if (data->url)
|
||||||
|
my_free(data->url);
|
||||||
|
my_free(data);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void repl_close(MYSQL *mysql)
|
||||||
|
{
|
||||||
|
MA_CONNECTION_HANDLER *hdlr= mysql->net.conn_hdlr;
|
||||||
|
REPL_DATA *data= (REPL_DATA *)hdlr->data;
|
||||||
|
|
||||||
|
/* restore master */
|
||||||
|
SET_MASTER(mysql, data);
|
||||||
|
|
||||||
|
/* free slave information and close connection */
|
||||||
|
if (data->cio[MARIADB_SLAVE])
|
||||||
|
{
|
||||||
|
/* restore mysql */
|
||||||
|
data->cio[MARIADB_SLAVE]->mysql= data->slave_mysql;
|
||||||
|
mysql_close(data->slave_mysql);
|
||||||
|
data->cio[MARIADB_SLAVE]= NULL;
|
||||||
|
data->slave_mysql= NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free masrwe information and close connection */
|
||||||
|
my_free(data->url);
|
||||||
|
my_free(data);
|
||||||
|
mysql->net.conn_hdlr->data= NULL;
|
||||||
|
return mysql_close(mysql);
|
||||||
|
}
|
||||||
|
|
||||||
|
static my_bool is_slave_command(const char *buffer, size_t buffer_len)
|
||||||
|
{
|
||||||
|
const char *buffer_end= buffer + buffer_len;
|
||||||
|
|
||||||
|
for (; buffer < buffer_end; ++buffer)
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
if (isalpha(c=*buffer))
|
||||||
|
{
|
||||||
|
if (tolower(c) == 's')
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static my_bool is_slave_stmt(MYSQL *mysql, const char *buffer)
|
||||||
|
{
|
||||||
|
unsigned long stmt_id= uint4korr(buffer);
|
||||||
|
LIST *stmt_list= mysql->stmts;
|
||||||
|
|
||||||
|
for (; stmt_list; stmt_list= stmt_list->next)
|
||||||
|
{
|
||||||
|
MYSQL_STMT *stmt= (MYSQL_STMT *)stmt_list->data;
|
||||||
|
if (stmt->stmt_id == stmt_id)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int repl_command(MYSQL *mysql,enum enum_server_command command, const char *arg,
|
||||||
|
size_t length, my_bool skipp_check, void *opt_arg)
|
||||||
|
{
|
||||||
|
REPL_DATA *data= (REPL_DATA *)mysql->net.conn_hdlr->data;
|
||||||
|
|
||||||
|
/* if we don't have slave or slave became unavailable root traffic to master */
|
||||||
|
if (!data->cio[MARIADB_SLAVE] || !data->read_only)
|
||||||
|
{
|
||||||
|
SET_MASTER(mysql, data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
switch(command) {
|
||||||
|
case MYSQL_COM_QUERY:
|
||||||
|
case MYSQL_COM_STMT_PREPARE:
|
||||||
|
if (is_slave_command(arg, length))
|
||||||
|
SET_SLAVE(mysql, data);
|
||||||
|
else
|
||||||
|
SET_MASTER(mysql,data);
|
||||||
|
break;
|
||||||
|
case MYSQL_COM_STMT_EXECUTE:
|
||||||
|
case MYSQL_COM_STMT_FETCH:
|
||||||
|
if (data->cio[MARIADB_SLAVE]->mysql->stmts && is_slave_stmt(data->cio[MARIADB_SLAVE]->mysql, arg))
|
||||||
|
SET_SLAVE(mysql, data);
|
||||||
|
else
|
||||||
|
SET_MASTER(mysql,data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
SET_MASTER(mysql,data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int repl_set_options(MYSQL *mysql, enum mysql_option option, void *arg)
|
||||||
|
{
|
||||||
|
REPL_DATA *data= (REPL_DATA *)mysql->net.conn_hdlr->data;
|
||||||
|
|
||||||
|
switch(option) {
|
||||||
|
case MARIADB_OPT_CONNECTION_READ_ONLY:
|
||||||
|
data->read_only= *(my_bool *)arg;
|
||||||
|
return 0;
|
||||||
|
/*
|
||||||
|
case MARIADB_OPT_CONNECTION_ROUND_ROBIN:
|
||||||
|
data->round_robin= *(my_bool *)arg;
|
||||||
|
return 0; */
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
@@ -200,10 +200,17 @@ static int test_conc131(MYSQL *my)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int test_conc129(MYSQL *my)
|
||||||
|
{
|
||||||
|
MYSQL *mysql= mysql_init(NULL);
|
||||||
|
FAIL_IF(mysql_close_start(mysql), "No error expected");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct my_tests_st my_tests[] = {
|
struct my_tests_st my_tests[] = {
|
||||||
{"async1", async1, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
{"async1", async1, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||||
{"test_conc131", test_conc131, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
{"test_conc131", test_conc131, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
||||||
|
{"test_conc129", test_conc129, TEST_CONNECTION_NONE, 0, NULL, NULL},
|
||||||
{NULL, NULL, 0, 0, NULL, NULL}
|
{NULL, NULL, 0, 0, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -57,7 +57,7 @@ static int test_conc66(MYSQL *my)
|
|||||||
diag("Error: %s", mysql_error(mysql));
|
diag("Error: %s", mysql_error(mysql));
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
rc= mysql_query(my, "DROP USER conc66@%");
|
rc= mysql_query(my, "DROP USER conc66@localhost");
|
||||||
|
|
||||||
check_mysql_rc(rc, my);
|
check_mysql_rc(rc, my);
|
||||||
mysql_close(mysql);
|
mysql_close(mysql);
|
||||||
|
@@ -26,7 +26,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
#include <mysql/client_plugin.h>
|
#include <mysql/client_plugin.h>
|
||||||
|
|
||||||
void *remote_plugin;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Bug#28075 "COM_DEBUG crashes mysqld"
|
Bug#28075 "COM_DEBUG crashes mysqld"
|
||||||
@@ -974,6 +973,8 @@ static int test_conc117(MYSQL *mysql)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_REMOTEIO
|
||||||
|
void *remote_plugin;
|
||||||
static int test_remote1(MYSQL *mysql)
|
static int test_remote1(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
@@ -1019,11 +1020,14 @@ static int test_remote2(MYSQL *my)
|
|||||||
mysql_close(mysql);
|
mysql_close(mysql);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
struct my_tests_st my_tests[] = {
|
struct my_tests_st my_tests[] = {
|
||||||
|
#ifdef HAVE_REMOTEIO
|
||||||
{"test_remote1", test_remote1, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
{"test_remote1", test_remote1, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||||
{"test_remote2", test_remote2, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
{"test_remote2", test_remote2, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
||||||
{"test_conc117", test_conc117, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
#endif
|
||||||
|
{"test_conc117", test_conc117, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||||
{"test_conc_114", test_conc_114, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
{"test_conc_114", test_conc_114, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||||
{"test_connect_attrs", test_connect_attrs, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
{"test_connect_attrs", test_connect_attrs, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||||
{"test_conc49", test_conc49, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
{"test_conc49", test_conc49, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
|
||||||
|
@@ -3868,7 +3868,45 @@ static int test_conc_5(MYSQL *mysql)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int test_conc141(MYSQL *mysql)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
char *query= "CALL p_conc141";
|
||||||
|
MYSQL_STMT *stmt= mysql_stmt_init(mysql);
|
||||||
|
|
||||||
|
rc= mysql_query(mysql, "DROP TABLE IF EXISTS conc141");
|
||||||
|
check_mysql_rc(rc, mysql);
|
||||||
|
rc= mysql_query(mysql, "CREATE TABLE conc141 (KeyVal int not null primary key)");
|
||||||
|
check_mysql_rc(rc, mysql);
|
||||||
|
rc= mysql_query(mysql, "INSERT INTO conc141 VALUES(1)");
|
||||||
|
check_mysql_rc(rc, mysql);
|
||||||
|
rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p_conc141");
|
||||||
|
check_mysql_rc(rc, mysql);
|
||||||
|
rc= mysql_query(mysql, "CREATE PROCEDURE p_conc141()\n"
|
||||||
|
"BEGIN\n"
|
||||||
|
"select * from conc141;\n"
|
||||||
|
"insert into conc141(KeyVal) VALUES(1);\n"
|
||||||
|
"END");
|
||||||
|
check_mysql_rc(rc, mysql);
|
||||||
|
|
||||||
|
rc= mysql_stmt_prepare(stmt, query, strlen(query));
|
||||||
|
check_stmt_rc(rc, stmt);
|
||||||
|
|
||||||
|
rc= mysql_stmt_execute(stmt);
|
||||||
|
check_stmt_rc(rc, stmt);
|
||||||
|
/* skip first result */
|
||||||
|
rc= mysql_stmt_next_result(stmt);
|
||||||
|
FAIL_IF(rc==-1, "No more results and error expected");
|
||||||
|
mysql_stmt_free_result(stmt);
|
||||||
|
FAIL_IF(mysql_stmt_errno(stmt), "No Error expected");
|
||||||
|
rc= mysql_stmt_execute(stmt);
|
||||||
|
check_stmt_rc(rc, stmt);
|
||||||
|
mysql_stmt_close(stmt);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
struct my_tests_st my_tests[] = {
|
struct my_tests_st my_tests[] = {
|
||||||
|
{"test_conc141", test_conc141, TEST_CONNECTION_NEW, 0, NULL , NULL},
|
||||||
{"test_conc67", test_conc67, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
{"test_conc67", test_conc67, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
||||||
{"test_conc_5", test_conc_5, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
{"test_conc_5", test_conc_5, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
||||||
{"test_bug1115", test_bug1115, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
{"test_bug1115", test_bug1115, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
|
||||||
|
Reference in New Issue
Block a user