1
0
mirror of https://github.com/mariadb-corporation/mariadb-connector-c.git synced 2025-08-08 14:02:17 +03:00

Added new functions mysql_get_optionv and mysql_get_option

This commit is contained in:
Georg Richter
2015-12-10 06:51:01 +01:00
parent cbf0226552
commit edcfe061c1
6 changed files with 282 additions and 38 deletions

View File

@@ -291,10 +291,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 mysql_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

@@ -79,6 +79,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

@@ -1231,15 +1231,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;
} }
@@ -2567,21 +2565,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;
} }
@@ -2779,19 +2773,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);
} }
} }
@@ -2813,6 +2807,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 ||
@@ -2825,24 +2824,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))
{ {
@@ -2893,6 +2888,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

@@ -416,7 +416,6 @@ int store_param(MYSQL_STMT *stmt, int column, unsigned char **p)
{ {
DBUG_ENTER("store_param"); DBUG_ENTER("store_param");
DBUG_PRINT("info", ("column: %d type: %d", column, stmt->params[column].buffer_type)); DBUG_PRINT("info", ("column: %d type: %d", column, stmt->params[column].buffer_type));
printf("type: %d\n", column, stmt->params[column].buffer_type);
switch (stmt->params[column].buffer_type) { switch (stmt->params[column].buffer_type) {
case MYSQL_TYPE_TINY: case MYSQL_TYPE_TINY:
int1store(*p, *(uchar *)stmt->params[column].buffer); int1store(*p, *(uchar *)stmt->params[column].buffer);

View File

@@ -740,7 +740,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;
mariadb_get_optionv(mysql, options_int[i], &intval[1]);
FAIL_IF(intval[0] != intval[1], "mariadb_get_optionv (int) failed");
}
for (i=0; options_bool[i]; i++)
{
mysql_options(mysql, options_bool[i], &boolval[0]);
intval[1]= 0;
mariadb_get_optionv(mysql, options_bool[i], &boolval[1]);
FAIL_IF(boolval[0] != boolval[1], "mariadb_get_optionv (my_bool) failed");
}
for (i=0; options_char[i]; i++)
{
mysql_options(mysql, options_char[i], char1);
char2= NULL;
mariadb_get_optionv(mysql, options_char[i], (void *)&char2);
FAIL_IF(strcmp(char1, char2), "mariadb_get_optionv (char) failed");
}
for (i=0; i < 3; i++)
mysql_options(mysql, MYSQL_INIT_COMMAND, init_command[i]);
mariadb_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]);
mariadb_get_optionv(mysql, MYSQL_OPT_CONNECT_ATTRS, NULL, NULL, &elements);
FAIL_IF(elements != 3, "expected 3 connection attributes");
mariadb_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},