1
0
mirror of https://github.com/mariadb-corporation/mariadb-connector-c.git synced 2025-08-08 14:02:17 +03:00
Conflicts:
	CMakeLists.txt
This commit is contained in:
Georg Richter
2015-12-10 12:55:02 +01:00
7 changed files with 337 additions and 57 deletions

View File

@@ -28,7 +28,6 @@ IF(CMAKE_VERSION VERSION_GREATER "2.9.9")
CMAKE_POLICY(SET CMP0045 OLD) CMAKE_POLICY(SET CMP0045 OLD)
ENDIF() ENDIF()
SET(MARIADB_CONNECTOR_C_COPYRIGHT "2013-2015 MariaDB Corporation Ab") SET(MARIADB_CONNECTOR_C_COPYRIGHT "2013-2015 MariaDB Corporation Ab")
### Options ### ### Options ###
@@ -296,10 +295,10 @@ IF(GIT_BUILD_SRCPKG)
STRING(REGEX REPLACE "\\[|\\]" "" GIT_BRANCH ${git_branch}) STRING(REGEX REPLACE "\\[|\\]" "" GIT_BRANCH ${git_branch})
MESSAGE(STATUS "${GIT_BRANCH}") MESSAGE(STATUS "${GIT_BRANCH}")
IF(WIN32) IF(WIN32)
EXECUTE_PROCESS(COMMAND git archive ${GIT_BRANCH} --format=zip --output=${CPACK_SOURCE_PACKAGE_FILE_NAME}.zip) EXECUTE_PROCESS(COMMAND git archive ${GIT_BRANCH} --format=zip --prefix=${CPACK_SOURCE_PACKAGE_FILE_NAME}/ --output=${CPACK_SOURCE_PACKAGE_FILE_NAME}.zip)
ELSE() ELSE()
EXECUTE_PROCESS(COMMAND git archive ${GIT_BRANCH} --format=zip --output=${CPACK_SOURCE_PACKAGE_FILE_NAME}.zip) EXECUTE_PROCESS(COMMAND git archive ${GIT_BRANCH} --format=zip --prefix=${CPACK_SOURCE_PACKAGE_FILE_NAME}/ --output=${CPACK_SOURCE_PACKAGE_FILE_NAME}.zip)
EXECUTE_PROCESS(COMMAND git archive ${GIT_BRANCH} --format=tar --output=${CPACK_SOURCE_PACKAGE_FILE_NAME}.tar) EXECUTE_PROCESS(COMMAND git archive ${GIT_BRANCH} --format=tar --prefix=${CPACK_SOURCE_PACKAGE_FILE_NAME}/ --output=${CPACK_SOURCE_PACKAGE_FILE_NAME}.tar)
EXECUTE_PROCESS(COMMAND gzip -9 -f ${CPACK_SOURCE_PACKAGE_FILE_NAME}.tar) EXECUTE_PROCESS(COMMAND gzip -9 -f ${CPACK_SOURCE_PACKAGE_FILE_NAME}.tar)
ENDIF() ENDIF()
ENDIF() ENDIF()

View File

@@ -214,7 +214,8 @@ extern unsigned int mariadb_deinitialize_ssl;
MARIADB_OPT_SSL_FP, /* single finger print for server certificate verification */ MARIADB_OPT_SSL_FP, /* single finger print for server certificate verification */
MARIADB_OPT_SSL_FP_LIST, /* finger print white list for server certificate verification */ MARIADB_OPT_SSL_FP_LIST, /* finger print white list for server certificate verification */
MARIADB_OPT_SSL_PASSWORD, /* password for encrypted certificates */ MARIADB_OPT_SSL_PASSWORD, /* password for encrypted certificates */
MARIADB_OPT_CONNECTION_READ_ONLY MARIADB_OPT_CONNECTION_READ_ONLY,
MYSQL_OPT_CONNECT_ATTRS /* for mysql_get_optionv */
}; };
enum mysql_status { MYSQL_STATUS_READY, enum mysql_status { MYSQL_STATUS_READY,
@@ -487,6 +488,8 @@ CHARSET_INFO * STDCALL mariadb_get_charset_by_nr(unsigned int csnr);
size_t STDCALL mariadb_convert_string(const char *from, size_t *from_len, CHARSET_INFO *from_cs, size_t STDCALL mariadb_convert_string(const char *from, size_t *from_len, CHARSET_INFO *from_cs,
char *to, size_t *to_len, CHARSET_INFO *to_cs, int *errorcode); char *to, size_t *to_len, CHARSET_INFO *to_cs, int *errorcode);
int STDCALL mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...); int STDCALL mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...);
int STDCALL mysql_get_optionv(MYSQL *mysql, enum mysql_option option, void *arg, ...);
int STDCALL mysql_get_option(MYSQL *mysql, enum mysql_option option, void *arg);
MYSQL_PARAMETERS *STDCALL mysql_get_parameters(void); MYSQL_PARAMETERS *STDCALL mysql_get_parameters(void);
unsigned long STDCALL mysql_hex_string(char *to, const char *from, size_t len); unsigned long STDCALL mysql_hex_string(char *to, const char *from, size_t len);
my_socket STDCALL mysql_get_socket(const MYSQL *mysql); my_socket STDCALL mysql_get_socket(const MYSQL *mysql);

View File

@@ -81,6 +81,8 @@ SET(EXPORT_SYMBOLS
mysql_get_client_info mysql_get_client_info
mysql_get_client_version mysql_get_client_version
mysql_get_host_info mysql_get_host_info
mysql_get_option
mysql_get_optionv
mysql_get_parameters mysql_get_parameters
mysql_get_proto_info mysql_get_proto_info
mysql_get_server_info mysql_get_server_info

View File

@@ -1229,15 +1229,13 @@ uchar *ma_send_connect_attr(MYSQL *mysql, uchar *buffer)
size_t len; size_t len;
uchar *p= hash_element(&mysql->options.extension->connect_attrs, i); uchar *p= hash_element(&mysql->options.extension->connect_attrs, i);
len= *(size_t *)p; len= strlen(p);
buffer= mysql_net_store_length(buffer, len); buffer= mysql_net_store_length(buffer, len);
p+= sizeof(size_t);
memcpy(buffer, p, len); memcpy(buffer, p, len);
buffer+= len; buffer+= (len);
p+= len; p+= (len + 1);
len= *(size_t *)p; len= strlen(p);
buffer= mysql_net_store_length(buffer, len); buffer= mysql_net_store_length(buffer, len);
p+= sizeof(size_t);
memcpy(buffer, p, len); memcpy(buffer, p, len);
buffer+= len; buffer+= len;
} }
@@ -2597,21 +2595,17 @@ static size_t get_store_length(size_t length)
return 9; return 9;
} }
uchar *ma_get_hash_key(const uchar *hash_entry, uchar *ma_get_hash_keyval(const uchar *hash_entry,
unsigned int *length, unsigned int *length,
my_bool not_used __attribute__((unused))) my_bool not_used __attribute__((unused)))
{ {
/* Hash entry has the following format: /* Hash entry has the following format:
Offset: 0 key length Offset: 0 key (\0 terminated)
sizeof(size_t) key key_length + 1 valu (\0 terminated)
key_length +
sizeof(size_t) value length
value
*/ */
uchar *p= (uchar *)hash_entry; uchar *p= (uchar *)hash_entry;
size_t len=*((size_t*)p); size_t len= strlen(p);
p+= sizeof(size_t); *length= len;
*length= (uint)len;
return p; return p;
} }
@@ -2809,19 +2803,19 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
break; break;
case MYSQL_OPT_CONNECT_ATTR_DELETE: case MYSQL_OPT_CONNECT_ATTR_DELETE:
{ {
uchar *p; uchar *h;
CHECK_OPT_EXTENSION_SET(&mysql->options); CHECK_OPT_EXTENSION_SET(&mysql->options);
if (hash_inited(&mysql->options.extension->connect_attrs) && if (hash_inited(&mysql->options.extension->connect_attrs) &&
(p= (uchar *)hash_search(&mysql->options.extension->connect_attrs, (uchar *)arg1, (h= (uchar *)hash_search(&mysql->options.extension->connect_attrs, (uchar *)arg1,
arg1 ? (uint)strlen((char *)arg1) : 0))) arg1 ? (uint)strlen((char *)arg1) : 0)))
{ {
size_t key_len= *(size_t *)p; uchar *p= h;
mysql->options.extension->connect_attrs_len-= key_len; size_t key_len= strlen(p);
mysql->options.extension->connect_attrs_len-= get_store_length(key_len); mysql->options.extension->connect_attrs_len-= key_len + get_store_length(key_len);
key_len= *(size_t *)(p + sizeof(size_t) + key_len); p+= key_len + 1;
mysql->options.extension->connect_attrs_len-= key_len; key_len= strlen(p);
mysql->options.extension->connect_attrs_len-= get_store_length(key_len); mysql->options.extension->connect_attrs_len-= key_len + get_store_length(key_len);
hash_delete(&mysql->options.extension->connect_attrs, p); hash_delete(&mysql->options.extension->connect_attrs, h);
} }
} }
@@ -2843,6 +2837,11 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
size_t storage_len= key_len + value_len + size_t storage_len= key_len + value_len +
get_store_length(key_len) + get_store_length(key_len) +
get_store_length(value_len); get_store_length(value_len);
/* since we store terminating zero character in hash, we need
* to increase lengths */
key_len++;
value_len++;
CHECK_OPT_EXTENSION_SET(&mysql->options); CHECK_OPT_EXTENSION_SET(&mysql->options);
if (!key_len || if (!key_len ||
@@ -2855,24 +2854,20 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...)
if (!hash_inited(&mysql->options.extension->connect_attrs)) if (!hash_inited(&mysql->options.extension->connect_attrs))
{ {
if (_hash_init(&mysql->options.extension->connect_attrs, if (_hash_init(&mysql->options.extension->connect_attrs,
0, 0, 0, ma_get_hash_key, ma_hash_free, 0)) 0, 0, 0, ma_get_hash_keyval, ma_hash_free, 0))
{ {
SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate, 0); SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate, 0);
goto end; goto end;
} }
} }
if ((buffer= (uchar *)my_malloc(2 * sizeof(size_t) + key_len + value_len, if ((buffer= (uchar *)my_malloc(key_len + value_len,
MYF(MY_WME | MY_ZEROFILL)))) MYF(MY_WME | MY_ZEROFILL))))
{ {
uchar *p= buffer; uchar *p= buffer;
*((size_t *)p)= key_len; strcpy(p, arg1);
p+= sizeof(size_t); p+= (strlen(arg1) + 1);
memcpy(p, arg1, key_len);
p+= key_len;
*((size_t *)p)= value_len;
p+= sizeof(size_t);
if (arg2) if (arg2)
memcpy(p, arg2, value_len); strcpy(p, arg2);
if (hash_insert(&mysql->options.extension->connect_attrs, buffer)) if (hash_insert(&mysql->options.extension->connect_attrs, buffer))
{ {
@@ -2921,6 +2916,176 @@ end:
DBUG_RETURN(1); DBUG_RETURN(1);
} }
int STDCALL
mysql_get_optionv(MYSQL *mysql, enum mysql_option option, void *arg, ...)
{
va_list ap;
DBUG_ENTER("mariadb_get_optionv");
DBUG_PRINT("enter",("option: %d",(int) option));
va_start(ap, arg);
switch(option) {
case MYSQL_OPT_CONNECT_TIMEOUT:
*((uint *)arg)= mysql->options.connect_timeout;
break;
case MYSQL_OPT_COMPRESS:
*((my_bool *)arg)= mysql->options.compress;
break;
case MYSQL_OPT_NAMED_PIPE:
*((my_bool *)arg)= mysql->options.named_pipe;
break;
case MYSQL_OPT_LOCAL_INFILE: /* Allow LOAD DATA LOCAL ?*/
*((uint *)arg)= test(mysql->options.client_flag & CLIENT_LOCAL_FILES);
break;
case MYSQL_INIT_COMMAND:
/* mysql_get_optionsv(mysql, MYSQL_INIT_COMMAND, commands, elements) */
{
unsigned int *elements;
if (arg)
*((char **)arg)= mysql->options.init_command ? mysql->options.init_command->buffer : NULL;
if ((elements= va_arg(ap, unsigned int *)))
*elements= mysql->options.init_command ? mysql->options.init_command->elements : 0;
}
break;
case MYSQL_READ_DEFAULT_FILE:
*((char **)arg)= mysql->options.my_cnf_file;
break;
case MYSQL_READ_DEFAULT_GROUP:
*((char **)arg)= mysql->options.my_cnf_group;
break;
case MYSQL_SET_CHARSET_DIR:
/* not supported in this version. Since all character sets
are internally available, we don't throw an error */
*((char **)arg)= NULL;
break;
case MYSQL_SET_CHARSET_NAME:
*((char **)arg)= mysql->options.charset_name;
break;
case MYSQL_OPT_RECONNECT:
*((uint *)arg)= mysql->reconnect;
break;
case MYSQL_OPT_PROTOCOL:
*((uint *)arg)= mysql->options.protocol;
break;
case MYSQL_OPT_READ_TIMEOUT:
*((uint *)arg)= mysql->options.read_timeout;
break;
case MYSQL_OPT_WRITE_TIMEOUT:
*((uint *)arg)= mysql->options.write_timeout;
break;
case MYSQL_REPORT_DATA_TRUNCATION:
*((uint *)arg)= mysql->options.report_data_truncation;
break;
case MYSQL_PROGRESS_CALLBACK:
*((void (**)(const MYSQL *, uint, uint, double, const char *, uint))arg)=
mysql->options.extension ? mysql->options.extension->report_progress : NULL;
break;
case MYSQL_PLUGIN_DIR:
*((char **)arg)= mysql->options.extension ? mysql->options.extension->plugin_dir : NULL;
break;
case MYSQL_DEFAULT_AUTH:
*((char **)arg)= mysql->options.extension ? mysql->options.extension->default_auth : NULL;
break;
case MYSQL_OPT_NONBLOCK:
*((my_bool *)arg)= test(mysql->options.extension && mysql->options.extension->async_context);
break;
case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
*((my_bool *)arg)= test(mysql->options.client_flag & CLIENT_SSL_VERIFY_SERVER_CERT);
break;
case MYSQL_OPT_SSL_KEY:
*((char **)arg)= mysql->options.ssl_key;
break;
case MYSQL_OPT_SSL_CERT:
*((char **)arg)= mysql->options.ssl_cert;
break;
case MYSQL_OPT_SSL_CA:
*((char **)arg)= mysql->options.ssl_ca;
break;
case MYSQL_OPT_SSL_CAPATH:
*((char **)arg)= mysql->options.ssl_capath;
break;
case MYSQL_OPT_SSL_CIPHER:
*((char **)arg)= mysql->options.ssl_cipher;
break;
case MYSQL_OPT_SSL_CRL:
*((char **)arg)= mysql->options.extension ? mysql->options.ssl_cipher : NULL;
break;
case MYSQL_OPT_SSL_CRLPATH:
*((char **)arg)= mysql->options.extension ? mysql->options.extension->ssl_crlpath : NULL;
break;
case MYSQL_OPT_CONNECT_ATTRS:
/* mysql_get_optionsv(mysql, MYSQL_OPT_CONNECT_ATTRS, keys, vals, elements) */
{
int i, *elements;
char **key= (char **)arg;
char **val;
if (!elements)
goto error;
val= va_arg(ap, char **);
if (!(elements= va_arg(ap, unsigned int *)))
goto error;
*elements= 0;
if (!mysql->options.extension ||
!hash_inited(&mysql->options.extension->connect_attrs))
break;
*elements= mysql->options.extension->connect_attrs.records;
if (val || key)
{
for (i=0; i < *elements; i++)
{
uchar *p= hash_element(&mysql->options.extension->connect_attrs, i);
if (key)
key[i]= p;
p+= strlen(p) + 1;
if (val)
val[i]= p;
}
}
}
break;
case MYSQL_SECURE_AUTH:
*((my_bool *)arg)= mysql->options.secure_auth;
break;
case MYSQL_OPT_BIND:
*((char **)arg)= mysql->options.bind_address;
break;
case MARIADB_OPT_SSL_FP:
*((char **)arg)= mysql->options.extension ? mysql->options.extension->ssl_fp : NULL;
break;
case MARIADB_OPT_SSL_FP_LIST:
*((char **)arg)= mysql->options.extension ? mysql->options.extension->ssl_fp_list : NULL;
break;
case MARIADB_OPT_SSL_PASSWORD:
*((char **)arg)= mysql->options.extension ? mysql->options.extension->ssl_pw : NULL;
break;
/* todo
case MARIADB_OPT_CONNECTION_READ_ONLY:
break;
*/
default:
va_end(ap);
DBUG_RETURN(-1);
}
va_end(ap);
DBUG_RETURN(0);
error:
va_end(ap);
DBUG_RETURN(-1);
}
int STDCALL mysql_get_option(MYSQL *mysql, enum mysql_option option, void *arg)
{
return mysql_get_optionv(mysql, option, arg);
}
int STDCALL int STDCALL
mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg) mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg)

View File

@@ -464,9 +464,13 @@ int ma_ssl_verify_server_cert(MARIADB_SSL *cssl)
{ {
X509 *cert; X509 *cert;
MYSQL *mysql; MYSQL *mysql;
MARIADB_PVIO *pvio; X509_NAME *x509sn;
int cn_pos;
X509_NAME_ENTRY *cn_entry;
ASN1_STRING *cn_asn1;
const char *cn_str;
SSL *ssl; SSL *ssl;
char *p1, *p2, buf[256]; MARIADB_PVIO *pvio;
if (!cssl || !cssl->ssl) if (!cssl || !cssl->ssl)
return 1; return 1;
@@ -477,33 +481,46 @@ int ma_ssl_verify_server_cert(MARIADB_SSL *cssl)
if (!mysql->host) if (!mysql->host)
{ {
pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, 0, pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
"Invalid (empty) hostname"); ER(CR_SSL_CONNECTION_ERROR), "Invalid (empty) hostname");
return 1; return 1;
} }
if (!(cert= SSL_get_peer_certificate(ssl))) if (!(cert= SSL_get_peer_certificate(ssl)))
{ {
pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, 0, pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
"Unable to get server certificate"); ER(CR_SSL_CONNECTION_ERROR), "Unable to get server certificate");
return 1; return 1;
} }
X509_NAME_oneline(X509_get_subject_name(cert), buf, 256); x509sn= X509_get_subject_name(cert);
if ((cn_pos= X509_NAME_get_index_by_NID(x509sn, NID_commonName, -1)) < 0)
goto error;
if (!(cn_entry= X509_NAME_get_entry(x509sn, cn_pos)))
goto error;
if (!(cn_asn1 = X509_NAME_ENTRY_get_data(cn_entry)))
goto error;
cn_str = (char *)ASN1_STRING_data(cn_asn1);
/* Make sure there is no embedded \0 in the CN */
if ((size_t)ASN1_STRING_length(cn_asn1) != strlen(cn_str))
goto error;
if (strcmp(cn_str, mysql->host))
goto error;
X509_free(cert); X509_free(cert);
/* Extract the server name from buffer: return 0;
Format: ....CN=/hostname/.... */ error:
if ((p1= strstr(buf, "/CN="))) X509_free(cert);
{
p1+= 4; pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
if ((p2= strchr(p1, '/'))) ER(CR_SSL_CONNECTION_ERROR), "Validation of SSL server certificate failed");
*p2= 0;
if (!strcmp(mysql->host, p1))
return(0);
}
pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, 0,
"Validation of SSL server certificate failed");
return 1; return 1;
} }

View File

@@ -0,0 +1,19 @@
#
# pkg_config.pc.in
#
# pkg_config configuration file
# For a detailled description of options, please visit
# Dan Nicholsons Guide to pkg-config (http://www.freedesktop.org/wiki/Software/pkg-config/)
#
includedir=@PREFIX_INSTALL_DIR@/@INCLUDE_INSTALL_DIR@/@SUFFIX_INSTALL_DIR@
libdir=@PREFIX_INSTALL_DIR@/@INCLUDE_INSTALL_DIR@/@SUFFIX_INSTALL_DIR@
prefix=@PREFIX_INSTALL_DIR@
Name: libmariadb
Version: @LIBMARIADB_VERSION@
Description: MariaDB Connector/C dynamic library
Cflags: -I@PREFIX_INSTALL_DIR@/@INCLUDE_INSTALL_DIR@/@SUFFIX_INSTALL_DIR@ @CMAKE_C_FLAGS@
Libs: -L@PREFIX_INSTALL_DIR@/@LIB_INSTALL_DIR@/@SUFFIX_INSTALL_DIR@ -lmariadb @extra_dynamic_LDFLAGS@

View File

@@ -744,7 +744,82 @@ static int test_bind_address(MYSQL *my)
return OK; return OK;
} }
static int test_get_options(MYSQL *my)
{
MYSQL *mysql= mysql_init(NULL);
int options_int[]= {MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_LOCAL_INFILE,
MYSQL_OPT_RECONNECT, MYSQL_OPT_PROTOCOL, MYSQL_OPT_READ_TIMEOUT, MYSQL_OPT_WRITE_TIMEOUT, 0};
my_bool options_bool[]= {MYSQL_OPT_COMPRESS, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_SECURE_AUTH,
#ifdef _WIN32
MYSQL_OPT_NAMED_PIPE,
#endif
0};
int options_char[]= {MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP, MYSQL_SET_CHARSET_NAME,
MYSQL_OPT_SSL_KEY, MYSQL_OPT_SSL_CA, MYSQL_OPT_SSL_CERT, MYSQL_OPT_SSL_CAPATH,
MYSQL_OPT_SSL_CIPHER, MYSQL_OPT_BIND, MARIADB_OPT_SSL_FP, MARIADB_OPT_SSL_FP_LIST,
MARIADB_OPT_SSL_PASSWORD, 0};
char *init_command[3]= {"SET @a:=1", "SET @b:=2", "SET @c:=3"};
int elements= 0;
char **command;
int intval[2]= {1, 0};
my_bool boolval[2]= {1, 0};
char *char1= "test", *char2;
int i;
char *attr_key[] = {"foo1", "foo2", "foo3"};
char *attr_val[] = {"bar1", "bar2", "bar3"};
char *key[3], *val[3];
for (i=0; options_int[i]; i++)
{
mysql_options(mysql, options_int[i], &intval[0]);
intval[1]= 0;
mysql_get_optionv(mysql, options_int[i], &intval[1]);
FAIL_IF(intval[0] != intval[1], "mysql_get_optionv (int) failed");
}
for (i=0; options_bool[i]; i++)
{
mysql_options(mysql, options_bool[i], &boolval[0]);
intval[1]= 0;
mysql_get_optionv(mysql, options_bool[i], &boolval[1]);
FAIL_IF(boolval[0] != boolval[1], "mysql_get_optionv (my_bool) failed");
}
for (i=0; options_char[i]; i++)
{
mysql_options(mysql, options_char[i], char1);
char2= NULL;
mysql_get_optionv(mysql, options_char[i], (void *)&char2);
FAIL_IF(strcmp(char1, char2), "mysql_get_optionv (char) failed");
}
for (i=0; i < 3; i++)
mysql_options(mysql, MYSQL_INIT_COMMAND, init_command[i]);
mysql_get_optionv(mysql, MYSQL_INIT_COMMAND, &command, &elements);
FAIL_IF(elements != 3, "expected 3 elements");
for (i=0; i < 3; i++)
FAIL_IF(strcmp(init_command[i], command[i]), "wrong init command");
for (i=0; i < 3; i++)
mysql_optionsv(mysql, MYSQL_OPT_CONNECT_ATTR_ADD, attr_key[i], attr_val[i]);
mysql_get_optionv(mysql, MYSQL_OPT_CONNECT_ATTRS, NULL, NULL, &elements);
FAIL_IF(elements != 3, "expected 3 connection attributes");
mysql_get_optionv(mysql, MYSQL_OPT_CONNECT_ATTRS, &key, &val, &elements);
for (i=0; i < elements; i++)
{
diag("%s => %s", key[i], val[i]);
}
mysql_close(mysql);
return OK;
}
struct my_tests_st my_tests[] = { struct my_tests_st my_tests[] = {
{"test_get_options", test_get_options, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
{"test_wrong_bind_address", test_wrong_bind_address, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_wrong_bind_address", test_wrong_bind_address, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
{"test_bind_address", test_bind_address, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_bind_address", test_bind_address, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
{"test_conc118", test_conc118, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_conc118", test_conc118, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},